/home/lnzliplg/public_html/carousel-slider.tar
modules/ImageCarousel/Item.php000064400000005537151727276350012374 0ustar00<?php

namespace CarouselSlider\Modules\ImageCarousel;

use CarouselSlider\Supports\Validate;
use WP_Post;

/**
 * Item class
 */
class Item {

	/**
	 * The WP_Post object.
	 *
	 * @var WP_Post
	 */
	protected $post;

	/**
	 * Class constructor
	 *
	 * @param WP_Post $post The WP_Post object.
	 */
	public function __construct( WP_Post $post ) {
		$this->post = $post;
	}

	/**
	 * Get post id
	 *
	 * @return int
	 */
	public function get_id(): int {
		return $this->get_post()->ID;
	}

	/**
	 * Get title
	 *
	 * @return string
	 */
	public function get_title(): string {
		return $this->get_post()->post_title;
	}

	/**
	 * Get title
	 *
	 * @return string
	 */
	public function get_caption(): string {
		return $this->get_post()->post_excerpt;
	}

	/**
	 * Get image alt text
	 *
	 * @return string
	 */
	public function get_alt_text(): string {
		$image_alt = get_post_meta( $this->get_post()->ID, '_wp_attachment_image_alt', true );

		return trim( wp_strip_all_tags( $image_alt ) );
	}

	/**
	 * Get link url
	 *
	 * @return string
	 */
	public function get_link_url(): string {
		$image_link_url = get_post_meta( $this->post->ID, '_carousel_slider_link_url', true );

		return Validate::url( $image_link_url ) ? $image_link_url : '';
	}

	/**
	 * Get link start HTML
	 *
	 * @param string $context The context.
	 * @param string $target The target.
	 *
	 * @return string
	 */
	public function get_link_html_start( string $context, string $target = '_blank' ): string {
		if ( 'lightbox' === $context ) {
			$full_img = $this->get_image_src( 'full' );

			return '<a class="magnific-popup" href="' . esc_url( $full_img[0] ) . '" data-width="' . esc_attr( $full_img[1] ) . '" data-height="' . esc_attr( $full_img[2] ) . '">';
		}

		$link_url = $this->get_link_url();
		if ( 'link' === $context && $link_url ) {
			return '<a href="' . esc_url( $link_url ) . '" target="' . esc_attr( $target ) . '">';
		}

		return '';
	}

	/**
	 * Get link end HTML
	 *
	 * @param string $context The context.
	 *
	 * @return string
	 */
	public function get_link_html_end( string $context ): string {
		if ( in_array( $context, [ 'lightbox', 'link' ], true ) ) {
			return '</a>';
		}

		return '';
	}

	/**
	 * Get image
	 *
	 * @param string|int[] $size Registered image size name, or an array of width and height.
	 *
	 * @return string
	 */
	public function get_image( $size = 'medium_large' ): string {
		return wp_get_attachment_image( $this->get_id(), $size, false, [ 'alt' => $this->get_alt_text() ] );
	}

	/**
	 * Get image src
	 *
	 * @param string|int[] $size Registered image size name, or an array of width and height.
	 *
	 * @return array
	 */
	public function get_image_src( $size = 'medium_large' ): array {
		return wp_get_attachment_image_src( $this->get_id(), $size );
	}

	/**
	 * Get WP_Post object
	 *
	 * @return WP_Post
	 */
	public function get_post(): WP_Post {
		return $this->post;
	}
}
modules/ImageCarousel/Module.php000064400000004613151727276350012715 0ustar00<?php

namespace CarouselSlider\Modules\ImageCarousel;

use CarouselSlider\Supports\Validate;
use WP_Post;

defined( 'ABSPATH' ) || exit;

/**
 * Module class
 *
 * @package Modules/ImageCarousel
 */
class Module {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_filter( 'carousel_slider/register_view', [ self::$instance, 'view' ] );

			// Add a custom link to the media gallery.
			add_filter( 'attachment_fields_to_edit', [ self::$instance, 'attachment_fields_to_edit' ], 10, 2 );
			add_filter( 'attachment_fields_to_save', [ self::$instance, 'attachment_fields_to_save' ], 10, 2 );

			Admin::init();
		}

		return self::$instance;
	}

	/**
	 * Register view
	 *
	 * @param array $views Registered views.
	 *
	 * @return array
	 */
	public function view( array $views ): array {
		$views['image-carousel']     = new View();
		$views['image-carousel-url'] = new UrlView();

		return $views;
	}


	/**
	 * Adding our custom fields to the $form_fields array
	 *
	 * @param array   $form_fields The form fields.
	 * @param WP_Post $post The WP_Post object.
	 *
	 * @return array
	 */
	public function attachment_fields_to_edit( array $form_fields, WP_Post $post ): array {
		$value = get_post_meta( $post->ID, '_carousel_slider_link_url', true );
		$field = [
			'label'      => __( 'Link to URL', 'carousel-slider' ),
			'input'      => 'textarea',
			'value'      => $value,
			'extra_rows' => [
				'carouselSliderInfo' => __( '"Link to URL" only works on Carousel Slider for linking image to a custom url.', 'carousel-slider' ),
			],
		];

		$form_fields['carousel_slider_link_url'] = $field;

		return $form_fields;
	}

	/**
	 * Save custom field value
	 *
	 * @param array $post The post object as array.
	 * @param array $attachment Attachment data.
	 *
	 * @return array
	 */
	public function attachment_fields_to_save( array $post, array $attachment ): array {
		$slider_link_url = $attachment['carousel_slider_link_url'] ?? null;

		if ( Validate::url( $slider_link_url ) ) {
			update_post_meta( $post['ID'], '_carousel_slider_link_url', esc_url_raw( $slider_link_url ) );
		} else {
			delete_post_meta( $post['ID'], '_carousel_slider_link_url' );
		}

		return $post;
	}
}
modules/ImageCarousel/UrlView.php000064400000003050151727276350013057 0ustar00<?php

namespace CarouselSlider\Modules\ImageCarousel;

use CarouselSlider\Abstracts\AbstractView;
use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\Supports\Validate;
use CarouselSlider\TemplateParserBase;

defined( 'ABSPATH' ) || exit;

/**
 * UrlView class
 *
 * @package Modules/ImageCarousel
 */
class UrlView extends AbstractView {

	/**
	 * Get slider setting
	 *
	 * @return SliderSetting
	 */
	public function get_slider_setting(): SliderSetting {
		if ( ! $this->slider_setting instanceof SliderSetting ) {
			$this->slider_setting = new Setting( $this->get_slider_id() );
		}

		return $this->slider_setting;
	}

	/**
	 * Render html content
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$setting     = $this->get_slider_setting();
		$slider_id   = $this->get_slider_id();
		$images_urls = (array) get_post_meta( $slider_id, '_images_urls', true );
		if ( count( $images_urls ) < 1 ) {
			return '';
		}
		$template = new TemplateParserBase( $setting );
		$template->set_template( 'loop/image-carousel-url.php' );

		$html = $this->start_wrapper_html();
		foreach ( $images_urls as $images_url ) {
			$item = new ExternalImageItem( $images_url );
			$template->set_object( $item );

			$html .= $this->start_item_wrapper_html();
			$html .= apply_filters( 'carousel_slider/loop/image-carousel-url', $template->render(), $item, $this->get_slider_setting() );
			$html .= $this->end_item_wrapper_html();
		}
		$html .= $this->end_wrapper_html();

		return apply_filters( 'carousel_slider_link_images_carousel', $html, $slider_id );
	}
}
modules/ImageCarousel/TemplateUrl.php000064400000003415151727276350013725 0ustar00<?php

namespace CarouselSlider\Modules\ImageCarousel;

use CarouselSlider\Abstracts\AbstractTemplate;

defined( 'ABSPATH' ) || exit;

/**
 * TemplateUrl class
 *
 * @package Modules/ImageCarousel
 */
class TemplateUrl extends AbstractTemplate {
	/**
	 * Get default image carousel settings
	 *
	 * @return array
	 */
	public static function get_default_settings(): array {
		return wp_parse_args(
			array(
				'_slide_type'              => 'image-carousel-url',
				// Image Carousel Settings.
				'_show_attachment_title'   => 'off',
				'_show_attachment_caption' => 'off',
				'_image_lightbox'          => 'on',
				'_image_target'            => '_self',
			),
			parent::get_default_settings()
		);
	}

	/**
	 * Create a gallery image carousel with random images
	 *
	 * @param string $slider_title The slider title.
	 * @param array  $args Arguments.
	 *
	 * @return int The WP_Post ID on success. Value 0 on failure.
	 */
	public static function create( $slider_title = null, $args = [] ): int {
		$images = self::get_images();
		$images = array_slice( $images, 0, 10 );

		$_urls = array();
		foreach ( $images as $image ) {
			$_urls[] = array(
				'url'      => $image['image_src'],
				'title'    => $image['title'],
				'caption'  => $image['caption'],
				'alt'      => $image['alt_text'],
				'link_url' => $image['link_url'],
			);
		}

		if ( empty( $slider_title ) ) {
			$slider_title = 'URL Image Carousel with Dummy Data';
		}

		$default = self::get_default_settings();

		$default['_images_urls'] = $_urls;

		$data = wp_parse_args( $args, $default );

		$post_id = self::create_slider( $slider_title );

		if ( ! $post_id ) {
			return 0;
		}

		foreach ( $data as $meta_key => $meta_value ) {
			update_post_meta( $post_id, $meta_key, $meta_value );
		}

		return $post_id;
	}
}
modules/ImageCarousel/Admin.php000064400000021177151727276360012525 0ustar00<?php

namespace CarouselSlider\Modules\ImageCarousel;

use CarouselSlider\Helper;
use CarouselSlider\Supports\MetaBoxForm;

defined( 'ABSPATH' ) || exit;

/**
 * Admin class
 *
 * @package Modules/ImageCarousel
 */
class Admin {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'carousel_slider/meta_box_content', [ self::$instance, 'meta_box_content' ], 10, 2 );
			add_action( 'carousel_slider/save_slider', [ self::$instance, 'save_slider' ], 10, 2 );
		}

		return self::$instance;
	}

	/**
	 * Save slider data
	 *
	 * @param int   $slider_id The slider id.
	 * @param array $data User submitted data.
	 *
	 * @return void
	 */
	public function save_slider( int $slider_id, array $data ) {
		$settings = $data['image_carousel'] ?? [];
		foreach ( $settings as $key => $val ) {
			if ( is_array( $val ) ) {
				$val = implode( ',', $val );
			}

			update_post_meta( $slider_id, $key, sanitize_text_field( $val ) );
		}
		// Save URL image carousel.
		$images_urls = isset( $data['_images_urls'] ) && is_array( $data['_images_urls'] ) ? $data['_images_urls'] : [];
		if ( count( $images_urls ) ) {
			$url         = $images_urls['url'] ?? [];
			$title       = $images_urls['title'] ?? [];
			$caption     = $images_urls['caption'] ?? [];
			$alt         = $images_urls['alt'] ?? [];
			$link_url    = $images_urls['link_url'] ?? [];
			$total_items = count( $url );

			$urls = array();

			for ( $i = 0; $i < $total_items; $i++ ) {
				$urls[] = array(
					'url'      => esc_url_raw( $url[ $i ] ),
					'title'    => sanitize_text_field( $title[ $i ] ),
					'caption'  => sanitize_text_field( $caption[ $i ] ),
					'alt'      => sanitize_text_field( $alt[ $i ] ),
					'link_url' => esc_url_raw( $link_url[ $i ] ),
				);
			}
			update_post_meta( $slider_id, '_images_urls', $urls );
		}
	}

	/**
	 * Show meta box content for product carousel
	 *
	 * @param int    $slider_id The slider id.
	 * @param string $slider_type The slider type.
	 */
	public function meta_box_content( int $slider_id, string $slider_type ) {
		if ( ! in_array( $slider_type, [ 'image-carousel', 'image-carousel-url' ], true ) ) {
			return;
		}

		$settings_fields = self::get_settings( $slider_type );
		$html            = '';
		foreach ( $settings_fields as $field ) {
			$html .= MetaBoxForm::field( $field );
		}

		Helper::print_unescaped_internal_string( $html );

		if ( 'image-carousel-url' === $slider_type ) {
			$this->image_url_dialog( $slider_id );
		}
	}

	/**
	 * Load image url dialog
	 *
	 * @param int $slider_id The slider id.
	 *
	 * @return void
	 */
	public function image_url_dialog( $slider_id ) {
		$images_urls = get_post_meta( $slider_id, '_images_urls', true );
		?>
		<shapla-dialog type="card" id="CarouselSliderModal"
					   heading="<?php esc_html_e( 'Image Carousel - from URL', 'carousel-slider' ); ?>"
		>
			<div class="carousel_slider-modal-body">
				<div>
					<div id="carousel_slider_form" class="carousel_slider-form shapla-columns is-multiline">
						<?php
						if ( is_array( $images_urls ) ) :
							foreach ( $images_urls as $image ) :
								?>
								<div class="media-url--column shapla-column is-12">
									<div class="carousel_slider-fields media-url-form-field">
										<div class="media-url-form-field__content">
											<label class="setting media-url-form-field__item">
													<span
														class="name"><?php esc_html_e( 'URL', 'carousel-slider' ); ?></span>
												<input type="url" name="_images_urls[url][]"
													   value="<?php echo esc_url( $image['url'] ); ?>"
													   autocomplete="off">
											</label>
											<label class="setting media-url-form-field__item">
													<span
														class="name"><?php esc_html_e( 'Title', 'carousel-slider' ); ?></span>
												<input type="text" name="_images_urls[title][]"
													   value="<?php echo esc_attr( $image['title'] ); ?>"
													   autocomplete="off">
											</label>
											<label class="setting media-url-form-field__item">
													<span
														class="name"><?php esc_html_e( 'Caption', 'carousel-slider' ); ?></span>
												<textarea
													name="_images_urls[caption][]"><?php echo esc_textarea( $image['caption'] ); ?></textarea>
											</label>
											<label class="setting media-url-form-field__item">
													<span
														class="name"><?php esc_html_e( 'Alt Text', 'carousel-slider' ); ?></span>
												<input type="text" name="_images_urls[alt][]"
													   value="<?php echo esc_attr( $image['alt'] ); ?>"
													   autocomplete="off">
											</label>
											<label class="setting media-url-form-field__item">
													<span
														class="name"><?php esc_html_e( 'Link To URL', 'carousel-slider' ); ?></span>
												<input type="text" name="_images_urls[link_url][]"
													   value="<?php echo esc_url( $image['link_url'] ); ?>"
													   autocomplete="off">
											</label>
										</div>
										<div class="media-url-form-field__actions">
											<span><span class="dashicons dashicons-move"></span></span>
											<span class="add_row"><span
													class="dashicons dashicons-plus-alt"></span></span>
											<span class="delete_row"><span
													class="dashicons dashicons-trash"></span></span>
										</div>
									</div>
								</div>
								<?php
							endforeach;
						endif;
						?>
						<div class="shapla-column is-12">
							<button class="button add_row">Add Item</button>
						</div>
					</div>
				</div>
			</div>
			<div slot="footer">
				<button class="button button-primary">
					<?php esc_html_e( 'Save', 'carousel-slider' ); ?>
				</button>
			</div>
		</shapla-dialog>
		<?php
	}

	/**
	 * Get settings
	 *
	 * @param string $slider_type The slider type.
	 *
	 * @return array
	 */
	public static function get_settings( string $slider_type ): array {
		$settings = [];

		if ( 'image-carousel-url' === $slider_type ) {
			$settings[] = [
				'group'       => 'image_carousel',
				'type'        => 'images_url',
				'id'          => '_images_urls',
				'label'       => esc_html__( 'Images URLs', 'carousel-slider' ),
				'description' => esc_html__( 'Enter external images URLs.', 'carousel-slider' ),
			];
		}

		if ( 'image-carousel' === $slider_type ) {
			$settings[] = [
				'group'       => 'image_carousel',
				'type'        => 'images_gallery',
				'id'          => '_wpdh_image_ids',
				'name'        => esc_html__( 'Carousel Images', 'carousel-slider' ),
				'description' => esc_html__( 'Choose carousel images from media library.', 'carousel-slider' ),
			];
			$settings[] = [
				'group'       => 'image_carousel',
				'type'        => 'switch',
				'id'          => '_shuffle_images',
				'label'       => esc_html__( 'Shuffle Images Order', 'carousel-slider' ),
				'description' => esc_html__( 'Check to shuffle images order at each page refresh.', 'carousel-slider' ),
				'default'     => 'off',
			];
			$settings[] = [
				'group'       => 'image_carousel',
				'type'        => 'switch',
				'id'          => '_image_lightbox',
				'label'       => esc_html__( 'Show Lightbox Gallery', 'carousel-slider' ),
				'description' => esc_html__( 'Check to show lightbox gallery.', 'carousel-slider' ),
				'default'     => 'off',
			];
		}

		$settings[] = [
			'group'       => 'image_carousel',
			'type'        => 'switch',
			'id'          => '_show_attachment_title',
			'label'       => esc_html__( 'Show Image Title', 'carousel-slider' ),
			'description' => esc_html__( 'Check to show title below image. Only works with image carousel.', 'carousel-slider' ),
			'default'     => 'off',
		];
		$settings[] = [
			'group'       => 'image_carousel',
			'type'        => 'switch',
			'id'          => '_show_attachment_caption',
			'label'       => esc_html__( 'Show Image Caption', 'carousel-slider' ),
			'description' => esc_html__( 'Check to show caption below image. Only works with image carousel.', 'carousel-slider' ),
			'default'     => 'off',
		];
		$settings[] = [
			'group'       => 'image_carousel',
			'type'        => 'button_group',
			'id'          => '_image_target',
			'label'       => esc_html__( 'Image Target', 'carousel-slider' ),
			'description' => esc_html__( 'Choose where to open the linked image.', 'carousel-slider' ),
			'default'     => '_self',
			'choices'     => [
				'_self'  => esc_html__( 'Same browser tab', 'carousel-slider' ),
				'_blank' => esc_html__( 'New browser tab', 'carousel-slider' ),
			],
		];

		return $settings;
	}
}
modules/ImageCarousel/View.php000064400000002723151727276360012403 0ustar00<?php

namespace CarouselSlider\Modules\ImageCarousel;

use CarouselSlider\Abstracts\AbstractView;
use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\TemplateParserBase;
use WP_Post;

defined( 'ABSPATH' ) || exit;

/**
 * View class
 *
 * @package Modules/ImageCarousel
 */
class View extends AbstractView {

	/**
	 * Get slider setting
	 *
	 * @return SliderSetting|Setting
	 */
	public function get_slider_setting(): SliderSetting {
		if ( ! $this->slider_setting instanceof SliderSetting ) {
			$this->slider_setting = new Setting( $this->get_slider_id() );
		}

		return $this->slider_setting;
	}

	/**
	 * Render html content
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$setting  = $this->get_slider_setting();
		$template = new TemplateParserBase( $setting );
		$template->set_template( 'loop/image-carousel.php' );

		$html = $this->start_wrapper_html();
		foreach ( $setting->get_image_ids() as $id ) {
			$_post = get_post( $id );
			if ( ! $_post instanceof WP_Post ) {
				continue;
			}

			$item = new Item( $_post );
			$template->set_object( $item );

			do_action( 'carousel_slider_image_gallery_loop', $_post );

			$html .= $this->start_item_wrapper_html();
			$html .= apply_filters( 'carousel_slider/loop/image-carousel', $template->render(), $item, $setting );
			$html .= $this->end_item_wrapper_html() . PHP_EOL;
		}
		$html .= $this->end_wrapper_html();

		return apply_filters( 'carousel_slider_gallery_images_carousel', $html );
	}
}
modules/ImageCarousel/Setting.php000064400000004506151727276360013107 0ustar00<?php

namespace CarouselSlider\Modules\ImageCarousel;

use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\Supports\Validate;

/**
 * Setting class
 *
 * @method bool should_shuffle_images()
 * @method bool should_show_title()
 * @method bool should_show_caption()
 * @method bool should_show_lightbox()
 */
class Setting extends SliderSetting {
	/**
	 * Is data read from the server?
	 *
	 * @var bool
	 */
	protected $extra_data_read = false;

	/**
	 * Get image ids
	 *
	 * @return array
	 */
	public function get_image_ids(): array {
		$ids = $this->get_prop( 'image_ids', [] );
		if ( is_string( $ids ) ) {
			$ids = array_filter( explode( ',', $ids ) );
		}
		if ( Validate::checked( $this->get_prop( 'shuffle_images' ) ) ) {
			shuffle( $ids );
		}

		return is_array( $ids ) ? $ids : [];
	}

	/**
	 * Get image target
	 *
	 * @return string
	 */
	public function get_image_target(): string {
		$target = $this->get_prop( 'image_target' );

		return in_array( $target, [ '_self', '_blank' ], true ) ? $target : '_self';
	}

	/**
	 * Read extra metadata
	 *
	 * @return void
	 */
	public function read_extra_metadata() {
		if ( $this->extra_data_read ) {
			return;
		}
		foreach ( self::extra_props() as $attribute => $config ) {
			$value = get_post_meta( $this->get_slider_id(), $config['id'], true );
			$value = ! empty( $value ) ? $value : $config['default'];
			$value = $this->prepare_item_for_response( $config['type'], $value );
			$this->set_prop( $attribute, $value );
		}
		$this->extra_data_read = true;
	}

	/**
	 * Slider extra props
	 *
	 * @return array
	 */
	public static function extra_props(): array {
		return [
			'image_ids'      => [
				'id'      => '_wpdh_image_ids',
				'type'    => 'int[]',
				'default' => '',
			],
			'shuffle_images' => [
				'id'      => '_shuffle_images',
				'type'    => 'bool',
				'default' => 'no',
			],
			'image_target'   => [
				'id'      => '_image_target',
				'type'    => 'string',
				'default' => '_self',
			],
			'show_title'     => [
				'id'      => '_show_attachment_title',
				'type'    => 'bool',
				'default' => 'off',
			],
			'show_caption'   => [
				'id'      => '_show_attachment_caption',
				'type'    => 'bool',
				'default' => 'off',
			],
			'show_lightbox'  => [
				'id'      => '_image_lightbox',
				'type'    => 'bool',
				'default' => 'off',
			],
		];
	}
}
modules/ImageCarousel/ExternalImageItem.php000064400000004260151727276360015033 0ustar00<?php

namespace CarouselSlider\Modules\ImageCarousel;

use CarouselSlider\Abstracts\Data;
use CarouselSlider\Helper;

/**
 * ExternalImageItem class
 *
 * @package CarouselSlider/Modules/ImageCarousel
 */
class ExternalImageItem extends Data {

	/**
	 * The image url
	 *
	 * @param  array $data  The data.
	 */
	public function __construct( array $data ) {
		$this->data = $data;
	}

	/**
	 * The image url.
	 *
	 * @return string
	 */
	public function get_image_url(): string {
		return $this->get_prop( 'url' );
	}

	/**
	 * Get title
	 *
	 * @return string
	 */
	public function get_title(): string {
		return $this->get_prop( 'title' );
	}

	/**
	 * Get caption
	 *
	 * @return string
	 */
	public function get_caption(): string {
		return $this->get_prop( 'caption' );
	}

	/**
	 * Get alt text
	 *
	 * @return string
	 */
	public function get_alt_text(): string {
		return $this->get_prop( 'alt' );
	}

	/**
	 * Get link
	 *
	 * @return string
	 */
	public function get_link_url(): string {
		return $this->get_prop( 'link_url' );
	}

	/**
	 * Get image html
	 *
	 * @param  bool $lazy  Load image lazily.
	 *
	 * @return string
	 */
	public function get_image_html( bool $lazy = true ): string {
		$attrs = [ 'alt' => esc_attr( $this->get_alt_text() ) ];
		if ( $lazy ) {
			if ( Helper::is_using_swiper() ) {
				$attrs['src']     = esc_url( $this->get_image_url() );
				$attrs['loading'] = 'lazy';
			} else {
				$attrs['class']    = 'owl-lazy';
				$attrs['data-src'] = esc_url( $this->get_image_url() );
			}
		} else {
			$attrs['src'] = esc_url( $this->get_image_url() );
		}

		return '<img ' . join( ' ', Helper::array_to_attribute( $attrs ) ) . ' />';
	}

	/**
	 * Get link start html
	 *
	 * @param  string $target  The target.
	 *
	 * @return string
	 */
	public function get_link_html_start( string $target = '_blank' ): string {
		$link_url = $this->get_link_url();
		if ( $link_url ) {
			return '<a href="' . esc_url( $link_url ) . '" target="' . esc_attr( $target ) . '">';
		}

		return '';
	}

	/**
	 * Get link end html
	 *
	 * @return string
	 */
	public function get_link_html_end(): string {
		$link_url = $this->get_link_url();
		if ( $link_url ) {
			return '</a>';
		}

		return '';
	}
}
modules/ImageCarousel/Template.php000064400000003121151727276360013235 0ustar00<?php

namespace CarouselSlider\Modules\ImageCarousel;

use CarouselSlider\Abstracts\AbstractTemplate;

defined( 'ABSPATH' ) || exit;

/**
 * Template class
 *
 * @package Modules/ImageCarousel
 */
class Template extends AbstractTemplate {

	/**
	 * Get default image carousel settings
	 *
	 * @return array
	 */
	public static function get_default_settings(): array {
		return wp_parse_args(
			[
				'_slide_type'              => 'image-carousel',
				// Image Carousel Settings.
				'_show_attachment_title'   => 'off',
				'_show_attachment_caption' => 'off',
				'_image_lightbox'          => 'on',
				'_image_target'            => '_self',
			],
			parent::get_default_settings()
		);
	}

	/**
	 * Create a gallery image carousel with random images
	 *
	 * @param string $slider_title The slider title.
	 * @param array  $args Arguments.
	 *
	 * @return int The WP_Post ID on success. Value 0 on failure.
	 */
	public static function create( $slider_title = '', $args = [] ): int {
		$images = self::get_images();
		$images = array_slice( $images, 0, 10 );
		$ids    = wp_list_pluck( $images, 'id' );
		$ids    = is_array( $ids ) ? implode( ',', $ids ) : $ids;

		if ( empty( $slider_title ) ) {
			$slider_title = 'Image Carousel with Dummy Data';
		}

		$default = self::get_default_settings();

		$default['_wpdh_image_ids'] = $ids;

		$data = wp_parse_args( $args, $default );

		$post_id = self::create_slider( $slider_title );

		if ( ! $post_id ) {
			return 0;
		}

		foreach ( $data as $meta_key => $meta_value ) {
			update_post_meta( $post_id, $meta_key, $meta_value );
		}

		return $post_id;
	}
}
modules/HeroCarousel/Item.php000064400000040367151727276360012250 0ustar00<?php

namespace CarouselSlider\Modules\HeroCarousel;

use CarouselSlider\Abstracts\Data;
use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\Helper;
use CarouselSlider\Supports\Sanitize;
use CarouselSlider\Supports\Validate;

defined( 'ABSPATH' ) || exit;

/**
 * Item class
 *
 * @package Modules/HeroCarousel
 */
class Item extends Data {
	/**
	 * Default content
	 *
	 * @var string[]
	 */
	protected static $default = [
		// Slide Content.
		'slide_heading'            => '',
		'slide_description'        => '',
		// Slide Background.
		'img_id'                   => '',
		'img_bg_position'          => 'center center',
		'img_bg_size'              => 'contain',
		'bg_color'                 => 'rgba(0,0,0,0.6)',
		'ken_burns_effect'         => '',
		'bg_overlay'               => '',
		// Slide Style.
		'content_alignment'        => 'center',
		'heading_font_size'        => '40',
		'heading_gutter'           => '30px',
		'heading_color'            => '#ffffff',
		'description_font_size'    => '20',
		'description_gutter'       => '30px',
		'description_color'        => '#ffffff',
		// Slide Link.
		'link_type'                => 'none',
		'slide_link'               => '',
		'link_target'              => '_self',
		// Slide Button #1.
		'button_one_text'          => '',
		'button_one_url'           => '',
		'button_one_target'        => '_self',
		'button_one_type'          => 'stroke',
		'button_one_size'          => 'medium',
		'button_one_border_width'  => '3px',
		'button_one_border_radius' => '0px',
		'button_one_bg_color'      => '#ffffff',
		'button_one_color'         => '#323232',
		// Slide Button #2.
		'button_two_text'          => '',
		'button_two_url'           => '',
		'button_two_target'        => '_self',
		'button_two_type'          => 'stroke',
		'button_two_size'          => 'medium',
		'button_two_border_width'  => '3px',
		'button_two_border_radius' => '0px',
		'button_two_bg_color'      => '#ffffff',
		'button_two_color'         => '#323232',
	];

	/**
	 * Slider settings
	 *
	 * @var array
	 */
	protected $slider_settings = [];

	/**
	 * SliderSetting class
	 *
	 * @var SliderSetting
	 */
	protected $setting;

	/**
	 * Class constructor.
	 *
	 * @param  array  $args  Optional arguments.
	 * @param  array  $slider_settings  Slider settings.
	 */
	public function __construct( array $args = [], array $slider_settings = [] ) {
		$this->data            = wp_parse_args( $args, self::get_default() );
		$this->slider_settings = $slider_settings;
	}

	/**
	 * Get slider setting
	 *
	 * @return SliderSetting
	 */
	public function get_setting(): SliderSetting {
		return $this->setting;
	}

	/**
	 * Set setting
	 *
	 * @param  Setting|SliderSetting  $setting  The SliderSetting object.
	 */
	public function set_setting( Setting $setting ) {
		$this->setting         = $setting;
		$this->slider_settings = $this->setting->get_content_settings();
	}

	/**
	 * Get default data
	 *
	 * @return string[]
	 */
	public static function get_default(): array {
		return self::$default;
	}

	/**
	 * Get default value
	 *
	 * @param  string  $key  Props key.
	 * @param  mixed  $default_value  Default value.
	 *
	 * @return mixed|string
	 */
	public static function get_default_value( string $key, $default_value = '' ) {
		return static::$default[ $key ] ?? $default_value;
	}

	/**
	 * Sanitize item data
	 *
	 * @param  array  $data  The data to be sanitized.
	 *
	 * @return array
	 */
	public static function sanitize( array $data ): array {
		$dimension_fields = [
			'heading_gutter',
			'description_gutter',
			'button_one_border_width',
			'button_one_border_radius',
			'button_two_border_width',
			'button_two_border_radius',
		];
		$color_fields     = [
			'bg_color',
			'bg_overlay',
			'heading_color',
			'description_color',
			'button_one_bg_color',
			'button_one_color',
			'button_two_bg_color',
			'button_two_color',
		];
		$data             = wp_parse_args( $data, self::get_default() );
		$sanitize_data    = [];
		foreach ( $data as $key => $value ) {
			if ( in_array( $key, [ 'slide_heading', 'slide_description' ], true ) ) {
				$sanitize_data[ $key ] = Sanitize::html( $value );
			} elseif ( in_array( $key, [ 'img_id', 'heading_font_size', 'description_font_size' ], true ) ) {
				$sanitize_data[ $key ] = Sanitize::int( $value );
			} elseif ( in_array( $key, [ 'slide_link', 'button_one_url', 'button_two_url' ], true ) ) {
				$sanitize_data[ $key ] = Sanitize::url( $value );
			} elseif ( in_array( $key, $color_fields, true ) ) {
				$sanitize_data[ $key ] = Sanitize::color( $value );
			} elseif ( in_array( $key, $dimension_fields, true ) ) {
				$sanitize_data[ $key ] = Sanitize::css_dimension( $value );
			} else {
				$sanitize_data[ $key ] = Sanitize::text( $value );
			}
		}

		return $sanitize_data;
	}

	/**
	 * Lazy load image
	 *
	 * @return bool
	 */
	public function lazy_load_image(): bool {
		return $this->setting->lazy_load_image();
	}

	/**
	 * Get slider id
	 *
	 * @return int
	 */
	public function get_slider_id(): int {
		return $this->setting->get_slider_id();
	}

	/**
	 * Get item id
	 *
	 * @return int
	 */
	public function get_item_id(): int {
		return (int) $this->get_prop( 'id' );
	}

	/**
	 * Get background type
	 *
	 * @return string
	 */
	public function get_background_type(): string {
		$bg_type = $this->get_prop( 'background_type' );
		if ( in_array( $bg_type, [ 'color', 'image' ], true ) ) {
			return $bg_type;
		}
		if ( ! empty( $this->get_prop( 'img_id' ) ) ) {
			return 'image';
		}

		return 'color';
	}

	/**
	 * If it has button one content
	 *
	 * @return bool
	 */
	public function has_button_one(): bool {
		return ! ! (
			! empty( $this->get_prop( 'button_one_text' ) ) &&
			! empty( $this->get_prop( 'button_one_url' ) ) &&
			Validate::url( $this->get_prop( 'button_one_url' ) )
		);
	}

	/**
	 * Has button two
	 *
	 * @return bool
	 */
	public function has_button_two(): bool {
		return ! ! (
			! empty( $this->get_prop( 'button_two_text' ) ) &&
			! empty( $this->get_prop( 'button_two_url' ) ) &&
			Validate::url( $this->get_prop( 'button_two_url' ) )
		);
	}

	/**
	 * Get link type
	 *
	 * @return string
	 */
	public function get_link_type(): string {
		$link_type = $this->get_prop( 'link_type', 'full' );

		return in_array( $link_type, [ 'full', 'button' ], true ) ? $link_type : 'full';
	}

	/**
	 * Get slide padding
	 *
	 * @return array
	 */
	public function get_slide_padding(): array {
		$default       = [
			'top'    => '1rem',
			'right'  => '3rem',
			'bottom' => '1rem',
			'left'   => '3rem',
		];
		$slide_padding = [];
		if ( isset( $this->slider_settings['slide_padding'] ) && is_array( $this->slider_settings['slide_padding'] ) ) {
			foreach ( $this->slider_settings['slide_padding'] as $position => $value ) {
				if ( array_key_exists( $position, $default ) ) {
					$slide_padding[ $position ] = $value;
				}
			}
		}

		return wp_parse_args( $slide_padding, $default );
	}

	/**
	 * Get content width
	 *
	 * @return mixed|string
	 */
	public function get_content_width() {
		return $this->slider_settings['content_width'] ?? '800px';
	}

	/**
	 * Get Slider height
	 *
	 * @return mixed|string
	 */
	public function get_slide_height() {
		return $this->slider_settings['slide_height'] ?? '300px';
	}

	/**
	 * Get content animation
	 *
	 * @return mixed|string
	 */
	public function get_content_animation() {
		$animation = $this->get_prop( 'content_animation' );
		if ( ! empty( $animation ) ) {
			return $animation;
		}

		return $this->slider_settings['content_animation'] ?? '';
	}

	/**
	 * Get item view
	 *
	 * @return string
	 */
	public function get_view(): string {
		$html = $this->get_cell_start();

		$html .= $this->get_cell_background();

		$html .= $this->get_cell_inner_start();

		// Background Overlay.
		$bg_overlay = $this->get_prop( 'bg_overlay' );
		if ( ! empty( $bg_overlay ) ) {
			$overlay_style = 'background-color: ' . $bg_overlay . ';';

			$html .= '<div class="carousel-slider-hero__cell__background_overlay" style="' . $overlay_style . '"></div>';
		}

		$cell_content_attr = [
			'class'          => 'carousel-slider-hero__cell__content hidden',
			'style'          => 'max-width:' . $this->get_content_width(),
			'data-animation' => $this->get_content_animation(),
		];

		$html .= '<div ' . join( ' ', Helper::array_to_attribute( $cell_content_attr ) ) . '>';

		// Slide Heading.
		$html .= $this->get_heading();

		// Slide Description.
		$html .= $this->get_description();

		if ( 'button' === $this->get_link_type() ) {
			$html .= '<div class="carousel-slider-hero__cell__buttons">';
			$html .= $this->get_button_one();
			$html .= $this->get_button_two();
			$html .= '</div>'; // .carousel-slider-hero__cell__buttons
		}

		$html .= '</div>';// .carousel-slider-hero__cell__content
		$html .= '</div>';// .carousel-slider-hero__cell__inner

		$html .= $this->get_cell_end();

		return apply_filters( 'carousel_slider_content', $html, $this->to_array(), $this->get_item_id() );
	}

	/**
	 * Get background
	 *
	 * @return string
	 */
	public function get_cell_background(): string {
		// Slide Background.
		$img_bg_position  = $this->get_prop( 'img_bg_position' );
		$img_bg_size      = $this->get_prop( 'img_bg_size' );
		$bg_color         = $this->get_prop( 'bg_color' );
		$ken_burns_effect = $this->get_prop( 'ken_burns_effect' );
		$img_id           = $this->get_prop( 'img_id' );
		$img_src          = wp_get_attachment_image_src( $img_id, 'full' );
		$have_img         = is_array( $img_src ) && Validate::url( $img_src[0] );

		$styles = [
			'background-position' => $img_bg_position,
			'background-size'     => $img_bg_size,
		];
		if ( $have_img && ! $this->lazy_load_image() ) {
			$styles['background-image'] = "url($img_src[0])";
		}
		if ( ! empty( $bg_color ) ) {
			$styles['background-color'] = $bg_color;
		}

		$_slide_bg_class = 'carousel-slider-hero__cell__background';

		if ( $this->lazy_load_image() ) {
			$_slide_bg_class .= Helper::is_using_swiper() ? ' swiper-lazy' : ' owl-lazy';
		}

		if ( 'zoom-in' === $ken_burns_effect ) {
			$_slide_bg_class .= ' carousel-slider-hero-ken-in';
		} elseif ( 'zoom-out' === $ken_burns_effect ) {
			$_slide_bg_class .= ' carousel-slider-hero-ken-out';
		}

		$attrs = [
			'id'    => sprintf( 'slide-item-%s-%s', $this->get_slider_id(), $this->get_item_id() ),
			'class' => $_slide_bg_class,
			'style' => Helper::array_to_style( $styles ),
		];

		if ( $have_img && $this->lazy_load_image() ) {
			if ( Helper::is_using_swiper() ) {
				$attrs['data-background'] = $img_src[0];
			} else {
				$attrs['data-src'] = $img_src[0];
			}
		}

		return '<div ' . implode( ' ', Helper::array_to_attribute( $attrs ) ) . '></div>';
	}

	/**
	 * Get cell inner start content
	 *
	 * @return string
	 */
	public function get_cell_inner_start(): string {
		$slide_padding = $this->get_slide_padding();
		$alignment     = $this->get_prop( 'content_alignment', 'left' );
		$alignment     = in_array( $alignment, [ 'left', 'center', 'right' ], true ) ? $alignment : 'left';

		$classes = [
			'carousel-slider-hero__cell__inner',
			'carousel-slider--h-position-center',
			'carousel-slider--v-position-middle',
			'carousel-slider--text-' . $alignment,
		];

		$styles = [
			'padding-top'    => esc_attr( $slide_padding['top'] ),
			'padding-right'  => esc_attr( $slide_padding['right'] ),
			'padding-bottom' => esc_attr( $slide_padding['bottom'] ),
			'padding-left'   => esc_attr( $slide_padding['left'] ),
		];

		return '<div class="' . implode( ' ', $classes ) . '" style="' . Helper::array_to_style( $styles ) . '">';
	}

	/**
	 * Get heading
	 *
	 * @return string
	 */
	public function get_heading(): string {
		$html          = '';
		$slide_heading = $this->get_prop( 'slide_heading' );
		if ( empty( $slide_heading ) ) {
			return $html;
		}
		$styles = [
			'--cs-heading-font-size' => (int) $this->get_prop( 'heading_font_size', 40 ) . 'px',
			'--cs-heading-gutter'    => $this->get_prop( 'heading_gutter', '30px' ),
			'--cs-heading-color'     => $this->get_prop( 'heading_color', '#ffffff' ),
		];

		$html .= '<div class="carousel-slider-hero__cell__heading" style="' . Helper::array_to_style( $styles ) . '">';
		$html .= wp_kses_post( $slide_heading );
		$html .= '</div>';

		return $html;
	}

	/**
	 * Get slide description
	 *
	 * @return string
	 */
	public function get_description(): string {
		$html              = '';
		$slide_description = $this->get_prop( 'slide_description' );
		if ( empty( $slide_description ) ) {
			return $html;
		}

		$styles = [
			'--cs-description-font-size' => (int) $this->get_prop( 'description_font_size', 20 ) . 'px',
			'--cs-description-gutter'    => $this->get_prop( 'description_gutter', '30px' ),
			'--cs-description-color'     => $this->get_prop( 'description_color', '#ffffff' ),
		];

		$html .= '<div class="carousel-slider-hero__cell__description" style="' . Helper::array_to_style( $styles ) . '">';
		$html .= wp_kses_post( $slide_description );
		$html .= '</div>';

		return $html;
	}

	/**
	 * Button one content
	 *
	 * @return string
	 */
	public function get_button_one(): string {
		$html = '';
		$url  = $this->get_prop( 'button_one_url' );
		if ( ! Validate::url( $url ) ) {
			return $html;
		}
		$btn_text = $this->get_prop( 'button_one_text' );
		$target   = $this->get_prop( 'button_one_target', '_self' );

		$classes = 'button cs-hero-button';
		$classes .= ' cs-hero-button-' . $this->get_item_id() . '-1';
		$classes .= ' cs-hero-button-' . $this->get_prop( 'button_one_type', 'normal' );
		$classes .= ' cs-hero-button-' . $this->get_prop( 'button_one_size', 'medium' );

		$style = [
			'--cs-button-bg-color'      => $this->get_prop( 'button_one_bg_color', '#00d1b2' ),
			'--cs-button-color'         => $this->get_prop( 'button_one_color', '#ffffff' ),
			'--cs-button-border-width'  => $this->get_prop( 'button_one_border_width', '0px' ),
			'--cs-button-border-radius' => $this->get_prop( 'button_one_border_radius', '3px' ),
		];

		$html .= '<span class="carousel-slider-hero__cell__button__one" style="' . Helper::array_to_style( $style ) . '">';
		$html .= '<a class="' . $classes . '" href="' . $url . '" target="' . $target . '">' . esc_html( $btn_text ) . '</a>';
		$html .= '</span>';

		return $html;
	}

	/**
	 * Button two content
	 *
	 * @return string
	 */
	public function get_button_two(): string {
		$html = '';
		$url  = $this->get_prop( 'button_two_url' );
		if ( ! Validate::url( $url ) ) {
			return $html;
		}
		$text   = $this->get_prop( 'button_two_text' );
		$target = $this->get_prop( 'button_two_target', '_self' );

		$classes = 'button cs-hero-button';
		$classes .= ' cs-hero-button-' . $this->get_item_id() . '-2';
		$classes .= ' cs-hero-button-' . $this->get_prop( 'button_two_type', 'normal' );
		$classes .= ' cs-hero-button-' . $this->get_prop( 'button_two_size', 'medium' );

		$style = [
			'--cs-button-bg-color'      => $this->get_prop( 'button_two_bg_color', '#00d1b2' ),
			'--cs-button-color'         => $this->get_prop( 'button_two_color', '#ffffff' ),
			'--cs-button-border-width'  => $this->get_prop( 'button_two_border_width', '0px' ),
			'--cs-button-border-radius' => $this->get_prop( 'button_two_border_radius', '3px' ),
		];

		$html .= '<span class="carousel-slider-hero__cell__button__two" style="' . Helper::array_to_style( $style ) . '">';
		$html .= '<a class="' . $classes . '" href="' . esc_url( $url ) . '" target="' . esc_attr( $target ) . '">' . esc_html( $text ) . '</a>';
		$html .= '</span>';

		return $html;
	}

	/**
	 * Get cell start HTML
	 *
	 * @return string
	 */
	public function get_cell_start(): string {
		$link_type    = $this->get_link_type();
		$slide_link   = $this->get_prop( 'slide_link' );
		$link_target  = $this->get_prop( 'link_target', '_self' );
		$is_full_link = 'full' === $link_type && Validate::url( $slide_link );

		$cell_attr = [
			'class' => 'carousel-slider-hero__cell hero__cell-' . $this->get_item_id(),
			'style' => '--cell-height: ' . $this->get_slide_height(),
		];
		if ( $is_full_link ) {
			$cell_attr = array_merge(
				$cell_attr,
				[
					'href'   => $slide_link,
					'target' => $link_target,
				]
			);
		}

		return '<' . ( $is_full_link ? 'a' : 'div' ) . ' ' . join(
				' ',
				Helper::array_to_attribute( $cell_attr )
			) . '>';
	}

	/**
	 * Get cell end HTML
	 *
	 * @return string
	 */
	public function get_cell_end(): string {
		$is_full_link = 'full' === $this->get_link_type() && Validate::url( $this->get_prop( 'slide_link' ) );

		return $is_full_link ? '</a>' : '</div>'; // .carousel-slider-hero__cell
	}
}
modules/HeroCarousel/Module.php000064400000005336151727276360012574 0ustar00<?php

namespace CarouselSlider\Modules\HeroCarousel;

use CarouselSlider\Helper;
use CarouselSlider\Supports\Sanitize;

defined( 'ABSPATH' ) || exit;

/**
 * Module class
 *
 * @package Modules/HeroCarousel
 */
class Module {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_filter( 'carousel_slider/register_view', [ self::$instance, 'view' ] );
			add_action( 'carousel_slider/save_slider', [ self::$instance, 'save_slider' ], 10, 2 );
			add_action( 'rest_api_init', [ new Controller(), 'register_routes' ] );

			if ( Helper::is_request( 'admin' ) ) {
				Admin::init();
				Ajax::init();
			}
		}

		return self::$instance;
	}

	/**
	 * Register view for hero carousel
	 *
	 * @param  array $views  List of views.
	 *
	 * @return array
	 */
	public function view( array $views ): array {
		$views['hero-banner-slider'] = new View();

		return $views;
	}

	/**
	 * Save slider content and settings
	 *
	 * @param  int   $slider_id  The slider id.
	 * @param  array $data  User submitted data.
	 */
	public function save_slider( int $slider_id, array $data ) {
		if ( isset( $data['carousel_slider_content'] ) ) {
			$_content_slides = is_array( $data['carousel_slider_content'] ) ? $data['carousel_slider_content'] : [];
			$_slides         = array_map(
				function ( $slide ) {
					return Item::sanitize( $slide );
				},
				$_content_slides
			);

			$_slides = array_values( $_slides );

			update_post_meta( $slider_id, '_content_slider', $_slides );
		}

		if ( isset( $data['content_settings'] ) && is_array( $data['content_settings'] ) ) {
			$this->update_content_settings( $slider_id, $data['content_settings'] );
		}
	}

	/**
	 * Update hero carousel settings
	 *
	 * @param  int   $post_id  post id.
	 * @param  array $setting Settings array.
	 */
	private function update_content_settings( int $post_id, array $setting ) {
		$_settings = [
			'slide_height'      => Sanitize::css_dimension( $setting['slide_height'] ),
			'content_width'     => Sanitize::css_dimension( $setting['content_width'] ),
			'content_animation' => sanitize_text_field( $setting['content_animation'] ),
			'slide_padding'     => [
				'top'    => Sanitize::css_dimension( $setting['slide_padding']['top'] ),
				'right'  => Sanitize::css_dimension( $setting['slide_padding']['right'] ),
				'bottom' => Sanitize::css_dimension( $setting['slide_padding']['bottom'] ),
				'left'   => Sanitize::css_dimension( $setting['slide_padding']['left'] ),
			],
		];
		update_post_meta( $post_id, '_content_slider_settings', $_settings );
	}
}
modules/HeroCarousel/Helper.php000064400000005624151727276360012566 0ustar00<?php

namespace CarouselSlider\Modules\HeroCarousel;

defined( 'ABSPATH' ) || exit;

/**
 * Helper class
 *
 * @package Modules/HeroCarousel
 */
class Helper {
	/**
	 * Get background size
	 *
	 * @return array
	 */
	public static function background_size(): array {
		return [
			'auto'      => 'auto',
			'contain'   => 'contain',
			'cover'     => 'cover',
			'100% 100%' => '100%',
			'100% auto' => '100% width',
			'auto 100%' => '100% height',
		];
	}

	/**
	 * Get background positions
	 *
	 * @return array
	 */
	public static function background_position(): array {
		return [
			'left top'      => 'left top',
			'left center'   => 'left center',
			'left bottom'   => 'left bottom',
			'center top'    => 'center top',
			'center center' => 'center',
			'center bottom' => 'center bottom',
			'right top'     => 'right top',
			'right center'  => 'right center',
			'right bottom'  => 'right bottom',
		];
	}

	/**
	 * Get animations
	 *
	 * @return array
	 */
	public static function animations(): array {
		return [
			''            => esc_html__( 'None', 'carousel-slider' ),
			'fadeInDown'  => esc_html__( 'Fade In Down', 'carousel-slider' ),
			'fadeInUp'    => esc_html__( 'Fade In Up', 'carousel-slider' ),
			'fadeInRight' => esc_html__( 'Fade In Right', 'carousel-slider' ),
			'fadeInLeft'  => esc_html__( 'Fade In Left', 'carousel-slider' ),
			'zoomIn'      => esc_html__( 'Zoom In', 'carousel-slider' ),
		];
	}

	/**
	 * Get text alignment
	 *
	 * @return string[]
	 */
	public static function text_alignment(): array {
		return [
			'left'   => 'left',
			'center' => 'center',
			'right'  => 'right',
		];
	}

	/**
	 * Get link type
	 *
	 * @return array
	 */
	public static function link_type(): array {
		return [
			'none'   => esc_html__( 'No Link', 'carousel-slider' ),
			'full'   => esc_html__( 'Full Slide', 'carousel-slider' ),
			'button' => esc_html__( 'Button', 'carousel-slider' ),
		];
	}

	/**
	 * Link target
	 *
	 * @return string[]
	 */
	public static function link_target(): array {
		return [
			'_blank' => __( 'New window', 'carousel-slider' ),
			'_self'  => __( 'Same window', 'carousel-slider' ),
		];
	}

	/**
	 * Ken burns effects
	 *
	 * @return array
	 */
	public static function ken_burns_effects(): array {
		return [
			''         => __( 'None', 'carousel-slider' ),
			'zoom-in'  => __( 'Zoom In', 'carousel-slider' ),
			'zoom-out' => __( 'Zoom Out', 'carousel-slider' ),
		];
	}

	/**
	 * Button size
	 *
	 * @return array
	 */
	public static function button_size(): array {
		return [
			'large'  => esc_html__( 'Large', 'carousel-slider' ),
			'medium' => esc_html__( 'Medium', 'carousel-slider' ),
			'small'  => esc_html__( 'Small', 'carousel-slider' ),
		];
	}

	/**
	 * Button type
	 *
	 * @return array
	 */
	public static function button_type(): array {
		return [
			'normal' => esc_html__( 'Normal', 'carousel-slider' ),
			'stroke' => esc_html__( 'Stroke', 'carousel-slider' ),
		];
	}
}
modules/HeroCarousel/Admin.php000064400000072347151727276360012405 0ustar00<?php

namespace CarouselSlider\Modules\HeroCarousel;

use CarouselSlider\Helper;
use CarouselSlider\Modules\HeroCarousel\Helper as HeroCarouselHelper;
use CarouselSlider\Supports\MetaBoxForm;

defined( 'ABSPATH' ) || exit;

/**
 * Admin class
 *
 * @package Modules/HeroCarousel
 */
class Admin {

	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	private static $instance;

	/**
	 * Only one instance of the class can be loaded
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'carousel_slider/meta_box_content', [ self::$instance, 'meta_box_content' ], 10, 2 );
		}

		return self::$instance;
	}

	/**
	 * Load meta box content
	 *
	 * @param int    $slider_id The slider id.
	 * @param string $slide_type The slider type.
	 */
	public function meta_box_content( int $slider_id, string $slide_type ) {
		if ( 'hero-banner-slider' !== $slide_type ) {
			return;
		}
		global $post;
		?>
		<button class="button carousel-slider__add-slide" data-post-id="<?php echo esc_attr( $slider_id ); ?>">
			Add Slide
		</button>
		<div id="carouselSliderContentInside">
			<?php
			$content_sliders  = get_post_meta( $post->ID, '_content_slider', true );
			$content_sliders  = is_array( $content_sliders ) ? array_values( $content_sliders ) : [];
			$content_settings = get_post_meta( $post->ID, '_content_slider_settings', true );
			$content_settings = is_array( $content_settings ) ? $content_settings : [];

			if ( count( $content_sliders ) > 0 ) {
				$total_sliders = count( $content_sliders );
				foreach ( $content_sliders as $slide_num => $content_slider ) {
					$item = new Item( $content_slider, $content_settings );
					$item->set_setting( new Setting( $post->ID ) );
					$item->set_prop( 'id', $slide_num + 1 );
					$item->set_prop( 'total_items', $total_sliders );

					self::item_meta_box( $item, $total_sliders );
				}
			}
			?>
		</div>

		<?php self::content_meta_box_settings( $post->ID ); ?>
		<?php
	}

	/**
	 * Item meta box
	 *
	 * @param Item $item The Item object.
	 * @param int  $total_items Total items.
	 */
	public static function item_meta_box( Item $item, int $total_items = 0 ) {
		$title       = sprintf( '%s %s', __( 'Slide', 'carousel-slider' ), $item->get_item_id() );
		$action_html = self::get_actions_html( $item->get_slider_id(), $item->get_item_id() - 1, $total_items );
		?>
		<div class="shapla-toggle shapla-toggle--normal" data-id="closed">
			<div class="shapla-toggle-title"><?php echo esc_html( $title ); ?></div>
			<div class="shapla-toggle-inner">
				<div class="shapla-toggle-content">

					<div class="carousel_slider__slide_actions"><?php echo wp_kses_post( $action_html ); ?></div>
					<div class="clear" style="width: 100%; margin-bottom: 1rem; height: 1px;"></div>

					<div class="shapla-section shapla-tabs shapla-tabs--stroke">
						<div class="shapla-tab-inner">

							<ul class="shapla-nav shapla-clearfix">
								<li>
									<a href="#carousel-slider-tab-background">
										<?php
										esc_html_e(
											'Slide Background',
											'carousel-slider'
										);
										?>
									</a>
								</li>
								<li>
									<a href="#carousel-slider-tab-content">
										<?php
										esc_html_e(
											'Slide Content',
											'carousel-slider'
										);
										?>
									</a>
								</li>
								<li>
									<a href="#carousel-slider-tab-link">
										<?php
										esc_html_e(
											'Slide Link',
											'carousel-slider'
										);
										?>
									</a>
								</li>
								<li>
									<a href="#carousel-slider-tab-style">
										<?php
										esc_html_e(
											'Slide Style',
											'carousel-slider'
										);
										?>
									</a>
								</li>
							</ul>

							<div id="carousel-slider-tab-content" class="shapla-tab tab-content">
								<?php self::get_item_tab_content( $item ); ?>
							</div>
							<div id="carousel-slider-tab-link" class="shapla-tab tab-content-link">
								<?php self::get_item_tab_link( $item ); ?>
							</div>
							<div id="carousel-slider-tab-background" class="shapla-tab tab-background">
								<?php self::get_item_tab_background( $item ); ?>
							</div>
							<div id="carousel-slider-tab-style" class="shapla-tab tab-style">
								<?php self::get_item_tab_style( $item ); ?>
							</div>
						</div>
					</div>

					<div class="clear"></div>
				</div>
			</div>
		</div>
		<?php
	}

	/**
	 * Get loop item content
	 *
	 * @param Item $item The Item object.
	 */
	public static function get_item_tab_content( Item $item ) {
		$form = new MetaBoxForm();

		$form->textarea(
			[
				'id'               => 'slide_heading',
				'name'             => esc_html__( 'Slide Heading', 'carousel-slider' ),
				'desc'             => esc_html__( 'Enter the heading for your slide. This field can take HTML markup.', 'carousel-slider' ),
				'rows'             => 3,
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][slide_heading]', $item->get_item_id() ),
					'value' => $item->get_prop( 'slide_heading' ),
				],
			]
		);
		$form->textarea(
			[
				'id'               => 'slide_description',
				'name'             => esc_html__( 'Slide Description', 'carousel-slider' ),
				'desc'             => esc_html__( 'Enter the description for your slide. This field can take HTML markup.', 'carousel-slider' ),
				'rows'             => 4,
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][slide_description]', $item->get_item_id() ),
					'value' => $item->get_prop( 'slide_description' ),
				],
			]
		);
	}

	/**
	 * Get item tab link
	 *
	 * @param Item $item The Item object.
	 */
	public static function get_item_tab_link( Item $item ) {
		$form      = new MetaBoxForm();
		$link_type = $item->get_prop( 'link_type', 'full' );

		$form->select(
			[
				'id'               => 'link_type',
				'class'            => 'sp-input-text link_type',
				'name'             => esc_html__( 'Slide Link Type', 'carousel-slider' ),
				'desc'             => esc_html__( 'Select how the slide will link.', 'carousel-slider' ),
				'options'          => [
					'none'   => esc_html__( 'No Link', 'carousel-slider' ),
					'full'   => esc_html__( 'Full Slide', 'carousel-slider' ),
					'button' => esc_html__( 'Button', 'carousel-slider' ),
				],
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][link_type]', $item->get_item_id() ),
					'value' => $item->get_prop( 'link_type' ),
				],
			]
		);

		echo '<div class="ContentCarouselLinkFull" style="' . ( 'full' === $link_type ? 'display:block' : 'display:none' ) . '">';
		$form->text(
			[
				'id'               => 'slide_link',
				'name'             => esc_html__( 'Slide Link', 'carousel-slider' ),
				'desc'             => esc_html__( 'Please enter your URL that will be used to link the full slide.', 'carousel-slider' ),
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][slide_link]', $item->get_item_id() ),
					'value' => $item->get_prop( 'slide_link' ),
				],
			]
		);
		$form->select(
			[
				'id'               => 'link_target',
				'name'             => esc_html__( 'Open Slide Link In New Window', 'carousel-slider' ),
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][link_target]', $item->get_item_id() ),
					'value' => $item->get_prop( 'link_target' ),
				],
				'options'          => [
					'_blank' => esc_html__( 'Yes', 'carousel-slider' ),
					'_self'  => esc_html__( 'No', 'carousel-slider' ),
				],
			]
		);
		echo '</div>';

		echo '<div class="ContentCarouselLinkButtons" style="' . ( 'button' === $link_type ? 'display:block' : 'display:none' ) . '">';
		self::get_item_tab_link_button_one( $item );
		self::get_item_tab_link_button_two( $item );
		echo '</div>';
	}

	/**
	 * Get loop item button one link
	 *
	 * @param Item $item The Item object.
	 */
	public static function get_item_tab_link_button_one( Item $item ) {
		$form = new MetaBoxForm();
		?>
		<div data-id="closed" id="content_carousel_button_one" class="shapla-toggle shapla-toggle--stroke">
			<span class="shapla-toggle-title">
				<?php esc_html_e( 'Button #1', 'carousel-slider' ); ?>
			</span>
			<div class="shapla-toggle-inner">
				<div class="shapla-toggle-content">
					<?php
					$form->text(
						[
							'id'               => 'button_one_text',
							'name'             => esc_html__( 'Button Text', 'carousel-slider' ),
							'desc'             => esc_html__( 'Add button text', 'carousel-slider' ),
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_one_text]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_one_text' ),
							],
						]
					);
					$form->text(
						[
							'id'               => 'button_one_url',
							'name'             => esc_html__( 'Button URL', 'carousel-slider' ),
							'desc'             => esc_html__( 'Add the button url e.g. https://example.com', 'carousel-slider' ),
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_one_url]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_one_url' ),
							],
						]
					);
					$form->select(
						[
							'id'               => 'button_one_target',
							'name'             => esc_html__( 'Open Button Link In', 'carousel-slider' ),
							'desc'             => esc_html__( 'Add the button url e.g. https://example.com', 'carousel-slider' ),
							'options'          => [
								'_blank' => esc_html__( 'New Window', 'carousel-slider' ),
								'_self'  => esc_html__( 'Same Window', 'carousel-slider' ),
							],
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_one_target]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_one_target', '_self' ),
							],
						]
					);
					$form->select(
						[
							'id'               => 'button_one_type',
							'name'             => esc_html__( 'Button Type', 'carousel-slider' ),
							'options'          => \CarouselSlider\Modules\HeroCarousel\Helper::button_type(),
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_one_type]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_one_type' ),
							],
						]
					);
					$form->select(
						[
							'id'               => 'button_one_size',
							'name'             => esc_html__( 'Button Size', 'carousel-slider' ),
							'options'          => \CarouselSlider\Modules\HeroCarousel\Helper::button_size(),
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_one_size]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_one_size' ),
							],
						]
					);
					$form->text(
						[
							'id'               => 'button_one_border_width',
							'name'             => esc_html__( 'Border Width', 'carousel-slider' ),
							'desc'             => esc_html__( 'Enter border width in pixel. e.g. 2px', 'carousel-slider' ),
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_one_border_width]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_one_border_width' ),
							],
						]
					);
					$form->text(
						[
							'id'               => 'button_one_border_radius',
							'name'             => esc_html__( 'Border Radius', 'carousel-slider' ),
							'desc'             => esc_html__( 'Enter border radius in pixel. e.g. 2px', 'carousel-slider' ),
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_one_border_radius]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_one_border_radius' ),
							],
						]
					);
					$form->color(
						[
							'id'               => 'button_one_bg_color',
							'name'             => esc_html__( 'Button Color', 'carousel-slider' ),
							'std'              => '#00d1b2',
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_one_bg_color]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_one_bg_color', '#00d1b2' ),
							],
						]
					);
					$form->color(
						[
							'id'               => 'button_one_color',
							'name'             => esc_html__( 'Button Text Color', 'carousel-slider' ),
							'std'              => '#ffffff',
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_one_color]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_one_color', '#ffffff' ),
							],
						]
					);
					?>
				</div>
			</div>
		</div>
		<?php
	}

	/**
	 * Get loop item button two link
	 *
	 * @param Item $item The Item object.
	 */
	public static function get_item_tab_link_button_two( Item $item ) {
		$form = new MetaBoxForm();
		?>
		<div data-id="closed" id="content_carousel_button_one" class="shapla-toggle shapla-toggle--stroke">
			<span class="shapla-toggle-title">
				<?php esc_html_e( 'Button #2', 'carousel-slider' ); ?>
			</span>
			<div class="shapla-toggle-inner">
				<div class="shapla-toggle-content">
					<?php
					$form->text(
						[
							'id'               => 'button_two_text',
							'name'             => esc_html__( 'Button Text', 'carousel-slider' ),
							'desc'             => esc_html__( 'Add button text', 'carousel-slider' ),
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_two_text]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_two_text' ),
							],
						]
					);
					$form->text(
						[
							'id'               => 'button_two_url',
							'name'             => esc_html__( 'Button URL', 'carousel-slider' ),
							'desc'             => esc_html__( 'Add the button url e.g. https://example.com', 'carousel-slider' ),
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_two_url]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_two_url' ),
							],
						]
					);
					$form->select(
						[
							'id'               => 'button_two_target',
							'name'             => esc_html__( 'Open Button Link In', 'carousel-slider' ),
							'desc'             => esc_html__( 'Add the button url e.g. https://example.com', 'carousel-slider' ),
							'options'          => [
								'_blank' => esc_html__( 'New Window', 'carousel-slider' ),
								'_self'  => esc_html__( 'Same Window', 'carousel-slider' ),
							],
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_two_target]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_two_target' ),
							],
						]
					);
					$form->select(
						[
							'id'               => 'button_two_type',
							'name'             => esc_html__( 'Button Type', 'carousel-slider' ),
							'options'          => [
								'normal' => esc_html__( 'Normal', 'carousel-slider' ),
								'stroke' => esc_html__( 'Stroke', 'carousel-slider' ),
							],
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_two_type]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_two_type', 'normal' ),
							],
						]
					);
					$form->select(
						[
							'id'               => 'button_two_size',
							'name'             => esc_html__( 'Button Size', 'carousel-slider' ),
							'options'          => [
								'large'  => esc_html__( 'Large', 'carousel-slider' ),
								'medium' => esc_html__( 'Medium', 'carousel-slider' ),
								'small'  => esc_html__( 'Small', 'carousel-slider' ),
							],
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_two_size]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_two_size' ),
							],
						]
					);
					$form->text(
						[
							'id'               => 'button_two_border_width',
							'name'             => esc_html__( 'Border Width', 'carousel-slider' ),
							'desc'             => esc_html__( 'Enter border width in pixel. e.g. 2px', 'carousel-slider' ),
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_two_border_width]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_two_border_width' ),
							],
						]
					);
					$form->text(
						[
							'id'               => 'button_two_border_radius',
							'name'             => esc_html__( 'Border Radius', 'carousel-slider' ),
							'desc'             => esc_html__( 'Enter border radius in pixel. e.g. 2px', 'carousel-slider' ),
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_two_border_radius]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_two_border_radius' ),
							],
						]
					);
					$form->color(
						[
							'id'               => 'button_two_bg_color',
							'name'             => esc_html__( 'Button Color', 'carousel-slider' ),
							'std'              => '#00d1b2',
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_two_bg_color]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_two_bg_color' ),
							],
						]
					);
					$form->color(
						[
							'id'               => 'button_two_color',
							'name'             => esc_html__( 'Button Text Color', 'carousel-slider' ),
							'std'              => '#ffffff',
							'input_attributes' => [
								'name'  => sprintf( 'carousel_slider_content[%s][button_two_color]', $item->get_item_id() ),
								'value' => $item->get_prop( 'button_two_color' ),
							],
						]
					);
					?>
				</div>
			</div>
		</div>
		<?php
	}

	/**
	 * Get loop item background
	 *
	 * @param Item $item The Item object.
	 */
	public static function get_item_tab_background( Item $item ) {
		$form     = new MetaBoxForm();
		$bg_image = wp_get_attachment_image_src( $item->get_prop( 'img_id' ), 'full' );

		// Canvas style.
		$canvas_style = [
			'background-repeat'   => 'no-repeat',
			'background-position' => $item->get_prop( 'img_bg_position', 'center center' ),
			'background-size'     => $item->get_prop( 'img_bg_size', 'cover' ),
			'background-color'    => $item->get_prop( 'bg_color' ),
		];
		if ( is_array( $bg_image ) ) {
			$canvas_style['background-image'] = 'url(' . $bg_image[0] . ')';
		}
		$canvas_style = Helper::array_to_style( $canvas_style );
		?>
		<div class="slide_bg_wrapper">
			<div class="slide-media-left">
				<div class="slide_thumb">
					<div class="content_slide_canvas"
						 style="<?php echo esc_attr( $canvas_style ); ?>"></div>
					<span class="delete-bg-img<?php echo ! is_array( $bg_image ) ? ' hidden' : ''; ?>"
						  title="<?php esc_html_e( 'Delete the background image for this slide', 'carousel-slider' ); ?>">&times;</span>
				</div>
			</div>
			<div class="slide-media-right">
				<?php
				$form->upload_iframe(
					[
						'id'               => 'img_id',
						'class'            => 'background_image_id',
						'label'            => esc_html__( 'Background Image', 'carousel-slider' ),
						'input_attributes' => [
							'name'  => sprintf( 'carousel_slider_content[%s][img_id]', $item->get_item_id() ),
							'value' => $item->get_prop( 'img_id' ),
						],
					]
				);
				$form->select(
					[
						'id'               => 'img_bg_position',
						'class'            => 'sp-input-text background_image_position',
						'name'             => esc_html__( 'Background Position', 'carousel-slider' ),
						'options'          => HeroCarouselHelper::background_position(),
						'input_attributes' => [
							'name'  => sprintf( 'carousel_slider_content[%s][img_bg_position]', $item->get_item_id() ),
							'value' => $item->get_prop( 'img_bg_position' ),
						],
					]
				);
				$form->select(
					[
						'id'               => 'img_bg_size',
						'class'            => 'sp-input-text background_image_size',
						'name'             => esc_html__( 'Background Size', 'carousel-slider' ),
						'options'          => HeroCarouselHelper::background_size(),
						'input_attributes' => [
							'name'  => sprintf( 'carousel_slider_content[%s][img_bg_size]', $item->get_item_id() ),
							'value' => $item->get_prop( 'img_bg_size' ),
						],
					]
				);
				$form->select(
					[
						'id'               => 'ken_burns_effect',
						'name'             => esc_html__( 'Ken Burns Effect', 'carousel-slider' ),
						'options'          => HeroCarouselHelper::ken_burns_effects(),
						'input_attributes' => [
							'name'  => sprintf( 'carousel_slider_content[%s][ken_burns_effect]', $item->get_item_id() ),
							'value' => $item->get_prop( 'ken_burns_effect' ),
						],
					]
				);
				$form->color(
					[
						'id'               => 'bg_color',
						'name'             => esc_html__( 'Background Color', 'carousel-slider' ),
						'std'              => 'rgba(255,255,255,0.5)',
						'input_attributes' => [
							'name'  => sprintf( 'carousel_slider_content[%s][bg_color]', $item->get_item_id() ),
							'value' => $item->get_prop( 'bg_color' ),
						],
					]
				);
				$form->color(
					[
						'id'               => 'bg_overlay',
						'name'             => esc_html__( 'Background Overlay', 'carousel-slider' ),
						'std'              => 'rgba(0,0,0,0.5)',
						'input_attributes' => [
							'name'  => sprintf( 'carousel_slider_content[%s][bg_overlay]', $item->get_item_id() ),
							'value' => $item->get_prop( 'bg_overlay' ),
						],
					]
				);
				?>
			</div>
		</div>
		<?php
	}

	/**
	 * Get item tab style
	 *
	 * @param Item $item The Item object.
	 */
	public static function get_item_tab_style( Item $item ) {
		$form = new MetaBoxForm();

		$form->select(
			[
				'id'               => 'content_alignment',
				'name'             => esc_html__( 'Content Alignment', 'carousel-slider' ),
				'desc'             => esc_html__( 'Select how the heading, description and buttons will be aligned', 'carousel-slider' ),
				'std'              => 'left',
				'options'          => HeroCarouselHelper::text_alignment(),
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][content_alignment]', $item->get_item_id() ),
					'value' => $item->get_prop( 'content_alignment' ),
				],
			]
		);
		$form->number(
			[
				'id'               => 'heading_font_size',
				'name'             => esc_html__( 'Heading Font Size', 'carousel-slider' ),
				'desc'             => esc_html__( 'Enter heading font size without px unit. In pixels, ex: 50 instead of 50px. Default: 60', 'carousel-slider' ),
				'std'              => '60',
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][heading_font_size]', $item->get_item_id() ),
					'value' => $item->get_prop( 'heading_font_size' ),
				],
			]
		);
		$form->text(
			[
				'id'               => 'heading_gutter',
				'name'             => esc_html__( 'Spacing/Gutter', 'carousel-slider' ),
				'desc'             => esc_html__( 'Enter gutter (space between description and heading) in px, em or rem, ex: 3rem', 'carousel-slider' ),
				'std'              => '30px',
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][heading_gutter]', $item->get_item_id() ),
					'value' => $item->get_prop( 'heading_gutter' ),
				],
			]
		);
		$form->color(
			[
				'id'               => 'heading_color',
				'name'             => esc_html__( 'Heading Color', 'carousel-slider' ),
				'desc'             => esc_html__( 'Select a color for the heading font. Default: #fff', 'carousel-slider' ),
				'std'              => '#ffffff',
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][heading_color]', $item->get_item_id() ),
					'value' => $item->get_prop( 'heading_color' ),
				],
			]
		);
		$form->text(
			[
				'id'               => 'description_font_size',
				'name'             => esc_html__( 'Description Font Size', 'carousel-slider' ),
				'desc'             => esc_html__( 'Enter description font size without px unit. In pixels, ex: 20 instead of 20px. Default: 24', 'carousel-slider' ),
				'std'              => '24',
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][description_font_size]', $item->get_item_id() ),
					'value' => $item->get_prop( 'description_font_size' ),
				],
			]
		);
		$form->text(
			[
				'id'               => 'description_gutter',
				'name'             => esc_html__( 'Description Spacing/Gutter', 'carousel-slider' ),
				'desc'             => esc_html__( 'Enter gutter (space between description and buttons) in px, em or rem, ex: 3rem', 'carousel-slider' ),
				'std'              => '30px',
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][description_gutter]', $item->get_item_id() ),
					'value' => $item->get_prop( 'description_gutter' ),
				],
			]
		);
		$form->color(
			[
				'id'               => 'description_color',
				'name'             => esc_html__( 'Description Color', 'carousel-slider' ),
				'desc'             => esc_html__( 'Select a color for the description font. Default: #fff', 'carousel-slider' ),
				'std'              => '#ffffff',
				'input_attributes' => [
					'name'  => sprintf( 'carousel_slider_content[%s][description_color]', $item->get_item_id() ),
					'value' => $item->get_prop( 'description_color' ),
				],
			]
		);
	}

	/**
	 * Get action HTML
	 *
	 * @param int $slider_id The slider id.
	 * @param int $item_index The slider item index number.
	 * @param int $total_items Total slide in a slider.
	 *
	 * @return string
	 */
	public static function get_actions_html( int $slider_id, int $item_index, int $total_items ): string {
		$can_move_up   = 0 !== $item_index;
		$can_move_down = ( $total_items - 1 ) !== $item_index;
		$buttons       = [
			[
				'action' => 'delete_slide',
				'icon'   => 'trash',
				'title'  => __( 'Delete current slide', 'carousel-slider' ),
			],
		];
		if ( $can_move_up ) {
			$buttons[] = [
				'action' => 'move_top',
				'icon'   => 'arrow-up-alt',
				'title'  => __( 'Move Slide to Top', 'carousel-slider' ),
			];
			$buttons[] = [
				'action' => 'move_up',
				'icon'   => 'arrow-up-alt2',
				'title'  => __( 'Move Slide Up', 'carousel-slider' ),
			];
		}
		if ( $can_move_down ) {
			$buttons[] = [
				'action' => 'move_down',
				'icon'   => 'arrow-down-alt2',
				'title'  => __( 'Move Slide Down', 'carousel-slider' ),
			];
			$buttons[] = [
				'action' => 'move_bottom',
				'icon'   => 'arrow-down-alt',
				'title'  => __( 'Move Slide to Bottom', 'carousel-slider' ),
			];
		}
		$html = '';
		foreach ( $buttons as $button ) {
			$html .= sprintf(
				'<button class="button carousel_slider__%s" data-post-id="%s" data-slide-pos="%s" title="%s">',
				$button['action'],
				$slider_id,
				$item_index,
				$button['title']
			);
			$html .= sprintf( '<span class="dashicons dashicons-%s"></span>', $button['icon'] );
			$html .= '</button>';
		}

		return $html;
	}

	/**
	 * Get content settings
	 *
	 * @param int $slider_id The slider id.
	 */
	public static function content_meta_box_settings( int $slider_id ) {
		$content_settings   = get_post_meta( $slider_id, '_content_slider_settings', true );
		$_slide_height      = $content_settings['slide_height'] ?? '400px';
		$_content_width     = $content_settings['content_width'] ?? '850px';
		$_content_animation = $content_settings['content_animation'] ?? '';
		$form               = new MetaBoxForm();

		echo '<div class="content_settings">';
		$form->text(
			[
				'group'            => 'content_settings',
				'id'               => 'slide_height',
				'name'             => esc_html__( 'Slide Height', 'carousel-slider' ),
				'desc'             => esc_html__( 'Enter a px, em, rem or vh value for slide height. ex: 100vh', 'carousel-slider' ),
				'std'              => '400px',
				'input_attributes' => [
					'name'  => 'content_settings[slide_height]',
					'value' => $_slide_height,
				],
			]
		);
		$form->text(
			[
				'group'            => 'content_settings',
				'id'               => 'content_width',
				'name'             => esc_html__( 'Slider Content Max Width', 'carousel-slider' ),
				'desc'             => esc_html__( 'Enter a px, em, rem or % value for slide height. ex: 960px', 'carousel-slider' ),
				'std'              => '850px',
				'input_attributes' => [
					'name'  => 'content_settings[content_width]',
					'value' => $_content_width,
				],
			]
		);
		$form->select(
			[
				'group'            => 'content_settings',
				'id'               => 'content_animation',
				'name'             => esc_html__( 'Content Animation', 'carousel-slider' ),
				'desc'             => esc_html__( 'Select slide content animation.', 'carousel-slider' ),
				'std'              => 'fadeOut',
				'options'          => HeroCarouselHelper::animations(),
				'input_attributes' => [
					'name'  => 'content_settings[content_animation]',
					'value' => $_content_animation,
				],
			]
		);
		$form->spacing(
			[
				'meta_key'         => '_content_slider_settings',
				'group'            => 'content_settings',
				'id'               => 'slide_padding',
				'name'             => esc_html__( 'Slider Padding', 'carousel-slider' ),
				'desc'             => esc_html__( 'Enter padding around slide in px, em or rem.', 'carousel-slider' ),
				'default'          => [
					'top'    => '1rem',
					'right'  => '1rem',
					'bottom' => '1rem',
					'left'   => '1rem',
				],
				'input_attributes' => [
					'value' => isset( $content_settings['slide_padding'] ) && is_array( $content_settings['slide_padding'] ) ?
						$content_settings['slide_padding'] : [],
				],
			]
		);
		echo '</div>';
	}
}
modules/HeroCarousel/View.php000064400000003550151727276370012256 0ustar00<?php

namespace CarouselSlider\Modules\HeroCarousel;

use CarouselSlider\Abstracts\AbstractView;
use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\TemplateParserBase;

defined( 'ABSPATH' ) || exit;

/**
 * View class
 *
 * @package Modules/HeroCarousel
 */
class View extends AbstractView {

	/**
	 * Get slider setting
	 *
	 * @return Setting
	 */
	public function get_slider_setting(): Setting {
		if ( ! $this->slider_setting instanceof SliderSetting ) {
			$this->slider_setting = new Setting( $this->get_slider_id() );
		}

		return $this->slider_setting;
	}

	/**
	 * Render html content
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$slider_id         = $this->get_slider_id();
		$items             = get_post_meta( $slider_id, '_content_slider', true );
		$items             = is_array( $items ) ? array_values( $items ) : [];
		$settings          = get_post_meta( $slider_id, '_content_slider_settings', true );
		$content_animation = ! empty( $settings['content_animation'] ) ? esc_attr( $settings['content_animation'] ) : '';

		$template = new TemplateParserBase( $this->get_slider_setting() );
		$template->set_template( 'loop/hero-banner-slider.php' );

		$html = $this->start_wrapper_html( [ 'data-animation' => $content_animation ] );
		foreach ( $items as $slide_id => $slide ) {
			$item = new Item( $slide );
			$item->set_prop( 'id', $slide_id + 1 );
			$item->set_setting( $this->get_slider_setting() );

			$template->set_object( $item );

			$item_html  = $this->start_item_wrapper_html();
			$item_html .= $template->render();
			$item_html .= $this->end_item_wrapper_html();

			$html .= apply_filters( 'carousel_slider/loop/hero-banner-slider', $item_html, $item, $this->get_slider_setting() ) . PHP_EOL;
		}

		$html .= $this->end_wrapper_html();

		return apply_filters( 'carousel_slider_hero_banner_carousel', $html, $slider_id );
	}
}
modules/HeroCarousel/Setting.php000064400000003014151727276370012754 0ustar00<?php

namespace CarouselSlider\Modules\HeroCarousel;

use CarouselSlider\Abstracts\SliderSetting;

/**
 * Settings class
 */
class Setting extends SliderSetting {
	/**
	 * Is data read from the server?
	 *
	 * @var bool
	 */
	protected $extra_data_read = false;

	/**
	 * Get slider items
	 *
	 * @return Item[]
	 */
	public function get_slider_items(): array {
		$items = get_post_meta( $this->get_slider_id(), '_content_slider', true );
		$items = is_array( $items ) ? array_values( $items ) : [];
		$data  = [];
		foreach ( $items as $item ) {
			$data[] = new Item( $item, $this->get_prop( 'slider_settings' ) );
		}

		return $data;
	}

	/**
	 * Get content settings
	 *
	 * @return array
	 */
	public function get_content_settings(): array {
		return $this->get_prop( 'slider_settings', [] );
	}

	/**
	 * Read extra metadata
	 *
	 * @return void
	 */
	public function read_extra_metadata() {
		if ( $this->extra_data_read ) {
			return;
		}
		foreach ( self::extra_props() as $attribute => $config ) {
			$value = get_post_meta( $this->get_slider_id(), $config['id'], true );
			$value = ! empty( $value ) ? $value : $config['default'];
			$value = $this->prepare_item_for_response( $config['type'], $value );
			$this->set_prop( $attribute, $value );
		}
		$this->extra_data_read = true;
	}

	/**
	 * Slider extra props
	 *
	 * @return array
	 */
	public static function extra_props(): array {
		return [
			'slider_settings' => [
				'id'      => '_content_slider_settings',
				'type'    => 'array',
				'default' => [],
			],
		];
	}
}
modules/HeroCarousel/Controller.php000064400000061437151727276370013477 0ustar00<?php

namespace CarouselSlider\Modules\HeroCarousel;

use CarouselSlider\REST\ApiController;
use CarouselSlider\Supports\Sanitize;
use WP_Error;
use WP_Post;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

/**
 * Controller class
 */
class Controller extends ApiController {
	/**
	 * Registers the routes for the objects of the controller.
	 */
	public function register_routes() {
		register_rest_route(
			$this->namespace,
			'/carousels/hero',
			[
				[
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => [ $this, 'create_item' ],
					'permission_callback' => [ $this, 'create_item_permissions_check' ],
					'args'                => $this->get_create_item_params(),
				],
			]
		);
		register_rest_route(
			$this->namespace,
			'/carousels/hero/(?P<id>[\d]+)',
			[
				'args' => [
					'id' => [
						'description' => __( 'Unique identifier for the carousel.', 'carousel-slider' ),
						'type'        => 'integer',
					],
				],
				[
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => [ $this, 'get_item' ],
					'permission_callback' => [ $this, 'get_item_permissions_check' ],
				],
				[
					'methods'             => WP_REST_Server::EDITABLE,
					'callback'            => [ $this, 'update_item' ],
					'permission_callback' => [ $this, 'create_item_permissions_check' ],
					'args'                => $this->get_create_item_params(),
				],
			]
		);
	}

	/**
	 * Creates one item from the collection.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response Response object.
	 */
	public function create_item( $request ) {
		$title = $request->get_param( 'title' );

		$slider_id = \CarouselSlider\Helper::create_slider( $title, 'hero-banner-slider' );
		if ( is_wp_error( $slider_id ) ) {
			return $this->respond_with_wp_error( $slider_id );
		}

		$general_settings = $request->get_param( 'general_settings' );
		$this->update_general_setting( $slider_id, $general_settings );

		$items        = $request->get_param( 'slider_items' );
		$slider_items = array_map( [ $this, 'prepare_slider_item_for_database' ], $items );
		update_post_meta( $slider_id, '_content_slider', $slider_items );

		$slider_settings = $request->get_param( 'slider_settings' );
		update_post_meta( $slider_id, '_content_slider_settings', $slider_settings );

		$settings         = new Setting( $slider_id );
		$general_settings = $settings->to_array();

		if ( isset( $general_settings['slider_settings'] ) ) {
			unset( $general_settings['slider_settings'] );
		}

		return $this->respond_created(
			[
				'title'            => $title,
				'slider_type'      => $settings->get_slider_type(),
				'slider_status'    => get_post_status( $slider_id ),
				'global_settings'  => $settings->get_global_settings(),
				'general_settings' => $general_settings,
				'slider_settings'  => $settings->get_content_settings(),
				'slider_items'     => $items,
			]
		);
	}

	/**
	 * Retrieves one item from the collection.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response Response object.
	 */
	public function get_item( $request ) {
		$id   = (int) $request->get_param( 'id' );
		$post = get_post( $id );

		$settings         = new Setting( $id );
		$general_settings = $settings->to_array();
		$items            = $settings->get_slider_items();
		$items            = array_map( [ $this, 'prepare_slider_item_for_response' ], $items );

		if ( isset( $general_settings['slider_settings'] ) ) {
			unset( $general_settings['slider_settings'] );
		}

		return $this->respond_ok(
			[
				'title'            => get_the_title( $post ),
				'slider_type'      => $settings->get_slider_type(),
				'slider_status'    => $post->post_status,
				'global_settings'  => $settings->get_global_settings(),
				'general_settings' => $general_settings,
				'slider_settings'  => $settings->get_content_settings(),
				'slider_items'     => $items,
			]
		);
	}

	/**
	 * Updates one item from the collection.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response Response object.
	 */
	public function update_item( $request ) {
		$slider_id = (int) $request->get_param( 'id' );
		$post      = get_post( $slider_id );
		if ( ! ( $post instanceof WP_Post && CAROUSEL_SLIDER_POST_TYPE === $post->post_type ) ) {
			return $this->respond_not_found();
		}

		$title = $request->get_param( 'title' );
		if ( get_the_title( $post ) !== $title ) {
			wp_update_post(
				[
					'ID'    => $slider_id,
					'title' => $title,
				]
			);
		}

		$general_settings = $request->get_param( 'general_settings' );
		$this->update_general_setting( $slider_id, $general_settings );

		$items        = $request->get_param( 'slider_items' );
		$slider_items = array_map( [ $this, 'prepare_slider_item_for_database' ], $items );
		update_post_meta( $slider_id, '_content_slider', $slider_items );

		$slider_settings = $request->get_param( 'slider_settings' );
		update_post_meta( $slider_id, '_content_slider_settings', $slider_settings );

		$settings         = new Setting( $slider_id );
		$general_settings = $settings->to_array();

		if ( isset( $general_settings['slider_settings'] ) ) {
			unset( $general_settings['slider_settings'] );
		}

		return $this->respond_ok(
			[
				'title'            => $title,
				'slider_type'      => $settings->get_slider_type(),
				'slider_status'    => get_post_status( $slider_id ),
				'global_settings'  => $settings->get_global_settings(),
				'general_settings' => $general_settings,
				'slider_settings'  => $settings->get_content_settings(),
				'slider_items'     => $items,
			]
		);
	}

	/**
	 * Sanitize general settings.
	 *
	 * @param mixed $data Raw data.
	 *
	 * @return array
	 */
	public function sanitize_general_setting( $data ): array {
		$sanitized_data = parent::sanitize_general_setting( $data );

		$sanitized_data['type_of_slider']  = 'slider';
		$sanitized_data['slides_per_view'] = [ 'xs' => 1 ];

		return $sanitized_data;
	}

	/**
	 * Sanitize hero slider settings
	 *
	 * @param mixed $data The raw data.
	 *
	 * @return array
	 */
	public function sanitize_hero_slider_settings( $data ): array {
		$default = [
			'slide_height'      => '400px',
			'content_width'     => '850px',
			'content_animation' => 'zoomIn',
			'slide_padding'     => [
				'top'    => '1rem',
				'right'  => '1rem',
				'bottom' => '1rem',
				'left'   => '1rem',
			],
		];
		if ( ! is_array( $data ) ) {
			return $default;
		}

		return wp_parse_args( $data, $default );
	}

	/**
	 * Sanitize hero slider items
	 *
	 * @param mixed $data The data to be sanitized.
	 *
	 * @return array
	 */
	public function sanitize_hero_slider_items( $data ): array {
		if ( ! is_array( $data ) ) {
			return [];
		}
		$sanitized_data = [];
		foreach ( $data as $index => $value ) {
			if ( ! is_array( $value ) ) {
				continue;
			}
			$sanitized_data[] = $this->sanitize_hero_slider_item( $value );
		}

		return $sanitized_data;
	}

	/**
	 * Sanitize hero slider item.
	 *
	 * @param array $value The value to be sanitized.
	 *
	 * @return array
	 */
	public function sanitize_hero_slider_item( array $value ): array {
		$sanitized_data = [
			'background_type' => $value['background_type'],
		];

		if ( 'image' === $value['background_type'] && is_array( $value['bg_image'] ) ) {
			$default                    = [
				'img_id'           => '',
				'img_position'     => Item::get_default_value( 'img_bg_position' ),
				'img_size'         => Item::get_default_value( 'img_bg_size' ),
				'overlay_color'    => Item::get_default_value( 'bg_overlay' ),
				'ken_burns_effect' => Item::get_default_value( 'ken_burns_effect' ),
			];
			$bg_image                   = wp_parse_args( $value['bg_image'], $default );
			$sanitized_data['bg_image'] = [
				'img_id'           => Sanitize::int( $bg_image['img_id'] ),
				'img_position'     => Sanitize::text( $bg_image['img_position'] ),
				'img_size'         => Sanitize::text( $bg_image['img_size'] ),
				'overlay_color'    => Sanitize::color( $bg_image['overlay_color'] ),
				'ken_burns_effect' => Sanitize::text( $bg_image['ken_burns_effect'] ),
			];
		}

		if ( 'color' === $value['background_type'] ) {
			$sanitized_data['bg_color'] = Sanitize::color( $value['bg_color'] );
		}

		$sanitized_data['content_alignment'] = $value['content_alignment'] ?? Item::get_default_value( 'content_alignment' );
		$sanitized_data['content_animation'] = $value['content_animation'] ?? '';

		$heading_default           = [
			'text'          => Item::get_default_value( 'slide_heading' ),
			'font_size'     => Item::get_default_value( 'heading_font_size' ),
			'margin_bottom' => Item::get_default_value( 'heading_gutter' ),
			'color'         => Item::get_default_value( 'heading_color' ),
		];
		$sanitized_data['heading'] = wp_parse_args( $value['heading'], $heading_default );

		if ( ! empty( $value['description']['text'] ) ) {
			$description_default           = [
				'text'          => Item::get_default_value( 'slide_description' ),
				'font_size'     => Item::get_default_value( 'description_font_size' ),
				'margin_bottom' => Item::get_default_value( 'description_gutter' ),
				'color'         => Item::get_default_value( 'description_color' ),
			];
			$sanitized_data['description'] = wp_parse_args( $value['description'], $description_default );
		}

		$sanitized_data['link_type'] = $value['link_type'] ?? Item::get_default_value( 'link_type' );

		if ( 'full' === $sanitized_data['link_type'] ) {
			$sanitized_data['full_link'] = [
				'url'    => $value['full_link']['url'],
				'target' => $value['full_link']['target'] ?? Item::get_default_value( 'link_target' ),
			];
		}
		if ( 'button' === $sanitized_data['link_type'] ) {
			if ( ! empty( $value['button_link']['primary']['text'] ) && ! empty( $value['button_link']['primary']['url'] ) ) {
				$primary_button_default = [
					'text'          => Item::get_default_value( 'button_one_text' ),
					'url'           => Item::get_default_value( 'button_one_url' ),
					'target'        => Item::get_default_value( 'button_one_target' ),
					'type'          => Item::get_default_value( 'button_one_type' ),
					'size'          => Item::get_default_value( 'button_one_size' ),
					'border_width'  => Item::get_default_value( 'button_one_border_width' ),
					'border_radius' => Item::get_default_value( 'button_one_border_radius' ),
					'bg_color'      => Item::get_default_value( 'button_one_bg_color' ),
					'color'         => Item::get_default_value( 'button_one_color' ),
				];
				$primary_button         = wp_parse_args( $value['button_link']['primary'], $primary_button_default );

				$sanitized_data['button_link']['primary'] = $primary_button;
			}
			if ( ! empty( $value['button_link']['secondary']['text'] ) && ! empty( $value['button_link']['secondary']['url'] ) ) {
				$secondary_button_default = [
					'text'          => Item::get_default_value( 'button_two_text' ),
					'url'           => Item::get_default_value( 'button_two_url' ),
					'target'        => Item::get_default_value( 'button_two_target' ),
					'type'          => Item::get_default_value( 'button_two_type' ),
					'size'          => Item::get_default_value( 'button_two_size' ),
					'border_width'  => Item::get_default_value( 'button_two_border_width' ),
					'border_radius' => Item::get_default_value( 'button_two_border_radius' ),
					'bg_color'      => Item::get_default_value( 'button_two_bg_color' ),
					'color'         => Item::get_default_value( 'button_two_color' ),
				];
				$secondary_button         = wp_parse_args( $value['button_link']['secondary'], $secondary_button_default );

				$sanitized_data['button_link']['secondary'] = $secondary_button;
			}
		}

		return $sanitized_data;
	}

	/**
	 * Prepare slider item for response
	 *
	 * @param Item $item The Item object.
	 *
	 * @return array
	 */
	public function prepare_slider_item_for_response( Item $item ): array {
		$data = [
			'background_type'   => $item->get_background_type(),
			'bg_color'          => $item->get_prop( 'bg_color' ),
			'bg_image'          => [
				'img_id'           => $item->get_prop( 'img_id' ),
				'img_position'     => $item->get_prop( 'img_bg_position' ),
				'img_size'         => $item->get_prop( 'img_bg_size' ),
				'overlay_color'    => $item->get_prop( 'bg_overlay' ),
				'ken_burns_effect' => $item->get_prop( 'ken_burns_effect' ),
			],
			'content_alignment' => $item->get_prop( 'content_alignment' ),
			'content_animation' => $item->get_content_animation(),
			'heading'           => [
				'text'          => $item->get_prop( 'slide_heading' ),
				'font_size'     => $item->get_prop( 'heading_font_size' ),
				'margin_bottom' => $item->get_prop( 'heading_gutter' ),
				'color'         => $item->get_prop( 'heading_color' ),
			],
			'description'       => [
				'text'          => $item->get_prop( 'slide_description' ),
				'font_size'     => $item->get_prop( 'description_font_size' ),
				'margin_bottom' => $item->get_prop( 'description_gutter' ),
				'color'         => $item->get_prop( 'description_color' ),
			],
			'link_type'         => $item->get_link_type(),
			'full_link'         => [
				'url'    => $item->get_prop( 'slide_link' ),
				'target' => $item->get_prop( 'link_target' ),
			],
			'button_link'       => [
				'primary'   => new \ArrayObject(),
				'secondary' => new \ArrayObject(),
			],
		];

		if ( $item->has_button_one() ) {
			$data['button_link']['primary'] = [
				'text'          => $item->get_prop( 'button_one_text' ),
				'url'           => $item->get_prop( 'button_one_url' ),
				'target'        => $item->get_prop( 'button_one_target' ),
				'type'          => $item->get_prop( 'button_one_type' ),
				'size'          => $item->get_prop( 'button_one_size' ),
				'border_width'  => $item->get_prop( 'button_one_border_width' ),
				'border_radius' => $item->get_prop( 'button_one_border_radius' ),
				'bg_color'      => $item->get_prop( 'button_one_bg_color' ),
				'color'         => $item->get_prop( 'button_one_color' ),
			];
		}

		if ( $item->has_button_two() ) {
			$data['button_link']['primary'] = [
				'text'          => $item->get_prop( 'button_two_text' ),
				'url'           => $item->get_prop( 'button_two_url' ),
				'target'        => $item->get_prop( 'button_two_target' ),
				'type'          => $item->get_prop( 'button_two_type' ),
				'size'          => $item->get_prop( 'button_two_size' ),
				'border_width'  => $item->get_prop( 'button_two_border_width' ),
				'border_radius' => $item->get_prop( 'button_two_border_radius' ),
				'bg_color'      => $item->get_prop( 'button_two_bg_color' ),
				'color'         => $item->get_prop( 'button_two_color' ),
			];
		}

		return $data;
	}

	/**
	 * Prepare slider item for database
	 *
	 * @param array $data Raw data.
	 *
	 * @return string[]
	 */
	public function prepare_slider_item_for_database( array $data ): array {
		$default        = Item::get_default();
		$sanitized_data = [
			'background_type'   => $data['background_type'],
			'content_alignment' => $data['content_alignment'],
			'content_animation' => $data['content_animation'],
			'link_type'         => $data['link_type'],
		];
		if ( 'color' === $data['background_type'] ) {
			$sanitized_data['bg_color'] = $data['bg_color'] ?? '';
		}
		if ( 'image' === $data['background_type'] && is_array( $data['bg_image'] ) ) {
			$sanitized_data['img_id']           = $data['bg_image']['img_id'];
			$sanitized_data['img_bg_position']  = $data['bg_image']['img_position'];
			$sanitized_data['img_bg_size']      = $data['bg_image']['img_size'];
			$sanitized_data['ken_burns_effect'] = $data['bg_image']['ken_burns_effect'];
			$sanitized_data['bg_overlay']       = $data['bg_image']['overlay_color'];
		}

		if ( ! empty( $data['heading']['text'] ) ) {
			$sanitized_data['slide_heading']     = $data['heading']['text'];
			$sanitized_data['heading_font_size'] = $data['heading']['font_size'];
			$sanitized_data['heading_gutter']    = $data['heading']['margin_bottom'];
			$sanitized_data['heading_color']     = $data['heading']['color'];
		}

		if ( ! empty( $data['description']['text'] ) ) {
			$sanitized_data['slide_description']     = $data['description']['text'];
			$sanitized_data['description_font_size'] = $data['description']['font_size'];
			$sanitized_data['description_gutter']    = $data['description']['margin_bottom'];
			$sanitized_data['description_color']     = $data['description']['color'];
		}

		if ( 'full' === $data['link_type'] ) {
			$sanitized_data['slide_link']  = $data['full_link']['url'];
			$sanitized_data['link_target'] = $data['full_link']['target'];
		}

		if ( 'button' === $data['link_type'] && isset( $data['button_link'] ) ) {
			if ( isset( $data['button_link']['primary'] ) ) {
				foreach ( $data['button_link']['primary'] as $key_suffix => $value ) {
					$sanitized_data[ 'button_one_' . $key_suffix ] = $value;
				}
			}
			if ( isset( $data['button_link']['secondary'] ) ) {
				foreach ( $data['button_link']['secondary'] as $key_suffix => $value ) {
					$sanitized_data[ 'button_two_' . $key_suffix ] = $value;
				}
			}
		}

		return wp_parse_args( $sanitized_data, $default );
	}

	/**
	 * Validate a request argument based on details registered to the route.
	 *
	 * @param mixed           $value The value.
	 * @param WP_REST_Request $request The Request object.
	 * @param string          $param Parameter name.
	 *
	 * @return true|WP_Error
	 */
	public function validate_hero_slider_items_args( $value, $request, $param ) {
		if ( ! is_array( $value ) ) {
			return new WP_Error(
				'rest_invalid_type',
				/* translators: 1: Parameter, 2: List of types. */
				__( 'slider_items is not of type array.', 'carousel-slider' ),
				array( 'param' => $param )
			);
		}
		$attributes = $request->get_attributes();
		if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) {
			return true;
		}

		foreach ( $value as $index => $item ) {
			$is_valid = $this->validate_hero_slider_item_args( $item, $index );
			if ( is_wp_error( $is_valid ) ) {
				return $is_valid;
			}
		}

		return true;
	}

	/**
	 * Validate hero slider single item arguments.
	 *
	 * @param array $item User submitted data.
	 * @param int   $index Item index.
	 *
	 * @return true|WP_Error
	 */
	public function validate_hero_slider_item_args( array $item, int $index = 0 ) {
		$background_type = $item['background_type'] ?? '';
		$name            = 'slider_items[' . $index . ']';
		if ( 'color' === $background_type ) {
			if ( empty( $item['bg_color'] ) ) {
				return new WP_Error(
					'rest_property_required',
					/* translators: %s will be replaced with name*/
					sprintf( __( 'bg_color is a required property of %s when background_type is set as color', 'carousel-slider' ), $name )
				);
			}
		}
		if ( 'image' === $background_type ) {
			if ( empty( $item['bg_image'] ) ) {
				return new WP_Error(
					'rest_property_required',
					/* translators: %s will be replaced with name*/
					sprintf( __( 'bg_image is a required property of %s when background_type is set as image', 'carousel-slider' ), $name )
				);
			}
			if ( empty( $item['bg_image']['img_id'] ) ) {
				return new WP_Error(
					'rest_property_required',
					/* translators: %s will be replaced with name*/
					sprintf( __( 'img_id is a required property of %s[bg_image]', 'carousel-slider' ), $name )
				);
			}

			$src = wp_get_attachment_image_src( $item['bg_image']['img_id'] );
			if ( ! is_array( $src ) ) {
				return new WP_Error(
					'rest_invalid_value',
					/* translators: %s will be replaced with name*/
					sprintf( __( 'The value of img_id of %s[bg_image] is invalid.', 'carousel-slider' ), $name )
				);
			}
		}

		return true;
	}

	/**
	 * Create item parameters
	 *
	 * @return array[]
	 */
	public function get_create_item_params(): array {
		return [
			'title'            => [
				'description'       => __( 'The carousel slider title', 'carousel-slider' ),
				'type'              => 'string',
				'required'          => true,
				'sanitize_callback' => 'sanitize_text_field',
				'validate_callback' => 'rest_validate_request_arg',
			],
			'general_settings' => [
				'description'       => __( 'Carousel settings.', 'carousel-slider' ),
				'type'              => 'object',
				'properties'        => $this->general_setting_args_properties(),
				'default'           => $this->general_setting_defaults,
				'sanitize_callback' => [ $this, 'sanitize_general_setting' ],
				'validate_callback' => 'rest_validate_request_arg',
			],
			'slider_settings'  => [
				'description'       => __( 'Hero carousel specific settings.', 'carousel-slider' ),
				'type'              => 'object',
				'required'          => true,
				'properties'        => [
					'slide_height'      => [
						'type'     => 'string',
						'required' => true,
					],
					'content_animation' => [
						'type'     => 'string',
						'required' => true,
						'enum'     => array_keys( Helper::animations() ),
					],
					'content_width'     => [ 'type' => 'string' ],
					'slide_padding'     => [
						'type'       => 'object',
						'properties' => [
							'top'    => [ 'type' => 'string' ],
							'right'  => [ 'type' => 'string' ],
							'bottom' => [ 'type' => 'string' ],
							'left'   => [ 'type' => 'string' ],
						],
					],
				],
				'sanitize_callback' => [ $this, 'sanitize_hero_slider_settings' ],
			],
			'slider_items'     => [
				'description'       => __( 'Carousel settings.', 'carousel-slider' ),
				'type'              => 'array',
				'required'          => true,
				'items'             => [
					'type'       => 'object',
					'properties' => $this->hero_carousel_setting_args_properties(),
				],
				'sanitize_callback' => [ $this, 'sanitize_hero_slider_items' ],
				'validate_callback' => [ $this, 'validate_hero_slider_items_args' ],
			],
		];
	}

	/**
	 * Get general setting arguments property
	 *
	 * @return array[]
	 */
	public function hero_carousel_setting_args_properties(): array {
		return [
			'background_type'   => [
				'type'     => 'string',
				'enum'     => [ 'color', 'image' ],
				'required' => true,
			],
			'bg_color'          => [
				'type'              => 'string',
				'sanitize_callback' => [ Sanitize::class, 'color' ],
			],
			'bg_image'          => [
				'type'       => 'object',
				'properties' => [
					'img_id'           => [
						'type'              => 'int',
						'sanitize_callback' => [ Sanitize::class, 'int' ],
					],
					'img_position'     => [
						'type' => 'string',
						'enum' => array_keys( Helper::background_position() ),
					],
					'img_size'         => [
						'type' => 'string',
						'enum' => array_keys( Helper::background_size() ),
					],
					'overlay_color'    => [
						'type'              => 'string',
						'sanitize_callback' => [ Sanitize::class, 'color' ],
					],
					'ken_burns_effect' => [
						'type' => 'string',
						'enum' => array_keys( Helper::ken_burns_effects() ),
					],
				],
			],
			'content_alignment' => [
				'required' => true,
				'type'     => 'string',
				'enum'     => array_keys( Helper::text_alignment() ),
			],
			'content_animation' => [
				'type' => 'string',
				'enum' => array_keys( Helper::animations() ),
			],
			'heading'           => [
				'required'   => true,
				'type'       => 'object',
				'properties' => $this->get_section_text_properties(),
			],
			'description'       => [
				'type'       => 'object',
				'properties' => $this->get_section_text_properties(),
			],
			'link_type'         => [
				'required' => true,
				'type'     => 'string',
				'enum'     => array_keys( Helper::link_type() ),
			],
			'full_link'         => [
				'type'       => 'object',
				'properties' => [
					'url'    => [ 'type' => 'string' ],
					'target' => [
						'type' => 'string',
						'enum' => array_keys( Helper::link_target() ),
					],
				],
			],
			'button_link'       => [
				'type'       => 'object',
				'properties' => [
					'primary'   => [
						'type'       => 'object',
						'properties' => $this->get_button_properties(),
					],
					'secondary' => [
						'type'       => 'object',
						'properties' => $this->get_button_properties(),
					],
				],
			],
		];
	}

	/**
	 * Get section text properties
	 *
	 * @return array[]
	 */
	protected function get_section_text_properties(): array {
		return [
			'text'          => [ 'type' => 'string' ],
			'font_size'     => [ 'type' => 'string' ],
			'margin_bottom' => [ 'type' => 'string' ],
			'color'         => [ 'type' => 'string' ],
		];
	}

	/**
	 * Get button properties
	 *
	 * @return array
	 */
	protected function get_button_properties(): array {
		return [
			'text'          => [ 'type' => 'string' ],
			'url'           => [ 'type' => 'string' ],
			'target'        => [ 'type' => 'string' ],
			'type'          => [
				'type' => 'string',
				'enum' => array_keys( Helper::button_type() ),
			],
			'size'          => [
				'type' => 'string',
				'enum' => array_keys( Helper::button_size() ),
			],
			'border_width'  => [ 'type' => 'string' ],
			'border_radius' => [ 'type' => 'string' ],
			'bg_color'      => [ 'type' => 'string' ],
			'color'         => [ 'type' => 'string' ],
		];
	}
}
modules/HeroCarousel/Template.php000064400000011007151727276370013113 0ustar00<?php

namespace CarouselSlider\Modules\HeroCarousel;

use CarouselSlider\Abstracts\AbstractTemplate;

defined( 'ABSPATH' ) || exit;

/**
 * Template class
 *
 * @package Modules/HeroCarousel
 */
class Template extends AbstractTemplate {

	/**
	 * Get default hero carousel settings
	 *
	 * @return array
	 */
	public static function get_default_settings(): array {
		return wp_parse_args(
			[
				'_slide_type'                  => 'hero-banner-slider',
				'_type_of_slider'              => 'slider',
				// Responsive Settings.
				'_items_portrait_mobile'       => '1',
				'_items_small_portrait_tablet' => '1',
				'_items_portrait_tablet'       => '1',
				'_items_small_desktop'         => '1',
				'_items_desktop'               => '1',
				'_items'                       => '1',
			],
			parent::get_default_settings()
		);
	}

	/**
	 * Get default hero carousel content settings
	 *
	 * @return array
	 */
	protected static function get_content_settings(): array {
		return [
			'slide_height'      => '300px',
			'content_width'     => '80%',
			'content_animation' => 'zoomIn',
			'slide_padding'     => [
				'top'    => '3rem',
				'right'  => '3rem',
				'bottom' => '3rem',
				'left'   => '3rem',
			],
		];
	}

	/**
	 * Hero Slider Content Settings
	 *
	 * @param  int   $index  The index number.
	 * @param  int   $image_id  Image id.
	 * @param  array $args  Additional arguments.
	 *
	 * @return array
	 */
	protected static function get_content( int $index = 0, int $image_id = 0, array $args = array() ): array {
		++$index;
		$settings = [
			// Slide Content.
			'slide_heading'            => 'Slide Heading ' . $index,
			'slide_description'        => 'Slide Description form slide ' . $index,
			// Slide Background.
			'img_id'                   => $image_id,
			'img_bg_position'          => 'center center',
			'img_bg_size'              => 'cover',
			'ken_burns_effect'         => ( $index % 2 ) ? 'zoom-in' : 'zoom-out',
			'bg_color'                 => 'rgba(255,255,255,0.5)',
			'bg_overlay'               => 'rgba(0,0,0,0.5)',
			// Slide Style.
			'content_alignment'        => 'left',
			'heading_font_size'        => 40,
			'heading_gutter'           => '30px',
			'heading_color'            => '#ffffff',
			'description_font_size'    => '20',
			'description_gutter'       => '30px',
			'description_color'        => '#ffffff',
			// Slide Link.
			'link_type'                => 'button',
			'slide_link'               => '',
			'link_target'              => '_self',
			// Slide Button #1.
			'button_one_text'          => 'Button ' . $index,
			'button_one_url'           => 'https://sayfulislam.com',
			'button_one_target'        => '_self',
			'button_one_type'          => 'stroke',
			'button_one_size'          => 'medium',
			'button_one_border_width'  => '2px',
			'button_one_border_radius' => '3px',
			'button_one_bg_color'      => '#00d1b2',
			'button_one_color'         => '#ffffff',
			// Slide Button #2.
			'button_two_text'          => '',
			'button_two_url'           => '',
			'button_two_target'        => '_self',
			'button_two_type'          => 'stroke',
			'button_two_size'          => 'medium',
			'button_two_border_width'  => '2px',
			'button_two_border_radius' => '3px',
			'button_two_bg_color'      => '#00d1b2',
			'button_two_color'         => '#ffffff',
		];

		return wp_parse_args( $args, $settings );
	}

	/**
	 * Create a hero carousel with random images
	 *
	 * @param  string $slider_title  The slider title.
	 * @param  array  $args  Additional arguments.
	 *
	 * @return int The WP_Post ID on success. Value 0 on failure.
	 */
	public static function create( string $slider_title = '', array $args = [] ): int {
		if ( empty( $slider_title ) ) {
			$slider_title = 'Hero Carousel';
		}

		$post_id = self::create_slider( $slider_title );

		if ( ! $post_id ) {
			return 0;
		}

		// Update General Settings.
		$data = wp_parse_args( $args, self::get_default_settings() );
		foreach ( $data as $meta_key => $meta_value ) {
			update_post_meta( $post_id, $meta_key, $meta_value );
		}

		// Update Content settings.
		update_post_meta( $post_id, '_content_slider_settings', self::get_content_settings() );

		// Update Content.
		$images     = self::get_images();
		$images_ids = wp_list_pluck( $images, 'id' );
		$images_ids = array_splice( $images_ids, 0, 5 );

		$content = array();
		foreach ( $images_ids as $index => $images_id ) {
			$content[] = self::get_content( $index, $images_id );
		}

		$content = array_values( $content );

		update_post_meta( $post_id, '_content_slider', $content );

		return $post_id;
	}
}
modules/HeroCarousel/Ajax.php000064400000007704151727276370012234 0ustar00<?php

namespace CarouselSlider\Modules\HeroCarousel;

defined( 'ABSPATH' ) || exit;

/**
 * Ajax class
 *
 * @package Modules/HeroCarousel
 */
class Ajax {

	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance = null;

	/**
	 * Ensures only one instance of this class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
			add_action( 'wp_ajax_add_content_slide', [ self::$instance, 'add_slide_template' ] );
		}

		return self::$instance;
	}

	/**
	 * Add slider template
	 *
	 * @return void
	 */
	public function add_slide_template() {
		if ( isset( $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], 'carousel_slider_ajax_nonce' ) ) {
			if ( ! isset( $_POST['post_id'] ) ) {
				wp_send_json( __( 'Required attribute is not set properly.', 'carousel-slider' ), 422 );
			}

			$post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0;

			$post_type = get_post_type_object( CAROUSEL_SLIDER_POST_TYPE );
			if ( ! current_user_can( $post_type->cap->edit_post, $post_id ) ) {
				wp_send_json( __( 'You are not authorized to perform this action.', 'carousel-slider' ), 401 );
			}

			$task = isset( $_POST['task'] ) ? sanitize_text_field( $_POST['task'] ) : 'add-slide';

			$slider_content = get_post_meta( $post_id, '_content_slider', true );
			$slider_content = is_array( $slider_content ) ? array_values( $slider_content ) : [];

			if ( 'add-slide' === $task ) {
				$new_content = $this->add_new_item( $post_id, $slider_content );
				wp_send_json( $new_content, 201 );
			}

			$last_index    = count( $slider_content ) - 1;
			$current_index = $this->get_current_index( $last_index );
			if ( - 1 === $current_index ) {
				wp_send_json_error();
			}

			$new_index = [
				'move-slide-top'    => 0,
				'move-slide-up'     => $current_index - 1,
				'move-slide-down'   => $current_index + 1,
				'move-slide-bottom' => $last_index,
			];

			if ( 'delete-slide' === $task ) {
				array_splice( $slider_content, $current_index, 1 );
			}

			if ( array_key_exists( $task, $new_index ) ) {
				$slider_content = $this->move_array_element( $slider_content, $current_index, $new_index[ $task ] );
			}

			$slider_content = array_values( $slider_content );

			update_post_meta( $post_id, '_content_slider', $slider_content );
			wp_send_json( $slider_content );
		}

		wp_send_json( __( 'You are not authorized to perform this action.', 'carousel-slider' ), 401 );
	}

	/**
	 * Move array element position
	 *
	 * @param  array $original_array  Array content.
	 * @param  int   $current_index  The current index.
	 * @param  int   $new_index  The new index.
	 *
	 * @return array
	 */
	private function move_array_element( array $original_array, int $current_index, int $new_index ): array {
		$output = array_splice( $original_array, $current_index, 1 );
		array_splice( $original_array, $new_index, 0, $output );

		return $original_array;
	}

	/**
	 * Add new item
	 *
	 * @param  int   $post_id  The post id.
	 * @param  array $slider_content  The slider content.
	 *
	 * @return array
	 */
	protected function add_new_item( int $post_id, array $slider_content ): array {
		$data             = [
			'slide_heading'     => 'Slide Heading',
			'slide_description' => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas, magnam!',
		];
		$slider_content[] = wp_parse_args( $data, Item::get_default() );
		update_post_meta( $post_id, '_content_slider', $slider_content );

		return $slider_content;
	}

	/**
	 * Get current index
	 *
	 * @param  int $last_index  Last slider index.
	 *
	 * @return int
	 */
	protected function get_current_index( int $last_index ): int {
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		$index = isset( $_POST['slide_pos'] ) && is_numeric( $_POST['slide_pos'] ) ? absint( $_POST['slide_pos'] ) : - 1;
		if ( in_array( $index, range( 0, $last_index ), true ) ) {
			return $index;
		}

		return - 1;
	}
}
modules/ProductCarousel/Module.php000064400000011656151727276370013322 0ustar00<?php

namespace CarouselSlider\Modules\ProductCarousel;

use Automattic\WooCommerce\Utilities\FeaturesUtil;
use WC_Product;

defined( 'ABSPATH' ) || exit;

/**
 * Module class
 *
 * @package Modules/ProductCarousel
 */
class Module {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_filter( 'carousel_slider/register_view', [ self::$instance, 'view' ] );

			add_action( 'carousel_slider_after_shop_loop_item', [ self::$instance, 'quick_view_button' ], 10, 2 );
			add_action( 'carousel_slider_after_shop_loop_item', [ self::$instance, 'wish_list_button' ], 12, 2 );

			add_action( 'wp_ajax_carousel_slider_quick_view', [ self::$instance, 'quick_view' ] );
			add_action( 'wp_ajax_nopriv_carousel_slider_quick_view', [ self::$instance, 'quick_view' ] );

			Admin::init();
		}

		return self::$instance;
	}

	/**
	 * Register view
	 *
	 * @param  array $views  Registered views.
	 *
	 * @return array
	 */
	public function view( array $views ): array {
		$views['product-carousel'] = new View();

		return $views;
	}

	/**
	 * Show quick view button on product slider
	 *
	 * @param  WC_Product $product  The WC_Product object.
	 * @param  int        $slider_id  The slider id.
	 */
	public static function quick_view_button( $product, $slider_id ) {
		$_show_btn = get_post_meta( $slider_id, '_product_quick_view', true );

		if ( 'on' === $_show_btn ) {
			wp_enqueue_script( 'magnific-popup' );

			$quick_view_html  = '<div style="clear: both;"></div>';
			$quick_view_html .= sprintf(
				'<a class="magnific-popup button quick_view" href="%1$s" data-product-id="%2$s">%3$s</a>',
				Helper::get_product_quick_view_url( $product->get_id() ),
				$product->get_id(),
				__( 'Quick View', 'carousel-slider' )
			);
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo apply_filters( 'carousel_slider_product_quick_view', $quick_view_html, $product );
		}
	}

	/**
	 * Show YITH Wishlist button on the product slider
	 *
	 * @param  WC_Product $product  The WC_Product object.
	 * @param  int        $slider_id  The slider id.
	 */
	public static function wish_list_button( $product, $slider_id ) {
		$_product_wish_list = get_post_meta( $slider_id, '_product_wishlist', true );
		if ( class_exists( 'YITH_WCWL' ) && 'on' === $_product_wish_list ) {
			echo do_shortcode( '[yith_wcwl_add_to_wishlist product_id="' . $product->get_id() . '"]' );
		}
	}

	/**
	 * Display quick view popup content
	 */
	public static function quick_view() {
		if ( ! isset( $_GET['_wpnonce'], $_GET['product_id'] ) ) {
			wp_die();
		}

		if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'carousel_slider_quick_view' ) ) {
			wp_die();
		}

		global $product;
		$product = wc_get_product( intval( $_GET['product_id'] ) );
		$html    = static::get_quick_view_html( $product );
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo apply_filters( 'carousel_slider/product_quick_view_html', $html, $product );
		wp_die();
	}

	/**
	 * Get quick view HTML
	 *
	 * @param  WC_Product $product  The WC_Product object.
	 *
	 * @return string
	 */
	public static function get_quick_view_html( WC_Product $product ): string {
		ob_start();
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$slider_id = isset( $_GET['slide_id'] ) ? intval( $_GET['slide_id'] ) : 0;
		?>
		<div id="pmid-<?php echo esc_attr( $slider_id ); ?>" class="product carousel-slider__product-modal">

			<div class="images">
				<?php echo get_the_post_thumbnail( $product->get_id(), 'medium_large' ); ?>
				<?php if ( $product->is_on_sale() ) : ?>
					<?php
					// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
					echo apply_filters(
						'woocommerce_sale_flash',
						'<span class="onsale">' . __( 'Sale!', 'carousel-slider' ) . '</span>',
						$product
					);
					?>
				<?php endif; ?>
			</div>

			<div class="summary entry-summary">

				<h1 class="product_title entry-title">
					<?php echo esc_html( $product->get_title() ); ?>
				</h1>

				<div class="woocommerce-product-rating">
					<?php
					// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
					echo wc_get_rating_html( $product->get_average_rating() );
					?>
				</div>

				<div class="price">
					<?php
					// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
					echo $product->get_price_html();
					?>
				</div>

				<div class="description">
					<div style="clear: both;"></div>
					<?php
					// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
					echo apply_filters( 'woocommerce_short_description', $product->get_description() );
					?>
				</div>

				<div>
					<div style="clear: both;"></div>
					<?php woocommerce_template_loop_add_to_cart(); ?>
				</div>

			</div>
		</div>
		<?php
		return ob_get_clean();
	}
}
modules/ProductCarousel/Helper.php000064400000014436151727276370013313 0ustar00<?php

namespace CarouselSlider\Modules\ProductCarousel;

use WC_Product;
use WP_Term;

defined( 'ABSPATH' ) || exit;

/**
 * Helper class
 *
 * @package Modules/ProductCarousel
 */
class Helper {

	/**
	 * List all (or limited) product categories.
	 *
	 * @param array $args Optional arguments.
	 *
	 * @return array|WP_Term[]
	 */
	public static function product_categories( array $args = [] ): array {
		$args = wp_parse_args(
			$args,
			[
				'hide_empty' => true,
				'orderby'    => 'name',
				'order'      => 'ASC',
			]
		);

		$args['taxonomy'] = 'product_cat';

		return get_terms( $args );
	}

	/**
	 * List all (or limited) product tags.
	 *
	 * @param array $args Optional arguments.
	 *
	 * @return array|WP_Term[]
	 */
	public static function product_tags( array $args = [] ): array {
		$args = wp_parse_args(
			$args,
			[
				'hide_empty' => true,
				'orderby'    => 'name',
				'order'      => 'ASC',
			]
		);

		$args['taxonomy'] = 'product_tag';

		return get_terms( $args );
	}

	/**
	 * Format term slug
	 *
	 * @param array  $tags List of term slug or term id.
	 * @param string $taxonomy Taxonomy slug.
	 *
	 * @return array
	 */
	public static function format_term_slug( array $tags, string $taxonomy ): array {
		$ids = [];
		foreach ( $tags as $index => $tag ) {
			if ( is_numeric( $tag ) ) {
				$ids[] = intval( $tag );
				unset( $tags[ $index ] );
			}
		}
		if ( count( $ids ) ) {
			$terms = get_terms(
				[
					'taxonomy' => $taxonomy,
					'include'  => $ids,
				]
			);
			$slugs = is_array( $terms ) ? wp_list_pluck( $terms, 'slug' ) : [];
			$tags  = array_merge( $slugs, array_values( $tags ) );
		}

		return $tags;
	}

	/**
	 * Get product quick view url
	 *
	 * @param int $product_id The product id.
	 *
	 * @return string
	 */
	public static function get_product_quick_view_url( int $product_id ): string {
		$args = array(
			'action'     => 'carousel_slider_quick_view',
			'ajax'       => 'true',
			'product_id' => $product_id,
		);
		$url  = add_query_arg( $args, admin_url( 'admin-ajax.php' ) );

		return wp_nonce_url( $url, 'carousel_slider_quick_view' );
	}

	/**
	 * Parse arguments
	 *
	 * @param array $args Arguments.
	 *
	 * @return array
	 */
	private static function parse_args( array $args = [] ): array {
		return wp_parse_args(
			$args,
			[
				'limit'      => 12,
				'order'      => 'DESC',
				'orderby'    => 'date',
				'visibility' => 'catalog',
				'paginate'   => false,
				'page'       => 1,
				'return'     => 'objects',
			]
		);
	}

	/**
	 * Get products
	 *
	 * @param int   $slider_id The slider id.
	 * @param array $args Arguments.
	 *
	 * @return array|WC_Product[]
	 */
	public static function get_products( int $slider_id, array $args = [] ): array {
		$setting = new Setting( $slider_id );

		$args       = static::parse_args( array_merge( $args, [ 'limit' => $setting->get_prop( 'per_page' ) ] ) );
		$query_type = $setting->get_query_type();

		self::add_specific_products_query_args( $setting, $args );
		self::add_product_categories_query_args( $setting, $args );
		self::add_product_tags_query_args( $setting, $args );
		self::add_featured_product_query_args( $query_type, $args );
		self::add_best_selling_query_args( $query_type, $args );
		self::add_recent_product_query_args( $query_type, $args );
		self::add_on_sale_query_args( $query_type, $args );
		self::add_top_rated_query_args( $query_type, $args );

		return wc_get_products( $args );
	}

	/**
	 * Add top-rated query args.
	 *
	 * @param string $query_type Query type.
	 * @param array  $args Query arguments.
	 *
	 * @return void
	 */
	protected static function add_top_rated_query_args( string $query_type, array &$args ) {
		if ( 'top_rated' === $query_type ) {
			$args['order']    = 'DESC';
			$args['orderby']  = 'meta_value_num';
			$args['meta_key'] = '_wc_average_rating';
		}
	}

	/**
	 * Add on sale query args.
	 *
	 * @param string $query_type Query type.
	 * @param array  $args Query arguments.
	 *
	 * @return void
	 */
	protected static function add_on_sale_query_args( string $query_type, array &$args ) {
		if ( 'sale' === $query_type ) {
			$args['include'] = array_merge( [ 0 ], wc_get_product_ids_on_sale() );
		}
	}

	/**
	 * Add recent product query args.
	 *
	 * @param string $query_type Query type.
	 * @param array  $args Query arguments.
	 *
	 * @return void
	 */
	protected static function add_recent_product_query_args( string $query_type, array &$args ) {
		if ( 'recent' === $query_type ) {
			$args['order']   = 'DESC';
			$args['orderby'] = 'date';
		}
	}

	/**
	 * Add bestselling product query args.
	 *
	 * @param string $query_type Query type.
	 * @param array  $args Query arguments.
	 *
	 * @return void
	 */
	protected static function add_best_selling_query_args( string $query_type, array &$args ) {
		if ( 'best_selling' === $query_type ) {
			$args['order']    = 'DESC';
			$args['orderby']  = 'meta_value_num';
			$args['meta_key'] = 'total_sales';
		}
	}

	/**
	 * Add featured product query args.
	 *
	 * @param string $query_type Query type.
	 * @param array  $args Query arguments.
	 *
	 * @return void
	 */
	protected static function add_featured_product_query_args( string $query_type, array &$args ) {
		if ( 'featured' === $query_type ) {
			$args['featured'] = true;
		}
	}

	/**
	 * Add product tags query args.
	 *
	 * @param Setting $setting The Setting object.
	 * @param array   $args Query arguments.
	 *
	 * @return void
	 */
	protected static function add_product_tags_query_args( Setting $setting, array &$args ) {
		if ( 'product_tags' === $setting->get_query_type() ) {
			$args['tag'] = $setting->get_tags_slug();
		}
	}

	/**
	 * Add product categories query args.
	 *
	 * @param Setting $setting The Setting object.
	 * @param array   $args Query arguments.
	 *
	 * @return void
	 */
	protected static function add_product_categories_query_args( Setting $setting, array &$args ) {
		if ( 'product_categories' === $setting->get_query_type() ) {
			$args['category'] = $setting->get_categories_slug();
		}
	}

	/**
	 * Add specific product query args.
	 *
	 * @param Setting $setting The Setting object.
	 * @param array   $args Query arguments.
	 *
	 * @return void
	 */
	protected static function add_specific_products_query_args( Setting $setting, array &$args ) {
		if ( 'specific_products' === $setting->get_query_type() ) {
			$args['include'] = $setting->get_prop( 'product_in' );
		}
	}
}
modules/ProductCarousel/Admin.php000064400000023421151727276400013110 0ustar00<?php

namespace CarouselSlider\Modules\ProductCarousel;

use CarouselSlider\Helper;
use CarouselSlider\Supports\MetaBoxForm;
use CarouselSlider\Admin\Setting;
use CarouselSlider\Supports\Sanitize;

defined( 'ABSPATH' ) || exit;

/**
 * Admin class
 *
 * @package Modules/ProductCarousel
 */
class Admin {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'carousel_slider/meta_box_content', [ self::$instance, 'meta_box_content' ], 10, 2 );
			add_filter( 'carousel_slider/admin/metabox_color_settings', [ self::$instance, 'color_settings' ] );

			add_action( 'carousel_slider/save_slider', [ self::$instance, 'save_slider' ], 10, 2 );
		}

		return self::$instance;
	}

	/**
	 * Save post carousel content
	 *
	 * @param int   $post_id The post id.
	 * @param array $data User submitted data.
	 *
	 * @return void
	 */
	public function save_slider( int $post_id, array $data ) {
		$raw_data = $data['product_carousel'] ?? [];
		foreach ( $raw_data as $meta_key => $meta_value ) {
			if ( is_array( $meta_value ) ) {
				$meta_value = implode( ',', $meta_value );
			}

			update_post_meta( $post_id, $meta_key, sanitize_text_field( $meta_value ) );
		}
	}

	/**
	 * Show meta box content for product carousel
	 *
	 * @param int    $slider_id The slider id.
	 * @param string $slider_type The slider type.
	 */
	public function meta_box_content( int $slider_id, string $slider_type ) {
		if ( 'product-carousel' !== $slider_type ) {
			return;
		}
		$form     = new MetaBoxForm();
		$template = Setting::get_option( 'woocommerce_shop_loop_item_template', 'v1-compatibility' );

		$form->select(
			array(
				'group'   => 'product_carousel',
				'type'    => 'select',
				'id'      => '_product_query_type',
				'name'    => esc_html__( 'Query Type', 'carousel-slider' ),
				'std'     => 'query_product',
				'options' => array(
					'query_product'      => esc_html__( 'Query Products', 'carousel-slider' ),
					'product_categories' => esc_html__( 'Product Categories', 'carousel-slider' ),
					'product_tags'       => esc_html__( 'Product Tags', 'carousel-slider' ),
					'specific_products'  => esc_html__( 'Specific Products', 'carousel-slider' ),
				),
			)
		);
		$form->select(
			array(
				'group'   => 'product_carousel',
				'type'    => 'select',
				'id'      => '_product_query',
				'name'    => esc_html__( 'Choose Query', 'carousel-slider' ),
				'std'     => 'featured',
				'options' => array(
					'featured'                => esc_html__( 'Featured Products', 'carousel-slider' ),
					'recent'                  => esc_html__( 'Recent Products', 'carousel-slider' ),
					'sale'                    => esc_html__( 'Sale Products', 'carousel-slider' ),
					'best_selling'            => esc_html__( 'Best-Selling Products', 'carousel-slider' ),
					'top_rated'               => esc_html__( 'Top Rated Products', 'carousel-slider' ),
					'product_categories_list' => esc_html__( 'Product Categories List', 'carousel-slider' ),
				),
			)
		);
		$form->post_terms(
			array(
				'group'    => 'product_carousel',
				'type'     => 'post_terms',
				'id'       => '_product_categories',
				'taxonomy' => 'product_cat',
				'multiple' => true,
				'name'     => esc_html__( 'Product Categories', 'carousel-slider' ),
				'desc'     => esc_html__( 'Show products associated with selected categories.', 'carousel-slider' ),
			)
		);
		$form->post_terms(
			array(
				'group'    => 'product_carousel',
				'type'     => 'post_terms',
				'id'       => '_product_tags',
				'taxonomy' => 'product_tag',
				'multiple' => true,
				'name'     => esc_html__( 'Product Tags', 'carousel-slider' ),
				'desc'     => esc_html__( 'Show products associated with selected tags.', 'carousel-slider' ),
			)
		);
		$form->posts_list(
			array(
				'group'     => 'product_carousel',
				'type'      => 'posts_list',
				'id'        => '_product_in',
				'post_type' => 'product',
				'multiple'  => true,
				'name'      => esc_html__( 'Specific products', 'carousel-slider' ),
				'desc'      => esc_html__( 'Select products that you want to show as slider. Select at least 5 products', 'carousel-slider' ),
			)
		);
		$form->number(
			array(
				'group' => 'product_carousel',
				'type'  => 'number',
				'id'    => '_products_per_page',
				'name'  => esc_html__( 'Product per page', 'carousel-slider' ),
				'std'   => 12,
				'desc'  => esc_html__( 'How many products you want to show on carousel slide.', 'carousel-slider' ),
			)
		);
		if ( 'v1-compatibility' === $template ) {
			$settings = self::get_settings_for_toggle_sections();

			foreach ( $settings as $setting ) {
				Helper::print_unescaped_internal_string( MetaBoxForm::field( $setting ) );
			}
		}
	}

	/**
	 * Color settings
	 *
	 * @param string $html The content html.
	 *
	 * @return string
	 */
	public function color_settings( string $html ): string {
		global $post;
		$slide_type = get_post_meta( $post->ID, '_slide_type', true );
		$slide_type = array_key_exists( $slide_type, Helper::get_slide_types() ) ? $slide_type : 'image-carousel';
		if ( 'product-carousel' !== $slide_type ) {
			return $html;
		}
		$form = new MetaBoxForm();
		ob_start();
		$form->color(
			array(
				'group' => 'product_carousel',
				'id'    => '_product_title_color',
				'type'  => 'color',
				'name'  => esc_html__( 'Product Title Color', 'carousel-slider' ),
				'desc'  => esc_html__( 'Pick a color for product title. This color will also apply to sale tag and price.', 'carousel-slider' ),
				'std'   => Helper::get_default_setting( 'product_title_color' ),
			)
		);
		$form->color(
			array(
				'group' => 'product_carousel',
				'id'    => '_product_button_bg_color',
				'type'  => 'color',
				'name'  => esc_html__( 'Product Button Background Color', 'carousel-slider' ),
				'desc'  => esc_html__( 'Pick a color for button background color. This color will also apply to product rating.', 'carousel-slider' ),
				'std'   => Helper::get_default_setting( 'product_button_bg_color' ),
			)
		);
		$form->color(
			array(
				'group' => 'product_carousel',
				'id'    => '_product_button_text_color',
				'type'  => 'color',
				'name'  => esc_html__( 'Product Button Text Color', 'carousel-slider' ),
				'desc'  => esc_html__( 'Pick a color for button text color.', 'carousel-slider' ),
				'std'   => Helper::get_default_setting( 'product_button_text_color' ),
			)
		);
		$content = ob_get_clean();

		return $html . $content;
	}

	/**
	 * Get settings for toggle sections
	 *
	 * @return array[]
	 */
	public static function get_settings_for_toggle_sections(): array {
		return [
			[
				'group'             => 'product_carousel',
				'type'              => 'switch',
				'id'                => '_product_title',
				'label'             => esc_html__( 'Show Title.', 'carousel-slider' ),
				'description'       => esc_html__( 'Check to show product title.', 'carousel-slider' ),
				'default'           => 'on',
				'sanitize_callback' => [ Sanitize::class, 'checked' ],
			],
			[
				'group'             => 'product_carousel',
				'type'              => 'switch',
				'id'                => '_product_rating',
				'label'             => esc_html__( 'Show Rating.', 'carousel-slider' ),
				'description'       => esc_html__( 'Check to show product rating.', 'carousel-slider' ),
				'default'           => 'on',
				'sanitize_callback' => [ Sanitize::class, 'checked' ],
			],
			[
				'group'             => 'product_carousel',
				'type'              => 'switch',
				'id'                => '_product_price',
				'label'             => esc_html__( 'Show Price.', 'carousel-slider' ),
				'description'       => esc_html__( 'Check to show product price.', 'carousel-slider' ),
				'default'           => 'on',
				'sanitize_callback' => [ Sanitize::class, 'checked' ],
			],

			[
				'group'             => 'product_carousel',
				'type'              => 'switch',
				'id'                => '_product_cart_button',
				'label'             => esc_html__( 'Show Cart Button.', 'carousel-slider' ),
				'description'       => esc_html__( 'Check to show product add to cart button.', 'carousel-slider' ),
				'default'           => 'on',
				'sanitize_callback' => [ Sanitize::class, 'checked' ],
			],
			[
				'group'             => 'product_carousel',
				'type'              => 'switch',
				'id'                => '_product_onsale',
				'label'             => esc_html__( 'Show Sale Tag', 'carousel-slider' ),
				'description'       => esc_html__( 'Check to show product sale tag for onsale products.', 'carousel-slider' ),
				'default'           => 'on',
				'sanitize_callback' => [ Sanitize::class, 'checked' ],
			],
			[
				'group'             => 'product_carousel',
				'type'              => 'switch',
				'id'                => '_product_wishlist',
				'label'             => esc_html__( 'Show Wishlist Button', 'carousel-slider' ),
				/* translators: 1: YITH WooCommerce Wishlist plugin url*/
				'description'       => sprintf( esc_html__( 'Check to show wishlist button. This feature needs %s plugin to be installed.', 'carousel-slider' ), sprintf( '<a href="https://wordpress.org/plugins/yith-woocommerce-wishlist/" target="_blank" >%s</a>', __( 'YITH WooCommerce Wishlist', 'carousel-slider' ) ) ),
				'default'           => 'off',
				'sanitize_callback' => [ Sanitize::class, 'checked' ],
			],
			[
				'group'             => 'product_carousel',
				'type'              => 'switch',
				'id'                => '_product_quick_view',
				'label'             => esc_html__( 'Show Quick View', 'carousel-slider' ),
				'description'       => esc_html__( 'Check to show quick view button.', 'carousel-slider' ),
				'default'           => 'on',
				'sanitize_callback' => [ Sanitize::class, 'checked' ],
			],
		];
	}
}
modules/ProductCarousel/View.php000064400000014460151727276400012775 0ustar00<?php

namespace CarouselSlider\Modules\ProductCarousel;

use CarouselSlider\Abstracts\AbstractView;
use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\Admin\Setting as GlobalSetting;
use CarouselSlider\Helper;
use CarouselSlider\Supports\Validate;
use CarouselSlider\Modules\ProductCarousel\Helper as ProductCarouselHelper;
use CarouselSlider\TemplateParserBase;
use WC_Product;

defined( 'ABSPATH' ) || exit;

/**
 * View class
 *
 * @package Modules/ProductCarousel
 */
class View extends AbstractView {

	/**
	 * Get slider setting
	 *
	 * @return SliderSetting
	 */
	public function get_slider_setting(): SliderSetting {
		if ( ! $this->slider_setting instanceof Setting ) {
			$this->slider_setting = new Setting( $this->get_slider_id() );
		}

		return $this->slider_setting;
	}

	/**
	 * Render html view
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$query_type    = get_post_meta( $this->slider_id, '_product_query_type', true );
		$query_type    = empty( $query_type ) ? 'query_product' : $query_type;
		$query_type    = ( 'query_porduct' === $query_type ) ? 'query_product' : $query_type; // Fix type mistake.
		$product_query = get_post_meta( $this->slider_id, '_product_query', true );

		if ( 'query_product' === $query_type && 'product_categories_list' === $product_query ) {
			return $this->get_category_view();
		}

		return $this->get_view();
	}

	/**
	 * Get slider settings
	 *
	 * @param int $slider_id The slider id.
	 *
	 * @return array
	 */
	public static function get_settings( int $slider_id ): array {
		$image_size = get_post_meta( $slider_id, '_image_size', true );
		$image_size = array_key_exists( $image_size, Helper::get_available_image_sizes() ) ? $image_size : 'thumbnail';

		return [
			'slider_id'        => $slider_id,
			'image_size'       => $image_size,
			'lazy_load_image'  => Validate::checked( get_post_meta( $slider_id, '_lazy_load_image', true ) ),
			'show_title'       => Validate::checked( get_post_meta( $slider_id, '_product_title', true ) ),
			'show_rating'      => Validate::checked( get_post_meta( $slider_id, '_product_rating', true ) ),
			'show_price'       => Validate::checked( get_post_meta( $slider_id, '_product_price', true ) ),
			'show_cart_button' => Validate::checked( get_post_meta( $slider_id, '_product_cart_button', true ) ),
			'show_onsale'      => Validate::checked( get_post_meta( $slider_id, '_product_onsale', true ) ),
			'show_wishlist'    => Validate::checked( get_post_meta( $slider_id, '_product_wishlist', true ) ),
			'show_quick_view'  => Validate::checked( get_post_meta( $slider_id, '_product_quick_view', true ) ),
		];
	}

	/**
	 * Get CSS variable
	 *
	 * @return array
	 */
	public function get_css_variable(): array {
		$css_vars                            = parent::get_css_variable();
		$css_vars['--cs-product-primary']    = get_post_meta( $this->get_slider_id(), '_product_button_bg_color', true );
		$css_vars['--cs-product-on-primary'] = get_post_meta( $this->get_slider_id(), '_product_button_text_color', true );
		$css_vars['--cs-product-text']       = get_post_meta( $this->get_slider_id(), '_product_title_color', true );

		return $css_vars;
	}

	/**
	 * Get view
	 *
	 * @return string
	 */
	public function get_view(): string {
		$products = ProductCarouselHelper::get_products( $this->get_slider_id() );
		$settings = $this->get_slider_setting();

		$template_name     = GlobalSetting::get_option( 'woocommerce_shop_loop_item_template' );
		$template_filename = 'v1-compatibility' === $template_name ? 'loop/product-carousel.php' : 'loop/product-carousel-2.php';
		$template          = new TemplateParserBase( $settings );
		$template->set_template( $template_filename );

		global $post;
		global $product;

		$html = $this->start_wrapper_html();
		foreach ( $products as $product ) {
			$_post = get_post( $product->get_id() );
			setup_postdata( $_post );

			if ( ! $product->is_visible() ) {
				continue;
			}

			if ( ! $product->has_enough_stock( 1 ) ) {
				continue;
			}

			$template->set_object( $product );
			$template->set_extra_vars( 'post', $_post );
			$template->set_extra_vars( 'product', $product );

			$html .= $this->start_item_wrapper_html();
			$html .= apply_filters( 'carousel_slider/loop/product-carousel', $template->render(), $product, $settings );
			$html .= $this->end_item_wrapper_html();
		}
		wp_reset_postdata();

		$html .= $this->end_wrapper_html();

		return apply_filters( 'carousel_slider_product_carousel', $html );
	}

	/**
	 * Get item
	 *
	 * @param WC_Product    $product The WC_Product object.
	 * @param SliderSetting $settings Settings array.
	 *
	 * @return string
	 */
	public static function get_item( WC_Product $product, Setting $settings ): string {
		$template = new TemplateParserBase( $settings );
		$template->set_template( 'loop/product-carousel.php' );
		$template->set_object( $product );
		$template->set_extra_vars( 'product', $product );

		return apply_filters( 'carousel_slider/loop/product-carousel', $template->render(), $product, $settings );
	}

	/**
	 * Get product slider item
	 *
	 * @param WC_Product    $product The WC_Product object.
	 * @param SliderSetting $settings Settings array.
	 *
	 * @return string
	 */
	public static function get_slider_item( WC_Product $product, SliderSetting $settings ): string {

		$template = new TemplateParserBase( $settings );
		$template->set_template( 'loop/product-carousel-2.php' );
		$template->set_object( $product );
		$template->set_extra_vars( 'product', $product );

		return apply_filters( 'carousel_slider/loop/product-carousel', $template->render(), $product, $settings );
	}

	/**
	 * Get view
	 *
	 * @return string
	 */
	public function get_category_view(): string {
		$slider_id  = $this->get_slider_id();
		$categories = ProductCarouselHelper::product_categories();

		$template = new TemplateParserBase( $this->get_slider_setting() );
		$template->set_template( 'loop/product-categories-list.php' );

		$html = $this->start_wrapper_html();
		foreach ( $categories as $category ) {
			$template->set_object( $category );
			$html .= $this->start_item_wrapper_html();
			$html .= apply_filters( 'carousel_slider/loop/product-category', $template->render(), $category, $this->get_slider_setting() );
			$html .= $this->end_item_wrapper_html();
		}

		$html .= $this->end_wrapper_html();

		return apply_filters( 'carousel_slider_product_carousel', $html, $slider_id );
	}
}
modules/ProductCarousel/Setting.php000064400000010473151727276400013500 0ustar00<?php

namespace CarouselSlider\Modules\ProductCarousel;

use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\Helper as GlobalHelper;

/**
 * Setting class
 *
 * @package Modules/ProductCarousel
 */
class Setting extends SliderSetting {
	/**
	 * Is data read from the server?
	 *
	 * @var bool
	 */
	protected $extra_data_read = false;

	/**
	 * Available types
	 *
	 * @var string[]
	 */
	protected static $types = [
		'product_categories_list',
		'product_categories',
		'product_tags',
		'specific_products',
		'featured',
		'recent',
		'sale',
		'best_selling',
		'top_rated',
	];

	/**
	 * Get query type
	 *
	 * @return string
	 */
	public function get_query_type(): string {
		$slide_type = $this->get_prop( 'product_query_type' );
		// For backward compatibility of typo.
		$slide_type    = str_replace( 'query_porduct', 'query_product', $slide_type );
		$product_query = $this->get_prop( 'product_query' );
		if ( 'query_product' === $slide_type ) {
			$slide_type = $product_query;
		}

		return in_array( $slide_type, self::$types, true ) ? $slide_type : 'recent';
	}

	/**
	 * Get product category slug
	 *
	 * @return array
	 */
	public function get_categories_slug(): array {
		$ids = $this->get_prop( 'product_categories' );

		return Helper::format_term_slug( $ids, 'product_cat' );
	}

	/**
	 * Get product category slug
	 *
	 * @return array
	 */
	public function get_tags_slug(): array {
		$ids = $this->get_prop( 'product_tags' );

		return Helper::format_term_slug( $ids, 'product_tag' );
	}

	/**
	 * Read extra metadata
	 *
	 * @return void
	 */
	public function read_extra_metadata() {
		if ( $this->extra_data_read ) {
			return;
		}
		foreach ( self::extra_props() as $attribute => $config ) {
			$value = get_post_meta( $this->get_slider_id(), $config['id'], true );
			$value = ! empty( $value ) ? $value : $config['default'];
			$value = $this->prepare_item_for_response( $config['type'], $value );
			$this->set_prop( $attribute, $value );
		}
		$this->extra_data_read = true;
	}

	/**
	 * Slider extra props
	 *
	 * @return array
	 */
	public static function extra_props(): array {
		return [
			'slide_type'         => [
				'id'      => '_slide_type',
				'type'    => 'string',
				'default' => 'product-carousel',
			],
			'product_query_type' => [
				'id'      => '_product_query_type',
				'type'    => 'string',
				'default' => 'query_product',
			],
			'product_query'      => [
				'id'      => '_product_query',
				'type'    => 'string',
				'default' => 'recent',
			],
			'product_categories' => [
				'id'      => '_product_categories',
				'type'    => 'int[]',
				'default' => '',
			],
			'product_tags'       => [
				'id'      => '_product_tags',
				'type'    => 'int[]',
				'default' => '',
			],
			'product_in'         => [
				'id'      => '_product_in',
				'type'    => 'int[]',
				'default' => '',
			],
			'per_page'           => [
				'id'      => '_products_per_page',
				'type'    => 'int',
				'default' => 12,
			],
			'show_title'         => [
				'id'      => '_product_title',
				'type'    => 'bool',
				'default' => true,
			],
			'show_rating'        => [
				'id'      => '_product_rating',
				'type'    => 'bool',
				'default' => true,
			],
			'show_price'         => [
				'id'      => '_product_price',
				'type'    => 'bool',
				'default' => true,
			],
			'show_cart_button'   => [
				'id'      => '_product_cart_button',
				'type'    => 'bool',
				'default' => true,
			],
			'show_onsale_tag'    => [
				'id'      => '_product_onsale',
				'type'    => 'bool',
				'default' => true,
			],
			'show_wishlist'      => [
				'id'      => '_product_wishlist',
				'type'    => 'bool',
				'default' => false,
			],
			'show_quick_view'    => [
				'id'      => '_product_quick_view',
				'type'    => 'bool',
				'default' => false,
			],
			'title_color'        => [
				'id'      => '_product_title_color',
				'type'    => 'string',
				'default' => GlobalHelper::get_default_setting( 'product_title_color' ),
			],
			'button_color'       => [
				'id'      => '_product_button_bg_color',
				'type'    => 'string',
				'default' => GlobalHelper::get_default_setting( 'product_button_bg_color' ),
			],
			'button_on_color'    => [
				'id'      => '_product_button_text_color',
				'type'    => 'string',
				'default' => GlobalHelper::get_default_setting( 'product_button_text_color' ),
			],
		];
	}
}
modules/ProductCarousel/Template.php000064400000007304151727276400013635 0ustar00<?php

namespace CarouselSlider\Modules\ProductCarousel;

use CarouselSlider\Abstracts\AbstractTemplate;
use CarouselSlider\Helper;

defined( 'ABSPATH' ) || exit;

/**
 * Template class
 *
 * @package Modules/ProductCarousel
 */
class Template extends AbstractTemplate {

	/**
	 * Get default image carousel settings
	 *
	 * @return array
	 */
	public static function get_default_settings(): array {
		return wp_parse_args(
			[
				'_slide_type'                => 'product-carousel',
				// Product Carousel Settings.
				'_product_query_type'        => 'query_product',
				'_product_query'             => 'recent',
				'_product_categories'        => '',
				'_product_tags'              => '',
				'_product_in'                => '',
				'_products_per_page'         => '12',
				'_product_title'             => 'on',
				'_product_rating'            => 'on',
				'_product_price'             => 'on',
				'_product_cart_button'       => 'on',
				'_product_onsale'            => 'on',
				'_product_wishlist'          => 'off',
				'_product_quick_view'        => 'off',
				'_product_title_color'       => Helper::get_default_setting( 'product_title_color' ),
				'_product_button_bg_color'   => Helper::get_default_setting( 'product_button_bg_color' ),
				'_product_button_text_color' => Helper::get_default_setting( 'product_button_text_color' ),
			],
			parent::get_default_settings()
		);
	}

	/**
	 * Create a gallery image carousel with random images
	 *
	 * @param string $slider_title The slider title.
	 * @param array  $args Arguments.
	 *
	 * @return int The post-ID on success. Value 0 on failure.
	 */
	public static function create( string $slider_title = null, array $args = [] ): int {
		if ( empty( $slider_title ) ) {
			$slider_title = 'Product Carousel';
		}

		$post_id = self::create_slider( $slider_title );

		if ( ! $post_id ) {
			return 0;
		}

		$data       = wp_parse_args( $args, self::get_default_settings() );
		$query_type = $data['_product_query_type'];

		$query_types  = [
			'specific_products'  => [
				'_product_in' => implode( ',', self::get_random_products_ids() ),
			],
			'product_categories' => [
				'_product_categories' => implode( ',', self::get_product_categories_ids() ),
			],
			'product_tags'       => [
				'_product_tags' => implode( ',', self::get_product_tags_ids() ),
			],
			'query_product'      => [
				'_product_query' => 'recent',
			],
		];
		$default_args = $query_types[ $query_type ] ?? [];

		foreach ( $default_args as $meta_key => $default_value ) {
			if ( empty( $data[ $meta_key ] ) ) {
				$data[ $meta_key ] = $default_value;
			}
		}

		foreach ( $data as $meta_key => $meta_value ) {
			update_post_meta( $post_id, $meta_key, $meta_value );
		}

		return $post_id;
	}

	/**
	 * Get random products ID
	 *
	 * @return array List of products ID.
	 */
	private static function get_random_products_ids(): array {
		$args = array(
			'post_type'      => 'product',
			'post_status'    => 'publish',
			'orderby'        => 'rand',
			'posts_per_page' => 10,
		);

		$_posts = get_posts( $args );

		return wp_list_pluck( $_posts, 'ID' );
	}

	/**
	 * Get random product categories id
	 *
	 * @return array List of product categories id.
	 */
	private static function get_product_categories_ids(): array {
		$terms = get_terms(
			[
				'taxonomy'   => 'product_cat',
				'hide_empty' => true,
				'number'     => 5,
			]
		);

		return wp_list_pluck( $terms, 'term_id' );
	}

	/**
	 * Get random product tags id
	 *
	 * @return array List of product tags id.
	 */
	private static function get_product_tags_ids(): array {
		$terms = get_terms(
			array(
				'taxonomy'   => 'product_tag',
				'hide_empty' => true,
				'number'     => 5,
			)
		);

		return wp_list_pluck( $terms, 'term_id' );
	}
}
modules/index.php000064400000000131151727276400010042 0ustar00<?php
/**
 * Each module goes it own directory
 *
 * @package CarouselSlider/Modules
 */
modules/PostCarousel/Item.php000064400000011242151727276400012261 0ustar00<?php

namespace CarouselSlider\Modules\PostCarousel;

use WP_Post;
use WP_Term;

/**
 * Item class
 *
 * @package CarouselSlider\Modules\PostCarousel
 */
class Item {
	/**
	 * Post object
	 *
	 * @var WP_Post
	 */
	protected $post;

	/**
	 * Item constructor.
	 *
	 * @param WP_Post $post Post object.
	 */
	public function __construct( $post = null ) {
		if ( $post instanceof WP_Post ) {
			$this->post = $post;
		}
	}

	/**
	 * Get thumbnail html
	 *
	 * @param string $image_size Image size slug.
	 * @param bool   $lazy_load Lazy load images.
	 *
	 * @return string
	 */
	public function get_thumbnail_html( string $image_size, bool $lazy_load ): string {
		$permalink    = get_permalink( $this->post );
		$thumbnail_id = (int) get_post_thumbnail_id( $this->post->ID );
		if ( ! $thumbnail_id ) {
			return '<a href="' . esc_url( $permalink ) . '" class="carousel-slider__post-image"></a>';
		}
		$image_src = wp_get_attachment_image_src( $thumbnail_id, $image_size );
		$url       = is_array( $image_src ) ? $image_src[0] : '';

		$attrs = [
			'class' => 'carousel-slider__post-image',
			'href'  => esc_url( $permalink ),
		];

		if ( ! $lazy_load ) {
			if ( \CarouselSlider\Helper::is_using_swiper() ) {
				$attrs['data-background'] = esc_url( $url );
				$attrs['class']           = 'carousel-slider__post-image swiper-lazy';
			} else {
				$attrs['data-src'] = esc_url( $url );
				$attrs['class']    = 'carousel-slider__post-image owl-lazy';
			}
		} else {
			$attrs['style'] = 'background-image: url(' . esc_url( $url ) . ')';
		}

		return '<a ' . join( ' ', \CarouselSlider\Helper::array_to_attribute( $attrs ) ) . '></a>';
	}

	/**
	 * Get WP_Post object
	 *
	 * @return WP_Post
	 */
	public function get_post(): WP_Post {
		return $this->post;
	}

	/**
	 * Get WP_Post id
	 *
	 * @return int
	 */
	public function get_id(): int {
		return $this->post->ID;
	}

	/**
	 * Get permalink
	 *
	 * @return false|string
	 */
	public function get_permalink() {
		return get_permalink( $this->get_post() );
	}

	/**
	 * Get WP_Post title
	 *
	 * @return string
	 */
	public function get_title(): string {
		return get_the_title( $this->get_post() );
	}

	/**
	 * Get WP_Post content
	 *
	 * @return string
	 */
	public function get_content(): string {
		return apply_filters( 'the_content', $this->get_post()->post_content );
	}

	/**
	 * Get summery HTML
	 *
	 * @param int $excerpt_length Excerpt length.
	 *
	 * @return string
	 */
	public function get_summery( int $excerpt_length = 20 ): string {
		return wp_trim_words(
			apply_filters( 'the_content', $this->get_post()->post_content ),
			apply_filters( 'carousel_slider_post_excerpt_length', $excerpt_length ),
			apply_filters( 'carousel_slider_post_read_more', ' ...', $this->get_post() )
		);
	}

	/**
	 *  Get author posts url
	 *
	 * @return string
	 */
	public function get_author_posts_url(): string {
		return get_author_posts_url( intval( $this->get_post()->post_author ) );
	}

	/**
	 * Get author display name
	 *
	 * @return string
	 */
	public function get_author_display_name(): string {
		return get_the_author_meta( 'display_name', intval( $this->get_post()->post_author ) );
	}

	/**
	 * Get a formatted date post modified data
	 *
	 * @param string $format Date format.
	 *
	 * @return string
	 */
	public function get_formatted_modified_date( string $format = '' ): string {
		if ( empty( $format ) ) {
			$format = get_option( 'date_format' );
		}

		return date_i18n( $format, strtotime( $this->get_post()->post_modified ) );
	}

	/**
	 * Get categories related to WP_Post
	 *
	 * @return array|WP_Term[] Array of terms.
	 */
	public function get_categories(): array {
		return get_the_category( $this->get_post() );
	}

	/**
	 * Check if it has a category
	 *
	 * @return bool
	 */
	public function has_category(): bool {
		return count( $this->get_categories() ) > 0;
	}

	/**
	 * Get a primary category related to post
	 *
	 * @TODO: Check Yost SEO plugin to get primary category.
	 *
	 * @return null|WP_Term
	 */
	public function get_primary_category() {
		if ( ! $this->has_category() ) {
			return null;
		}
		$categories          = $this->get_categories();
		$primary_category    = $categories[0];
		$primary_category_id = $this->get_primary_category_id();
		if ( ! $primary_category_id ) {
			return $primary_category;
		}
		foreach ( $categories as $category ) {
			if ( $category->term_id === $this->get_primary_category_id() ) {
				$primary_category = $category;
				break;
			}
		}

		return $primary_category;
	}

	/**
	 * Get primary category id
	 *
	 * @return int
	 */
	public function get_primary_category_id(): int {
		$meta = get_post_meta( $this->get_id(), '_yoast_wpseo_primary_category', true );

		return is_numeric( $meta ) ? intval( $meta ) : 0;
	}
}
modules/PostCarousel/Module.php000064400000001430151727276400012606 0ustar00<?php

namespace CarouselSlider\Modules\PostCarousel;

defined( 'ABSPATH' ) || exit;

/**
 * Module class
 *
 * @package Modules/PostCarousel
 */
class Module {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_filter( 'carousel_slider/register_view', [ self::$instance, 'view' ] );
			Admin::init();
		}

		return self::$instance;
	}

	/**
	 * Render view
	 *
	 * @param array $views Registered views.
	 *
	 * @return array
	 */
	public function view( array $views ): array {
		$views['post-carousel'] = new View();

		return $views;
	}
}
modules/PostCarousel/Helper.php000064400000005267151727276410012615 0ustar00<?php

namespace CarouselSlider\Modules\PostCarousel;

use WP_Post;

defined( 'ABSPATH' ) || exit;

/**
 * Helper class
 *
 * @package Modules/PostCarousel
 */
class Helper {
	/**
	 * Get posts by carousel slider ID
	 *
	 * @param int $slider_id The slider id.
	 *
	 * @return WP_Post[]
	 */
	public static function get_posts( int $slider_id ): array {
		// Get settings from the carousel slider.
		$order      = get_post_meta( $slider_id, '_post_order', true );
		$orderby    = get_post_meta( $slider_id, '_post_orderby', true );
		$per_page   = intval( get_post_meta( $slider_id, '_posts_per_page', true ) );
		$query_type = get_post_meta( $slider_id, '_post_query_type', true );
		$query_type = empty( $query_type ) ? 'latest_posts' : $query_type;

		$args = [
			'post_type'      => 'post',
			'post_status'    => 'publish',
			'order'          => $order,
			'orderby'        => $orderby,
			'posts_per_page' => $per_page,
		];

		// Get posts by WP_Post IDs.
		if ( 'specific_posts' === $query_type ) {
			$post_in = explode( ',', get_post_meta( $slider_id, '_post_in', true ) );
			$post_in = array_map( 'intval', $post_in );
			unset( $args['posts_per_page'] );
			$args = array_merge( $args, array( 'post__in' => $post_in ) );
		}

		// Get posts by post catagories IDs.
		if ( 'post_categories' === $query_type ) {
			$post_categories = get_post_meta( $slider_id, '_post_categories', true );
			$args            = array_merge( $args, array( 'cat' => $post_categories ) );
		}

		// Get posts by WP_Post tags IDs.
		if ( 'post_tags' === $query_type ) {
			$post_tags = get_post_meta( $slider_id, '_post_tags', true );
			$post_tags = array_map( 'intval', explode( ',', $post_tags ) );
			$args      = array_merge( $args, [ 'tag__in' => $post_tags ] );
		}

		// Get posts by date range.
		if ( 'date_range' === $query_type ) {

			$post_date_after  = get_post_meta( $slider_id, '_post_date_after', true );
			$post_date_before = get_post_meta( $slider_id, '_post_date_before', true );

			if ( $post_date_after && $post_date_before ) {
				$args = array_merge(
					$args,
					[
						'date_query' => [
							[
								'after'     => $post_date_after,
								'before'    => $post_date_before,
								'inclusive' => true,
							],
						],
					]
				);
			} elseif ( $post_date_after ) {
				$args = array_merge(
					$args,
					[
						'date_query' => [
							[
								'before'    => $post_date_before,
								'inclusive' => true,
							],
						],
					]
				);
			} elseif ( $post_date_before ) {
				$args = array_merge(
					$args,
					[
						'date_query' => [
							[
								'before'    => $post_date_before,
								'inclusive' => true,
							],
						],
					]
				);
			}
		}

		return get_posts( $args );
	}
}
modules/PostCarousel/Admin.php000064400000013375151727276410012425 0ustar00<?php

namespace CarouselSlider\Modules\PostCarousel;

use CarouselSlider\Supports\MetaBoxForm;

defined( 'ABSPATH' ) || exit;

/**
 * Admin class
 *
 * @package Modules/PostCarousel
 */
class Admin {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'carousel_slider/meta_box_content', [ self::$instance, 'meta_box_content' ], 10, 2 );
			add_action( 'carousel_slider/save_slider', [ self::$instance, 'save_slider' ], 10, 2 );
		}

		return self::$instance;
	}

	/**
	 * Save post carousel content
	 *
	 * @param int   $post_id The post id.
	 * @param array $data User submitted data.
	 *
	 * @return void
	 */
	public function save_slider( int $post_id, array $data ) {
		if ( 'post-carousel' !== get_post_meta( $post_id, '_slide_type', true ) ) {
			return;
		}
		$raw_data = $data['post_carousel'] ?? [];
		foreach ( $this->get_settings_fields() as $field ) {
			$value = $raw_data[ $field['id'] ] ?? $field['default'];
			if ( is_array( $value ) ) {
				$value = implode( ',', $value );
			}

			update_post_meta( $post_id, $field['id'], sanitize_text_field( $value ) );
		}
	}

	/**
	 * Metabox content
	 *
	 * @param int    $slider_id The slider id.
	 * @param string $slider_type The slider type.
	 *
	 * @return void
	 */
	public function meta_box_content( int $slider_id, string $slider_type ) {
		if ( 'post-carousel' !== $slider_type ) {
			return;
		}
		foreach ( $this->get_settings_fields() as $field ) {
			\CarouselSlider\Helper::print_unescaped_internal_string( MetaBoxForm::field( $field ) );
		}
	}

	/**
	 * Get setting field
	 *
	 * @return array[]
	 */
	public function get_settings_fields(): array {
		return [
			[
				'group'   => 'post_carousel',
				'type'    => 'select',
				'id'      => '_post_query_type',
				'label'   => esc_html__( 'Query Type', 'carousel-slider' ),
				'default' => 'latest_posts',
				'choices' => [
					'latest_posts'    => esc_html__( 'Latest Posts', 'carousel-slider' ),
					'date_range'      => esc_html__( 'Date Range', 'carousel-slider' ),
					'post_categories' => esc_html__( 'Post Categories', 'carousel-slider' ),
					'post_tags'       => esc_html__( 'Post Tags', 'carousel-slider' ),
					'specific_posts'  => esc_html__( 'Specific posts', 'carousel-slider' ),
				],
			],
			[
				'group'       => 'post_carousel',
				'type'        => 'date',
				'id'          => '_post_date_after',
				'label'       => esc_html__( 'Date from', 'carousel-slider' ),
				/* translators: 1: an example date string */
				'description' => sprintf( esc_html__( 'Example: %s', 'carousel-slider' ), gmdate( 'F d, Y', strtotime( '-3 months' ) ) ),
				'default'     => '',
			],
			[
				'group'       => 'post_carousel',
				'type'        => 'date',
				'id'          => '_post_date_before',
				'label'       => esc_html__( 'Date to', 'carousel-slider' ),
				/* translators: 1: an example date string */
				'description' => sprintf( esc_html__( 'Example: %s', 'carousel-slider' ), gmdate( 'F d, Y', strtotime( '-7 days' ) ) ),
				'default'     => '',
			],
			[
				'group'       => 'post_carousel',
				'type'        => 'post_terms',
				'id'          => '_post_categories',
				'taxonomy'    => 'category',
				'multiple'    => true,
				'label'       => esc_html__( 'Post Categories', 'carousel-slider' ),
				'description' => esc_html__( 'Show posts associated with selected categories.', 'carousel-slider' ),
				'default'     => '',
			],
			[
				'group'       => 'post_carousel',
				'type'        => 'post_terms',
				'id'          => '_post_tags',
				'taxonomy'    => 'post_tag',
				'multiple'    => true,
				'label'       => esc_html__( 'Post Tags', 'carousel-slider' ),
				'description' => esc_html__( 'Show posts associated with selected tags.', 'carousel-slider' ),
				'default'     => '',
			],
			[
				'group'       => 'post_carousel',
				'type'        => 'posts_list',
				'id'          => '_post_in',
				'multiple'    => true,
				'label'       => esc_html__( 'Specific posts', 'carousel-slider' ),
				'description' => esc_html__( 'Select posts that you want to show as slider. Select at least 5 posts', 'carousel-slider' ),
				'default'     => '',
			],
			[
				'group'       => 'post_carousel',
				'type'        => 'number',
				'id'          => '_posts_per_page',
				'label'       => esc_html__( 'Posts per page', 'carousel-slider' ),
				'default'     => 12,
				'description' => esc_html__( 'How many post you want to show on carousel slide.', 'carousel-slider' ),
			],
			[
				'group'   => 'post_carousel',
				'type'    => 'select',
				'id'      => '_post_order',
				'label'   => esc_html__( 'Order', 'carousel-slider' ),
				'default' => 'DESC',
				'choices' => [
					'ASC'  => esc_html__( 'Ascending Order', 'carousel-slider' ),
					'DESC' => esc_html__( 'Descending Order', 'carousel-slider' ),
				],
			],
			[
				'group'   => 'post_carousel',
				'type'    => 'select',
				'id'      => '_post_orderby',
				'label'   => esc_html__( 'Order by', 'carousel-slider' ),
				'default' => 'ID',
				'choices' => [
					'none'          => esc_html__( 'No order', 'carousel-slider' ),
					'ID'            => esc_html__( 'Post id', 'carousel-slider' ),
					'author'        => esc_html__( 'Post author', 'carousel-slider' ),
					'title'         => esc_html__( 'Post title', 'carousel-slider' ),
					'modified'      => esc_html__( 'Last modified date', 'carousel-slider' ),
					'date'          => esc_html__( 'Publication date', 'carousel-slider' ),
					'rand'          => esc_html__( 'Random order', 'carousel-slider' ),
					'comment_count' => esc_html__( 'Number of comments', 'carousel-slider' ),
				],
			],
		];
	}
}
modules/PostCarousel/View.php000064400000002431151727276410012276 0ustar00<?php

namespace CarouselSlider\Modules\PostCarousel;

use CarouselSlider\Abstracts\AbstractView;
use CarouselSlider\Modules\PostCarousel\Helper as PostCarouselHelper;
use CarouselSlider\TemplateParserBase;

defined( 'ABSPATH' ) || exit;

/**
 * View class
 *
 * @package Modules/PostCarousel
 */
class View extends AbstractView {

	/**
	 * Render html view
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$posts = PostCarouselHelper::get_posts( $this->get_slider_id() );

		$content_html = $this->start_wrapper_html();

		$template = new TemplateParserBase( $this->get_slider_setting() );
		$template->set_template( 'loop/post-carousel.php' );

		foreach ( $posts as $post ) {
			setup_postdata( $post );
			$category = get_the_category( $post->ID );

			$template->set_object( new Item( $post ) );

			do_action( 'carousel_slider_post_loop', $post, $category );

			$content_html .= $this->start_item_wrapper_html();
			$content_html .= apply_filters( 'carousel_slider/loop/post-carousel', $template->render(), $post, $this->get_slider_setting() );
			$content_html .= $this->end_item_wrapper_html();
		}
		wp_reset_postdata();

		$content_html .= $this->end_wrapper_html();

		return apply_filters( 'carousel_slider_posts_carousel', $content_html, $this->get_slider_id(), $posts );
	}
}
modules/PostCarousel/Template.php000064400000006330151727276410013141 0ustar00<?php

namespace CarouselSlider\Modules\PostCarousel;

use CarouselSlider\Abstracts\AbstractTemplate;
use WP_Term;

defined( 'ABSPATH' ) || exit;

/**
 * Template class
 *
 * @package Modules/PostCarousel
 */
class Template extends AbstractTemplate {

	/**
	 * Get default image carousel settings
	 *
	 * @return array
	 */
	public static function get_default_settings(): array {
		return wp_parse_args(
			[
				'_slide_type'       => 'post-carousel',
				// Post-Carousel Settings.
				'_post_query_type'  => 'latest_posts',
				'_post_date_after'  => '',
				'_post_date_before' => '',
				'_post_categories'  => '',
				'_post_tags'        => '',
				'_post_in'          => '',
				'_posts_per_page'   => '12',
				'_post_orderby'     => 'ID',
				'_post_order'       => 'DESC',
				'_post_height'      => '450',
			],
			parent::get_default_settings()
		);
	}

	/**
	 * Create a gallery image carousel with random images
	 *
	 * @param string $slider_title The slider title.
	 * @param array  $args Optional arguments.
	 *
	 * @return int The WP_Post ID on success. Value 0 on failure.
	 */
	public static function create( string $slider_title = '', array $args = array() ): int {
		if ( empty( $slider_title ) ) {
			$slider_title = 'Post Carousel with Latest Post';
		}

		$post_id = self::create_slider( $slider_title );

		if ( is_wp_error( $post_id ) ) {
			return 0;
		}

		$data       = wp_parse_args( $args, self::get_default_settings() );
		$query_type = $data['_post_query_type'];

		$query_types = [
			'specific_posts'  => [ '_post_in' => implode( ',', self::get_random_posts_ids() ) ],
			'post_categories' => [ '_post_categories' => implode( ',', self::get_post_categories_ids() ) ],
			'post_tags'       => [ '_post_tags' => implode( ',', self::get_post_tags_ids() ) ],
			'date_range'      => [
				'_post_date_after'  => gmdate( 'Y-m-d', strtotime( '-3 years' ) ),
				'_post_date_before' => gmdate( 'Y-m-d', strtotime( '-2 hours' ) ),
			],
		];

		$default_args = $query_types[ $query_type ] ?? [];

		foreach ( $default_args as $meta_key => $default_value ) {
			if ( empty( $data[ $meta_key ] ) ) {
				$data[ $meta_key ] = $default_value;
			}
		}

		foreach ( $data as $meta_key => $meta_value ) {
			update_post_meta( $post_id, $meta_key, $meta_value );
		}

		return $post_id;
	}

	/**
	 * Get random posts ID
	 *
	 * @return array List of posts ID.
	 */
	private static function get_random_posts_ids(): array {
		$args = [
			'post_type'      => 'post',
			'post_status'    => 'publish',
			'orderby'        => 'rand',
			'posts_per_page' => 10,
		];

		$_posts = get_posts( $args );

		return wp_list_pluck( $_posts, 'ID' );
	}

	/**
	 * Get random post-categories id
	 *
	 * @return array List of categories id.
	 */
	private static function get_post_categories_ids(): array {
		$terms = get_terms(
			[
				'taxonomy'   => 'category',
				'hide_empty' => true,
				'number'     => 5,
			]
		);

		return wp_list_pluck( $terms, 'term_id' );
	}

	/**
	 * Get random post tags id
	 *
	 * @return array|WP_Term[] List of tags id.
	 */
	private static function get_post_tags_ids(): array {
		$terms = get_terms(
			[
				'taxonomy'   => 'post_tag',
				'hide_empty' => true,
				'number'     => 5,
			]
		);

		return wp_list_pluck( $terms, 'term_id' );
	}
}
modules/VideoCarousel/Item.php000064400000003102151727276410012377 0ustar00<?php

namespace CarouselSlider\Modules\VideoCarousel;

use CarouselSlider\Abstracts\Data;

/**
 * Item class
 */
class Item extends Data {
	/**
	 * Default data
	 *
	 * @var string[]
	 */
	protected $defaults = [
		'provider'  => '',
		'url'       => '',
		'video_id'  => '',
		'thumbnail' => '',
	];

	/**
	 * Class constructor
	 *
	 * @param array $data Video item data.
	 */
	public function __construct( array $data = [] ) {
		$this->data = wp_parse_args( $data, $this->defaults );
	}

	/**
	 * Get video provider
	 *
	 * @return string
	 */
	public function get_provider(): string {
		return $this->get_prop( 'provider' );
	}

	/**
	 * Get video id
	 *
	 * @return string|int YouTube, vimeo or integer value for self-hosted video.
	 */
	public function get_video_id() {
		return $this->get_prop( 'video_id' );
	}

	/**
	 * Get video url
	 *
	 * @return string
	 */
	public function get_url(): string {
		return $this->get_prop( 'url' );
	}

	/**
	 * Get video embed url
	 *
	 * @return string
	 */
	public function get_embed_url(): string {
		if ( 'youtube' === $this->get_provider() ) {
			return sprintf( '//youtube.com/embed/%s?autoplay=1', $this->get_video_id() );
		}
		if ( 'vimeo' === $this->get_provider() ) {
			return sprintf( '//player.vimeo.com/video/%s?autoplay=1', $this->get_video_id() );
		}

		return '//about:blank';
	}

	/**
	 * Get video thumbnail
	 *
	 * @param string $size Image size.
	 *
	 * @return string
	 */
	public function get_thumbnail_url( string $size = 'large' ): string {
		$thumbnail = $this->get_prop( 'thumbnail' );

		return $thumbnail[ $size ] ?? '';
	}
}
modules/VideoCarousel/Module.php000064400000006210151727276410012731 0ustar00<?php

namespace CarouselSlider\Modules\VideoCarousel;

use CarouselSlider\Modules\VideoCarousel\Helper as VideoCarouselHelper;

defined( 'ABSPATH' ) || exit;

/**
 * Module class
 *
 * @package Modules/VideoCarousel
 */
class Module {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'carousel_slider/meta_box_content', [ self::$instance, 'meta_box_content' ], 10, 2 );
			add_action( 'carousel_slider/save_slider', [ self::$instance, 'save_slider' ], 10, 2 );
			add_filter( 'carousel_slider/register_view', [ self::$instance, 'view' ] );
		}

		return self::$instance;
	}

	/**
	 * Meta box content
	 *
	 * @param  int    $slider_id  The slider id.
	 * @param  string $slider_type  The slider type.
	 */
	public function meta_box_content( int $slider_id, string $slider_type ) {
		if ( 'video-carousel' !== $slider_type ) {
			return;
		}
		?>
			<div class="carousel-slider-video-carousel-urls-container">
				<div class="carousel-slider-video-carousel-urls shapla-columns is-multiline" id="carousel-slider-video-carousel-urls">
					<?php
					$video_urls = get_post_meta( $slider_id, '_video_urls', true );
					if ( empty( $video_urls ) ) {
						$urls       = get_post_meta( $slider_id, '_video_url', true );
						$video_urls = VideoCarouselHelper::get_video_url( $urls );
					}
					foreach ( $video_urls as $index => $video_url ) {
						$item = new Item( $video_url );
						include CAROUSEL_SLIDER_PATH . '/templates/admin-meta-box/video-loop-item.php';
					}
					?>
				</div>
				<div class="shapla-columns">
					<div class="shapla-column is-12">
						<button class="button add_video_url_row"><?php esc_html_e( 'Add New Item', 'carousel-slider' ); ?></button>
					</div>
				</div>
			</div>
		<?php
	}

	/**
	 * Save slider video url
	 *
	 * @param  int   $slider_id  The slider id.
	 * @param  array $data  The raw data.
	 */
	public function save_slider( int $slider_id, $data ) {
		$video_urls = $data['_video_urls'] ?? [];
		if ( is_array( $video_urls ) && count( $video_urls ) ) {
			$video_urls = VideoCarouselHelper::get_video_url( $video_urls );
			update_post_meta( $slider_id, '_video_urls', $video_urls );

			if ( count( $video_urls ) ) {
				$sanitize_urls = wp_list_pluck( $video_urls, 'url' );
				update_post_meta( $slider_id, '_video_url', implode( ',', $sanitize_urls ) );
			}

			return;
		}
		$urls = $data['_video_url'] ?? '';
		if ( $urls ) {
			$urls          = is_string( $urls ) ? explode( ',', $urls ) : $urls;
			$sanitize_urls = [];
			if ( is_array( $urls ) ) {
				foreach ( $urls as $url ) {
					if ( filter_var( $url, FILTER_VALIDATE_URL ) ) {
						$sanitize_urls[] = $url;
					}
				}
			}
			update_post_meta( $slider_id, '_video_url', implode( ',', $sanitize_urls ) );
		}
	}

	/**
	 * Register view
	 *
	 * @param  array $views  Registered views.
	 *
	 * @return array
	 */
	public function view( array $views ): array {
		$views['video-carousel'] = new View();

		return $views;
	}
}
modules/VideoCarousel/Helper.php000064400000005657151727276420012742 0ustar00<?php

namespace CarouselSlider\Modules\VideoCarousel;

defined( 'ABSPATH' ) || exit;

/**
 * Helper class
 *
 * @package Modules/VideoCarousel
 */
class Helper {
	/**
	 * Get Youtube video ID from URL
	 *
	 * @param  string $url  The url string.
	 *
	 * @return false|string Youtube video ID or FALSE if not found
	 */
	public static function get_youtube_id_from_url( string $url ) {
		$parts = wp_parse_url( $url );
		if ( isset( $parts['query'] ) ) {
			parse_str( $parts['query'], $qs );
			if ( isset( $qs['v'] ) ) {
				return $qs['v'];
			} elseif ( isset( $qs['vi'] ) ) {
				return $qs['vi'];
			}
		}
		if ( isset( $parts['path'] ) ) {
			$path = explode( '/', trim( $parts['path'], '/' ) );

			return $path[ count( $path ) - 1 ];
		}

		return false;
	}

	/**
	 * Get Vimeo video ID from URL
	 *
	 * @param  string $url  The url string.
	 *
	 * @return false|string Vimeo video ID or FALSE if not found
	 */
	public static function get_vimeo_id_from_url( string $url ) {
		$parts = wp_parse_url( $url );
		if ( isset( $parts['path'] ) ) {
			$path = explode( '/', trim( $parts['path'], '/' ) );

			return $path[ count( $path ) - 1 ];
		}

		return false;
	}

	/**
	 * Get video URL
	 *
	 * @param  array|string $video_urls  The video urls.
	 *
	 * @return array
	 */
	public static function get_video_url( $video_urls ): array {
		if ( is_string( $video_urls ) ) {
			$video_urls = array_filter( explode( ',', $video_urls ) );
		}
		$_url = array();
		if ( is_array( $video_urls ) && count( $video_urls ) ) {
			foreach ( $video_urls as $video_url ) {
				if ( ! filter_var( $video_url, FILTER_VALIDATE_URL ) ) {
					continue;
				}
				$provider  = '';
				$video_id  = '';
				$thumbnail = '';
				if (
					false !== strpos( $video_url, 'youtube.com' ) ||
					false !== strpos( $video_url, 'youtu.be' )
				) {
					$provider  = 'youtube';
					$video_id  = static::get_youtube_id_from_url( $video_url );
					$video_url = sprintf( 'https://youtube.com/watch?v=%s', $video_id );
					$thumbnail = array(
						'large'  => 'https://img.youtube.com/vi/' . $video_id . '/hqdefault.jpg',
						'medium' => 'https://img.youtube.com/vi/' . $video_id . '/mqdefault.jpg',
						'small'  => 'https://img.youtube.com/vi/' . $video_id . '/sddefault.jpg',
					);

				} elseif ( false !== strpos( $video_url, 'vimeo.com' ) ) {
					$provider  = 'vimeo';
					$video_id  = static::get_vimeo_id_from_url( $video_url );
					$response  = wp_remote_get( "https://vimeo.com/api/v2/video/$video_id.json" );
					$thumbnail = json_decode( wp_remote_retrieve_body( $response ), true );
					$thumbnail = array(
						'large'  => $thumbnail[0]['thumbnail_large'] ?? null,
						'medium' => $thumbnail[0]['thumbnail_medium'] ?? null,
						'small'  => $thumbnail[0]['thumbnail_small'] ?? null,
					);
				}

				$_url[] = array(
					'provider'  => $provider,
					'url'       => $video_url,
					'video_id'  => $video_id,
					'thumbnail' => $thumbnail,
				);
			}
		}

		return $_url;
	}
}
modules/VideoCarousel/View.php000064400000002322151727276420012417 0ustar00<?php

namespace CarouselSlider\Modules\VideoCarousel;

use CarouselSlider\Abstracts\AbstractView;
use CarouselSlider\Modules\VideoCarousel\Helper as VideoCarouselHelper;
use CarouselSlider\TemplateParserBase;

defined( 'ABSPATH' ) || exit;

/**
 * View class
 *
 * @package Modules/VideoCarousel
 */
class View extends AbstractView {
	/**
	 * Render html view
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$setting   = $this->get_slider_setting();
		$slider_id = $this->get_slider_id();
		$urls      = get_post_meta( $slider_id, '_video_url', true );
		$urls      = VideoCarouselHelper::get_video_url( $urls );

		$template = new TemplateParserBase( $setting );
		$template->set_template( 'loop/video-carousel.php' );

		$html = $this->start_wrapper_html();
		foreach ( $urls as $url ) {
			$item = new Item( $url );
			$template->set_object( $item );

			$html .= $this->start_item_wrapper_html();
			$html .= apply_filters(
				'carousel_slider/loop/video-carousel',
				$template->render(),
				$item,
				$this->get_slider_setting()
			);
			$html .= $this->end_item_wrapper_html();
		}

		$html .= $this->end_wrapper_html();

		return apply_filters( 'carousel_slider_videos_carousel', $html, $slider_id );
	}
}
modules/VideoCarousel/Template.php000064400000003137151727276420013265 0ustar00<?php

namespace CarouselSlider\Modules\VideoCarousel;

use CarouselSlider\Abstracts\AbstractTemplate;

defined( 'ABSPATH' ) || exit;

/**
 * Template class
 *
 * @package Modules/VideoCarousel
 */
class Template extends AbstractTemplate {

	/**
	 * Create a gallery image carousel with random images
	 *
	 * @param string $slider_title The slider title.
	 * @param array  $args Additional arguments.
	 *
	 * @return int The WP_Post ID on success. Value 0 on failure.
	 */
	public static function create( $slider_title = null, $args = [] ): int {
		if ( empty( $slider_title ) ) {
			$slider_title = 'Image Carousel with Dummy Data';
		}

		$default = self::get_default_settings();
		$urls    = self::get_video_urls();
		$urls    = implode( ',', $urls );

		$default['_slide_type'] = 'video-carousel';
		$default['_video_url']  = $urls;

		$data = wp_parse_args( $args, $default );

		$post_id = self::create_slider( $slider_title );

		if ( ! $post_id ) {
			return 0;
		}

		foreach ( $data as $meta_key => $meta_value ) {
			update_post_meta( $post_id, $meta_key, $meta_value );
		}

		return $post_id;
	}

	/**
	 * Get video url
	 *
	 * @return array
	 */
	private static function get_video_urls(): array {
		return [
			'https://www.youtube.com/watch?v=_hVsamgr1k4',
			'https://www.youtube.com/watch?v=ZzI1JhElrxc',
			'https://www.youtube.com/watch?v=ImJB946azy0',
			'https://www.youtube.com/watch?v=a7hqn1yNzwM',
			'https://www.youtube.com/watch?v=OaYQZfr1RM',
			'https://www.youtube.com/watch?v=kYgp6wp27lM',
			'https://www.youtube.com/watch?v=4LhDXH81whk',
			'https://www.youtube.com/watch?v=yiAkvXyfakg',
		];
	}
}
templates/loop/image-carousel-url.php000064400000003011151727276420013731 0ustar00<?php

use CarouselSlider\Helper;
use CarouselSlider\Modules\ImageCarousel\ExternalImageItem;
use CarouselSlider\Modules\ImageCarousel\Setting;

defined( 'ABSPATH' ) || die;

/**
 * The global variables that are available to use here
 *
 * This template can be overridden by copying it to yourtheme/carousel-slider/loop/image-carousel-url.php.
 *
 * @global Setting $setting Slider setting object.
 * @global ExternalImageItem $object The Image Carousel Item object.
 */
?>
<div class="carousel-slider__item">
	<?php
	// Print start anchor tag for lightbox and external link.
	Helper::print_unescaped_internal_string( $object->get_link_html_start( $setting->get_image_target() ) );

	// Print image.
	Helper::print_unescaped_internal_string( $object->get_image_html( $setting->lazy_load_image() ) );

	if ( $setting->should_show_title() || $setting->should_show_caption() ) {
		echo '<div class="carousel-slider__caption">';

		if ( $setting->should_show_title() ) {
			echo '<h4 class="title">' . esc_html( $object->get_title() ) . '</h4>';
		}
		if ( $setting->should_show_caption() ) {
			echo '<p class="caption">' . esc_html( $object->get_caption() ) . '</p>';
		}

		echo '</div>';
	}

	// Print end anchor tag for lightbox and external link.
	Helper::print_unescaped_internal_string( $object->get_link_html_end() );

	// For swiper, add placeholder element for lazy loading.
	if ( $setting->is_using_swiper() && $setting->lazy_load_image() ) {
		echo '<div class="swiper-lazy-preloader swiper-lazy-preloader-white"></div>';
	}
	?>
</div>
templates/loop/product-categories-list.php000064400000001340151727276420015013 0ustar00<?php
defined( 'ABSPATH' ) || die;

/**
 * The global variables that are available to use here
 *
 * This template can be overridden by copying it to yourtheme/carousel-slider/loop/product-categories-list.php.
 *
 * @global \CarouselSlider\Modules\ProductCarousel\Setting $setting Slider setting object.
 * @global \WP_Term $object The WP_Term object.
 */

echo '<div class="product carousel-slider__product">';
do_action( 'woocommerce_before_subcategory', $object );
do_action( 'woocommerce_before_subcategory_title', $object );
do_action( 'woocommerce_shop_loop_subcategory_title', $object );
do_action( 'woocommerce_after_subcategory_title', $object );
do_action( 'woocommerce_after_subcategory', $object );
echo '</div>' . PHP_EOL;
templates/loop/image-carousel.php000064400000004047151727276430013144 0ustar00<?php

use CarouselSlider\Helper;
use CarouselSlider\Modules\ImageCarousel\Item;
use CarouselSlider\Modules\ImageCarousel\Setting;

defined( 'ABSPATH' ) || die;

/**
 * The global variables that are available to use here
 *
 * This template can be overridden by copying it to yourtheme/carousel-slider/loop/image-carousel.php.
 *
 * @global Setting $setting Slider setting object.
 * @global Item $object The Image Carousel Item object.
 */
$full_img     = $object->get_image_src( 'full' );
$link_context = $setting->should_show_lightbox() ? 'lightbox' : 'link';
?>
<div class="carousel-slider__item">
	<?php
	// Print start anchor tag for lightbox and external link.
	Helper::print_unescaped_internal_string( $object->get_link_html_start( $link_context, $setting->get_image_target() ) );

	// Print image.
	if ( $setting->lazy_load_image() ) {
		$image_src = $object->get_image_src( $setting->get_image_size() );
		if ( $setting->is_using_swiper() ) {
			echo '<img src="' . esc_attr( $image_src[0] ) . '" loading="lazy" alt="' . esc_attr( $object->get_alt_text() ) . '">';
		} else {
			echo '<img class="owl-lazy" data-src="' . esc_attr( $image_src[0] ) . '" alt="' . esc_attr( $object->get_alt_text() ) . '">';
		}
	} else {
		Helper::print_unescaped_internal_string( $object->get_image( $setting->get_image_size() ) );
	}

	if ( $setting->should_show_title() || $setting->should_show_caption() ) {
		echo '<div class="carousel-slider__caption">';

		if ( $setting->should_show_title() ) {
			echo '<h4 class="title">' . esc_html( $object->get_title() ) . '</h4>';
		}
		if ( $setting->should_show_caption() ) {
			echo '<p class="caption">' . esc_html( $object->get_caption() ) . '</p>';
		}

		echo '</div>';
	}

	// Print end anchor tag for lightbox and external link.
	Helper::print_unescaped_internal_string( $object->get_link_html_end( $link_context ) );

	// For swiper, add placeholder element for lazy loading.
	if ( $setting->is_using_swiper() && $setting->lazy_load_image() ) {
		echo '<div class="swiper-lazy-preloader swiper-lazy-preloader-white"></div>';
	}
	?>
</div>
templates/loop/product-carousel-2.php000064400000001464151727276430013701 0ustar00<?php

defined( 'ABSPATH' ) || die;

/**
 * The global variables that are available to use here
 *
 * @global \CarouselSlider\Modules\ProductCarousel\Setting $setting Slider setting object.
 * @global \WC_Product $product The WooCommerce product object.
 * @global \WP_Post $post The WP_Post object.
 */


echo '<div class="product carousel-slider__product">';

do_action( 'carousel_slider_before_shop_loop_item', $product, $setting->get_slider_id() );

do_action( 'woocommerce_before_shop_loop_item' );
do_action( 'woocommerce_before_shop_loop_item_title' );
do_action( 'woocommerce_shop_loop_item_title' );
do_action( 'woocommerce_after_shop_loop_item_title' );
do_action( 'woocommerce_after_shop_loop_item' );

do_action( 'carousel_slider_after_shop_loop_item', $product, $setting->get_slider_id() );

echo '</div>';
templates/loop/hero-banner-slider.php000064400000003225151727276430013724 0ustar00<?php

defined( 'ABSPATH' ) || die;

/**
 * The global variables that are available to use here
 *
 * This template can be overridden by copying it to yourtheme/carousel-slider/loop/hero-banner-slider.php.
 *
 * @global \CarouselSlider\Modules\HeroCarousel\Setting $setting Slider setting object.
 * @global \CarouselSlider\Modules\HeroCarousel\Item $object Hero carousel item object.
 */

$html = $object->get_cell_start();

$html .= $object->get_cell_background();

$html .= $object->get_cell_inner_start();

// Background Overlay.
$bg_overlay = $object->get_prop( 'bg_overlay' );
if ( ! empty( $bg_overlay ) ) {
	$overlay_style = 'background-color: ' . $bg_overlay . ';';

	$html .= '<div class="carousel-slider-hero__cell__background_overlay" style="' . $overlay_style . '"></div>';
}

$cell_content_attr = [
	'class'          => 'carousel-slider-hero__cell__content hidden',
	'style'          => 'max-width:' . $object->get_content_width(),
	'data-animation' => $object->get_content_animation(),
];

$html .= '<div ' . join( ' ', \CarouselSlider\Helper::array_to_attribute( $cell_content_attr ) ) . '>';

// Slide Heading.
$html .= $object->get_heading();

// Slide Description.
$html .= $object->get_description();

if ( 'button' === $object->get_link_type() ) {
	$html .= '<div class="carousel-slider-hero__cell__buttons">';
	$html .= $object->get_button_one();
	$html .= $object->get_button_two();
	$html .= '</div>'; // .carousel-slider-hero__cell__buttons
}

$html .= '</div>';// .carousel-slider-hero__cell__content
$html .= '</div>';// .carousel-slider-hero__cell__inner

$html .= $object->get_cell_end();

\CarouselSlider\Helper::print_unescaped_internal_string( $html );
templates/loop/post-carousel.php000064400000004041151727276430013041 0ustar00<?php

use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\Helper;
use CarouselSlider\Modules\PostCarousel\Item;

defined( 'ABSPATH' ) || die;

/**
 * The global variables that are available to use here
 *
 * This template can be overridden by copying it to yourtheme/carousel-slider/loop/post-carousel.php.
 *
 * @global SliderSetting $setting Slider setting object.
 * @global Item $object The item object.
 */
?>
<div class="carousel-slider__post">
	<div class="carousel-slider__post-content">
		<div class="carousel-slider__post-header">
			<?php
			Helper::print_unescaped_internal_string(
				$object->get_thumbnail_html( $setting->get_image_size(), $setting->lazy_load_image() )
			);
			?>
			<a class="carousel-slider__post-title" href="<?php echo esc_url( $object->get_permalink() ); ?>">
				<h2><?php echo esc_html( $object->get_title() ); ?></h2>
			</a>
		</div>
		<div class="carousel-slider__post-excerpt">
			<?php Helper::print_unescaped_internal_string( $object->get_summery() ); ?>
		</div>
		<footer class="carousel-slider__post-meta">
			<div class="carousel-slider__post-publication-meta">
				<div class="carousel-slider__post-details-info">
					<div class="carousel-slider__post-author">
						<a class="carousel-slider__post-author-link"
						   href="<?php echo esc_url( $object->get_author_posts_url() ); ?>">
							<?php echo esc_html( $object->get_author_display_name() ); ?>
						</a>
					</div>
					<time class="carousel-slider__post-publication-date"
						  datetime="<?php echo esc_attr( $object->get_formatted_modified_date( 'c' ) ); ?>">
						<?php echo esc_attr( $object->get_formatted_modified_date() ); ?>
					</time>
				</div>
			</div>
			<?php if ( $object->has_category() ) { ?>
				<div class="carousel-slider__post-category">
					<a class="carousel-slider__post-category-link"
					   href="<?php echo esc_url( get_category_link( $object->get_primary_category()->term_id ) ); ?>">
						<?php echo esc_html( $object->get_primary_category()->name ); ?>
					</a>
				</div>
			<?php } ?>
		</footer>
	</div>
</div>
templates/loop/video-carousel.php000064400000003112151727276430013160 0ustar00<?php

use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\Helper;
use CarouselSlider\Modules\VideoCarousel\Item;

defined( 'ABSPATH' ) || die;

/**
 * The global variables that are available to use here
 *
 * This template can be overridden by copying it to yourtheme/carousel-slider/loop/video-carousel.php.
 *
 * @global SliderSetting $setting Slider setting object.
 * @global Item $object The video carousel item setting.
 */
$popup_args = [
	'class'          => 'magnific-popup',
	'href'           => esc_url( $object->get_url() ),
	'data-provider'  => esc_attr( $object->get_provider() ),
	'data-id'        => esc_attr( $object->get_video_id() ),
	'data-embed_url' => esc_url( $object->get_embed_url() ),
];
$lazy_class = $setting->is_using_swiper() ? 'swiper-lazy' : 'owl-lazy';
?>
<div class="carousel-slider-item-video">
	<div class="carousel-slider-video-wrapper">
		<a <?php Helper::print_unescaped_internal_string( join( ' ', Helper::array_to_attribute( $popup_args ) ) ); ?>>
			<div class="carousel-slider-video-play-icon"></div>
			<div class="carousel-slider-video-overlay"></div>
			<?php if ( $setting->lazy_load_image() ) { ?>
				<?php if ( Helper::is_using_swiper() ) { ?>
					<img  alt="" src="<?php echo esc_url( $object->get_thumbnail_url() ); ?>" loading="lazy">
				<?php } else { ?>
					<img class="<?php echo esc_attr( $lazy_class ); ?>" alt=""
						data-src="<?php echo esc_url( $object->get_thumbnail_url() ); ?>">
				<?php } ?>
			<?php } else { ?>
				<img src="<?php echo esc_url( $object->get_thumbnail_url() ); ?>" alt="">
			<?php } ?>
		</a>
	</div>
</div>
templates/loop/product-carousel.php000064400000004617151727276440013546 0ustar00<?php
defined( 'ABSPATH' ) || die;

/**
 * The global variables that are available to use here
 *
 * @global \CarouselSlider\Modules\ProductCarousel\Setting $setting Slider setting object.
 * @global \WC_Product $object The WooCommerce product object.
 */

echo '<div class="product carousel-slider__product">';

do_action( 'carousel_slider_before_shop_loop_item', $object );

// Show product image.
if ( $object->get_image_id() ) {
	echo '<a class="woocommerce-LoopProduct-link" href="' . esc_url( $object->get_permalink() ) . '">';
	if ( $setting->lazy_load_image() ) {
		$image      = wp_get_attachment_image_src( $object->get_image_id(), $setting->get_image_size() );
		$lazy_class = $setting->is_using_swiper() ? 'swiper-lazy' : 'owl-lazy';
		if ( $setting->is_using_swiper() ) {
			echo '<img src="' . esc_url( $image[0] ) . '" alt="" loading="lazy" />';
		} else {
			echo '<img class="' . esc_attr( $lazy_class ) . '" data-src="' . esc_url( $image[0] ) . '" />';
		}
	} else {
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo $object->get_image( $setting->get_image_size() );
	}
	echo '</a>';
}

// Show title.
if ( $setting->get_prop( 'show_title' ) ) {
	echo '<a href="' . esc_attr( $object->get_permalink() ) . '">';
	echo '<h3 class="woocommerce-loop-product__title">' . esc_html( $object->get_title() ) . '</h3>';
	echo '</a>';
}

// Show Rating.
if ( $setting->get_prop( 'show_rating' ) ) {
	// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	echo wc_get_rating_html( $object->get_average_rating() );
}

// Sale Product batch.
if ( $object->is_on_sale() && $setting->get_prop( 'show_onsale_tag' ) ) {
	// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	echo apply_filters(
		'woocommerce_sale_flash',
		'<span class="onsale">' . __( 'Sale!', 'carousel-slider' ) . '</span>',
		get_post( $object->get_id() ),
		$object
	);
}

// Show Price.
if ( $setting->get_prop( 'show_price' ) ) {
	$price_html = '<span class="price">' . $object->get_price_html() . '</span>';
	// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	echo apply_filters( 'carousel_slider_product_price', $price_html, $object );
}

// Show button.
if ( $setting->get_prop( 'show_cart_button' ) ) {
	echo '<div style="clear: both;"></div>';
	woocommerce_template_loop_add_to_cart();
}

do_action( 'carousel_slider_after_shop_loop_item', $object, $setting->get_slider_id(), $setting );

echo '</div>';
templates/admin-meta-box/video-loop-item.php000064400000002154151727276440015107 0ustar00<?php

defined( 'ABSPATH' ) || die;

/**
 * This template is for admin video carousel meta box loop item
 *
 * @var CarouselSlider\Modules\VideoCarousel\Item $item Item object.
 * @var int $index Item index number.
 */
?>
<div class="carousel_slider-fields--video-urls shapla-column is-12 is-6-fullhd">
	<div class="carousel_slider-fields media-url-form-field">
		<div class="media-url-form-field__content">
			<label class="setting media-url-form-field__item">
				<span class="name"><?php esc_html_e( 'Youtube or Vimeo URL', 'carousel-slider' ); ?></span>
				<input type="url" name="_video_urls[]"
					   value="<?php echo esc_url( $item->get_url() ); ?>" autocomplete="off"
					   placeholder="https://www.youtube.com/watch?v=UOYK79yVrJ4">
			</label>
		</div>
		<div class="media-url-form-field__actions flex-direction-row">
			<span class="sort_video_url_row"><span class="dashicons dashicons-move"></span></span>
			<span class="add_video_url_row"><span class="dashicons dashicons-plus-alt"></span></span>
			<span class="delete_video_url_row"><span class="dashicons dashicons-trash"></span></span>
		</div>
	</div>
</div>
readme.txt000064400000016174151727276440006572 0ustar00=== Carousel Slider ===
Contributors: sayful
Tags: carousel, carousel slider, image carousel, product carousel, slider
Requires at least: 6.7
Tested up to: 6.9
Requires PHP: 7.0
Stable tag: 2.2.17
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.txt

Create SEO friendly Image, Logo, Video, Post, WooCommerce Product Carousel, and Slider.

== Description ==

**Create SEO friendly Image, Logo, Video, Post, WooCommerce Product Carousel, and Slider.**

Carousel Slider is a touch-enabled WordPress plugin that lets you create a highly customizable,
stylish responsive carousel slider. With Carousel Slider, you can create an image carousel using a media gallery or
custom url, post carousel, video carousel.

**If you like this plugin, please give us [5 star](https://wordpress.org/support/plugin/carousel-slider/reviews/?rate=5#new-post) to encourage for future improvement.**

= Key Features List =

* **Support major website/page builder**, including Gutenberg (WordPress core), Elementor, Visual Composer, SiteOrigin, Divi Builder
* **Multiple types carousel**, images from media gallery, images from URL, videos from youtube and vimeo, posts, and WooCommerce products carousel slider
* **Hero slider** with background image, title, description, call to action buttons and more
* **Posts carousel**, support Specific posts, Post Categories, Post Tags, Posts per page, Date range query and ordering
* **Video carousel**, support custom height and width (Currently only support video from Youtube and Vimeo)
* **WooCommerce Product carousel**, support Product Categories, Product Tags, Specific Products, Featured Products, Recent Products, Sale Products, Best-Selling Products, Top Rated Products
* Options to hide/show product Title, Rating, Price, Cart Button, Sale Tag, Wishlist Button, Quick View button and options to change color for Title, Button Background, Button text
* **Fully responsive**, configure the number of items to display for desktop, small desktop, tablet and mobile devices
* **Lightweight**, only loads stuff when carousel is used
* **Navigation and pagination**, choose what type of navigation is displayed for your carousel with unlimited colors option
* **Works great in touch devices**, Touch and Grab enabled
* Supported in all major browsers
* CSS3 3D Acceleration
* Multiple carousel on same page
* Lazy load images
* Support image title, caption, link url
* and more options

== Installation ==

* From your WordPress dashboard go to **Plugins > Add New**.
* Search for **Carousel Slider** in **Search Plugins** box.
* Find the WordPress Plugin named **Carousel Slider** by **Sayful Islam**.
* Click **Install Now** to install the **Carousel Slider** Plugin.
* The plugin will begin to download and install.
* Now click **Activate** to activate the plugin.

If you still need help. visit [WordPress codex](https://codex.wordpress.org/Managing_Plugins#Installing_Plugins)

== Screenshots ==

1. Carousel slider admin page
2. Front-end example of a post-carousel slider.
3. Front-end example of a video carousel slider.
4. Front-end example of an image carousel slider.
5. Front-end example of a product carousel slider.
6. Front-end example of products Quick View.
7. Front-end example of image lightbox.
8. Carousel slider admin live preview.

== Upgrade Notice ==
Update to get new features and better security.

== Frequently Asked Questions ==

= Will Carousel Slider work with my theme? =
Carousel Slider works with any WordPress theme if themes are developed according to WordPress standard.

= Is Carousel Slider responsive? =
Yes, Carousel Slider is fully responsive, mobile, and touch-friendly.

= Can I add Carousel Slider anywhere on my website?=
Yes, you can add a carousel inside your blog posts, pages, widgets, and anywhere else on your WordPress website with a shortcode.

= Can I have multiple carousels on the same post / page?
Yes. You can add multiple carousels on the same post / page.

= How to use Carousel Slider in Gutenberg Block Editor (WordPress 5.0 or later) =
Carousel Slider is a first-class citizen in Gutenberg Block Editor. Search 'carousel slider' There is
a dedicated 'carousel slider' block with a live preview for Gutenberg Block Editor.

== Changelog ==

= version 2.2.17 - 2025-12-01 =
* Test with WordPress 6.9 and WooCommerce 10.3
* Fix - Function _load_textdomain_just_in_time was called incorrectly issue.

= version 2.2.16 - 2025-04-10 =
* Remove data sharing and feedback functionality.
* Test with WordPress 6.8 and WooCommerce 9.8

= version 2.2.15 - 2024-10-10 =
* Fix - Fix XSS security vulnerability via Magnific Popups JavaScript Library

= version 2.2.14 - 2024-08-20 =
* Fix - Fix XSS security vulnerability from the slide edit page for Hero Carousel. (reported by Bob)

= version 2.2.13 - 2024-06-14 =
* Feature - Add a live preview option on the slider edit page.

= version 2.2.12 - 2024-05-22 =
* Tweak - Update video parse functionality from YouTube share url.
* Tweak - Add a setting option to enable/disable data sharing.
* Dev - Update internal code based on updated WordPress coding standards.
* Dev - Fix some minor bugs.

= version 2.2.11 - 2024-04-18 =
* Fix - Fix XSS security vulnerability from the slide edit page for Image Carousel (URL). (reported by Dmitrii Ignatyev)

= version 2.2.10 - 2024-04-09 =
* Fix - Fix XSS security vulnerability from the slide edit page for Hero Carousel. (reported by Artyom Krugov)

= version 2.2.9 - 2024-04-07 =
* Dev - Update compatibility with WooCommerce High-Performance Order Storage.
* Dev - Tested with WordPress 6.5 and WooCommerce 8.7

= version 2.2.8 - 2024-02-28 =
* Fix - Fix slider is not showing on update 2.2.7

= version 2.2.7 - 2024-02-28 =
* Fix - Update data escape functionality for slider configuration.

= version 2.2.6 - 2024-02-07 =
* Fix - Fix data sanitize issue for the field 'Slides Per View' on the admin edit page.

= version 2.2.5 - 2023-11-12 =
* Fix - Fix post-carousel date issue.
* Fix - Fix star rating style broken for WooCommerce product carousel.

= version 2.2.4 - 2023-08-20 =
* Fix - Add nonce verification and permission checking on hero carousel ajax actions.
* Fix - Add permission checking on plugin deactivation feedback data submission.

= version 2.2.3 - 2023-08-18 =
* Fix - Fix a security issue related to a plugin data tracking consent option.

= version 2.2.2 - 2023-08-08 =
* Dev - Tested with WordPress 6.3 and WooCommerce 7.9
* Dev - Add REST API functionality to create/update hero carousel (Coming UI improvement for hero carousel).

= version 2.2.1 - 2023-03-31 =
* Dev - Tested with WordPress 6.2 and WooCommerce 7.5
* Dev - Update the Swiper JavaScript library to version 9.1
* Dev - Update other JavaScript dependencies to the latest version.

= version 2.2.0 - 2022-12-31 =
* Feature - Add template to overwrite design from theme.
* Feature - Add basic dialog to replace "Magnific Popup" library.
* Feature - Add "Swiper" to replace "Owl Carousel 2" for the slider library.
* Dev - Re-design responsive setting functionality.
* Dev - Add SliderSettingInterface class.
* Dev - Add MetaBoxConfig class to make metabox configuration shareable.
* Dev - Add multi-checkbox setting field.
* Fix - Hero carousel delete button not working.
* Fix - Hero carousel index is not correct.
languages/readme.txt000064400000000202151727276440010521 0ustar00Translations have moved to
https://translate.wordpress.org/projects/wp-plugins/carousel-slider/

Thank you for your contribution.
carousel-slider.php000064400000016063151727276440010377 0ustar00<?php
/**
 * Plugin Name: Carousel Slider
 * Plugin URI: https://majeedraza.me/?utm_source=wp-plugins&utm_campaign=plugin-uri&utm_medium=wp-dash
 * Description: <strong>Carousel Slider</strong> allows you to create beautiful, touch-enabled, responsive carousels and sliders. It lets you create SEO friendly Image carousel from Media Library or from custom URL, Video carousel using YouTube and Vimeo video, Post carousel, Hero banner slider and various types of WooCommerce products carousels.
 * Version: 2.2.17
 * Requires at least: 6.7
 * Requires PHP: 7.0
 * Author: Sayful Islam
 * Author URI: https://github.com/sayful1/?utm_source=wp-plugins&utm_campaign=author-uri&utm_medium=wp-dash
 *
 * WC requires at least: 3.0
 * WC tested up to: 10.3
 *
 * Text Domain: carousel-slider
 *
 * License: GPLv3
 * License URI: https://www.gnu.org/licenses/gpl-3.0.txt
 *
 * @package Carousel_Slider
 * @author Sayful Islam
 */

// If this file is called directly, abort.
defined( 'ABSPATH' ) || exit;

if ( ! class_exists( 'Carousel_Slider' ) ) {
	/**
	 * The core plugin class.
	 * This is used to define internationalization, admin-specific hooks, and public-facing site hooks.
	 * Also maintains the unique identifier of this plugin as well as the current version of the plugin.
	 */
	final class Carousel_Slider {

		/**
		 * Plugin name slug
		 *
		 * @var string
		 */
		private $plugin_name = 'carousel-slider';

		/**
		 * Plugin custom post type
		 *
		 * @var string
		 */
		private $post_type = 'carousels';

		/**
		 * Plugin version
		 *
		 * @var string
		 */
		private $version = '2.2.16';

		/**
		 * Minimum PHP version required
		 *
		 * @var string
		 */
		private $min_php = '7.0';

		/**
		 * The instance of the class
		 *
		 * @var self
		 */
		private static $instance;

		/**
		 * Main Carousel_Slider Instance
		 * Ensures only one instance of the class is loaded or can be loaded.
		 *
		 * @return Carousel_Slider - Main instance
		 * @since 1.6.0
		 */
		public static function instance() {
			if ( is_null( self::$instance ) ) {
				self::$instance = new self();

				// define plugin constants.
				self::$instance->define_constants();

				// Register autoloader.
				self::$instance->register_autoloader();

				// Check if the PHP version is supported for our plugin.
				if ( ! self::$instance->is_supported_php() ) {
					register_activation_hook( __FILE__, [ self::$instance, 'auto_deactivate' ] );
					add_action( 'admin_notices', [ self::$instance, 'php_version_notice' ] );

					return self::$instance;
				}

				do_action( 'carousel_slider/init' );

				// bootstrap plugin main class.
				self::$instance->bootstrap_plugin();

				register_activation_hook( __FILE__, [ self::$instance, 'activation' ] );
				register_deactivation_hook( __FILE__, [ self::$instance, 'deactivation' ] );

				do_action( 'carousel_slider/loaded' );
			}

			return self::$instance;
		}

		/**
		 * Define plugin constants
		 */
		public function define_constants() {
			define( 'CAROUSEL_SLIDER', $this->plugin_name );
			define( 'CAROUSEL_SLIDER_VERSION', $this->version );
			define( 'CAROUSEL_SLIDER_POST_TYPE', $this->post_type );
			define( 'CAROUSEL_SLIDER_FILE', __FILE__ );
			define( 'CAROUSEL_SLIDER_PATH', dirname( CAROUSEL_SLIDER_FILE ) );
			define( 'CAROUSEL_SLIDER_URL', plugins_url( '', CAROUSEL_SLIDER_FILE ) );
			define( 'CAROUSEL_SLIDER_ASSETS', CAROUSEL_SLIDER_URL . '/assets' );
			$this->define_constant( 'CAROUSEL_SLIDER_PRO_PROMOTION', false );
		}

		/**
		 * Define constant if not defined
		 *
		 * @param string $constant_name The constant name.
		 * @param mixed  $value The constant value.
		 *
		 * @return void
		 */
		public function define_constant( string $constant_name, $value ) {
			if ( ! defined( $constant_name ) ) {
				define( $constant_name, $value );
			}
		}

		/**
		 * Load plugin classes
		 */
		private function register_autoloader() {
			if ( file_exists( CAROUSEL_SLIDER_PATH . '/vendor/autoload.php' ) ) {
				include CAROUSEL_SLIDER_PATH . '/vendor/autoload.php';
			} else {
				include_once CAROUSEL_SLIDER_PATH . '/includes/Autoloader.php';

				// instantiate the loader.
				$loader = new CarouselSlider\Autoloader();

				// register the base directories for the namespace prefix.
				$loader->add_namespace( 'CarouselSlider', CAROUSEL_SLIDER_PATH . '/includes' );
				$loader->add_namespace( 'CarouselSlider\Modules', CAROUSEL_SLIDER_PATH . '/modules' );

				// register the autoloader.
				$loader->register();
			}
		}

		/**
		 * Instantiate the required classes
		 *
		 * @return void
		 */
		public function bootstrap_plugin() {
			CarouselSlider\Plugin::init();
		}

		/**
		 * To be run when the plugin is activated
		 *
		 * @return void
		 */
		public function activation() {
			do_action( 'carousel_slider/activation' );
		}

		/**
		 * To be run when the plugin is deactivated
		 *
		 * @return void
		 */
		public function deactivation() {
			do_action( 'carousel_slider/deactivation' );
		}

		/**
		 * Show notice about the PHP version
		 *
		 * @return void
		 */
		public function php_version_notice() {

			if ( $this->is_supported_php() || ! current_user_can( 'manage_options' ) ) {
				return;
			}

			$error  = __( 'Your installed PHP Version is: ', 'carousel-slider' ) . PHP_VERSION . '. ';
			$error .= sprintf(
			/* translators: 1: min php version requires */
				__( 'The Carousel Slider plugin requires PHP version %s or greater.', 'carousel-slider' ),
				$this->min_php
			);
			?>
			<div class="error">
				<p><?php printf( esc_html( $error ) ); ?></p>
			</div>
			<?php
		}

		/**
		 * Bail out if the php version is lower than
		 *
		 * @return void
		 */
		public function auto_deactivate() {
			if ( $this->is_supported_php() ) {
				return;
			}

			deactivate_plugins( plugin_basename( __FILE__ ) );

			$error  = '<h1>' . __( 'An Error Occurred', 'carousel-slider' ) . '</h1>';
			$error .= '<h2>' . __( 'Your installed PHP Version is: ', 'carousel-slider' ) . PHP_VERSION . '</h2>';
			/* translators: 1: min php version requires */
			$error .= '<p>' . sprintf( __( 'The Carousel Slider plugin requires PHP version %s or greater', 'carousel-slider' ), $this->min_php ) . '</p>';
			$error .= '<p>' . sprintf(
				/* translators: 1: php doc page link start, 2: php doc page link end */
				__( 'The version of your PHP is %1$s unsupported and old %2$s. ', 'carousel-slider' ),
				'<a href="https://php.net/supported-versions.php" target="_blank"><strong>',
				'</strong></a>'
			);
			$error .= __( 'You should update your PHP software or contact your host regarding this matter.', 'carousel-slider' ) . '</p>';

			$title = __( 'Plugin Activation Error', 'carousel-slider' );
			wp_die( wp_kses_post( $error ), esc_html( $title ), [ 'back_link' => true ] );
		}

		/**
		 * Check if the PHP version is supported
		 *
		 * @return bool
		 */
		private function is_supported_php() {
			return ! version_compare( PHP_VERSION, $this->min_php, '<=' );
		}
	}
}

/**
 * Begins execution of the plugin.
 *
 * Since everything within the plugin is registered via hooks,
 * then kicking off the plugin from this point in the file does
 * not affect the page life cycle.
 */
Carousel_Slider::instance();
includes/Assets.php000064400000013271151727276440010350 0ustar00<?php

namespace CarouselSlider;

defined( 'ABSPATH' ) || exit;

/**
 * Assets class
 */
class Assets {

	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	private static $instance;

	/**
	 * Plugin name slug
	 *
	 * @var string
	 */
	private $plugin_name;

	/**
	 * The plugin version
	 *
	 * @var string
	 */
	private $version;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'wp_loaded', [ self::$instance, 'register' ] );
			add_action( 'admin_head', [ self::$instance, 'admin_localize_data' ], 9 );
		}

		return self::$instance;
	}

	/**
	 * Check if script debugging is enabled
	 *
	 * @return bool
	 */
	private function is_script_debug_enabled(): bool {
		return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG;
	}

	/**
	 * Checks to see if the site has SSL enabled or not.
	 *
	 * @return bool
	 */
	public static function is_ssl(): bool {
		if ( is_ssl() ) {
			return true;
		} elseif ( 0 === stripos( get_option( 'siteurl' ), 'https://' ) ) {
			return true;
		} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
			return true;
		}

		return false;
	}

	/**
	 * Get assets URL
	 *
	 * @param  string $path  Optional path.
	 *
	 * @return string
	 */
	public static function get_assets_url( string $path = '' ): string {
		$url = CAROUSEL_SLIDER_ASSETS;

		if ( static::is_ssl() && 0 === stripos( $url, 'http://' ) ) {
			$url = str_replace( 'http://', 'https://', $url );
		}

		if ( ! empty( $path ) ) {
			return rtrim( $url, '/' ) . '/' . ltrim( $path, '/' );
		}

		return $url;
	}

	/**
	 * Register our app scripts and styles
	 *
	 * @return void
	 */
	public function register() {
		$this->plugin_name = CAROUSEL_SLIDER;
		$this->version     = CAROUSEL_SLIDER_VERSION;

		if ( $this->is_script_debug_enabled() ) {
			$this->version = $this->version . '-' . time();
		}

		$this->register_scripts( $this->get_scripts() );
		$this->register_styles( $this->get_styles() );
	}

	/**
	 * Register scripts
	 *
	 * @param  array $scripts  The scripts to register.
	 *
	 * @return void
	 */
	private function register_scripts( array $scripts ) {
		foreach ( $scripts as $handle => $script ) {
			$deps      = $script['deps'] ?? false;
			$in_footer = $script['in_footer'] ?? true;
			$version   = $script['version'] ?? $this->version;
			wp_register_script( $handle, $script['src'], $deps, $version, $in_footer );
		}
	}

	/**
	 * Register styles
	 *
	 * @param  array $styles  The styles to register.
	 *
	 * @return void
	 */
	public function register_styles( array $styles ) {
		foreach ( $styles as $handle => $style ) {
			$deps = $style['deps'] ?? false;
			wp_register_style( $handle, $style['src'], $deps, $this->version );
		}
	}

	/**
	 * Get all registered scripts
	 *
	 * @return array
	 */
	public function get_scripts(): array {
		return [
			'carousel-slider-admin'              => [
				'src'  => static::get_assets_url( 'js/admin.js' ),
				'deps' => [
					'jquery',
					'wp-color-picker',
					'jquery-ui-accordion',
					'jquery-ui-tabs',
					'jquery-ui-sortable',
				],
			],
			'carousel-slider-admin-new-carousel' => [
				'src' => static::get_assets_url( 'js/admin-add-new-carousel.js' ),
			],
			'carousel-slider-frontend'           => [
				'src'  => static::get_assets_url( 'js/frontend.js' ),
				'deps' => [ 'jquery' ],
			],
			'carousel-slider-frontend-v2'        => [
				'src' => static::get_assets_url( 'js/frontend-v2.js' ),
			],
		];
	}

	/**
	 * Get registered styles
	 *
	 * @return array
	 */
	public function get_styles(): array {
		return [
			'carousel-slider-frontend'           => [
				'src' => static::get_assets_url( 'css/frontend.css' ),
			],
			'carousel-slider-frontend-v2'        => [
				'src' => static::get_assets_url( 'css/frontend-v2.css' ),
			],
			'carousel-slider-admin'              => [
				'src'  => static::get_assets_url( 'css/admin.css' ),
				'deps' => [ 'wp-color-picker' ],
			],
			'carousel-slider-admin-new-carousel' => [
				'src' => static::get_assets_url( 'css/admin-add-new-carousel.css' ),
			],
		];
	}

	/**
	 * Script to load css file via javaScript
	 *
	 * @return string
	 */
	public static function get_style_loader_script(): string {
		$data = self::get_assets_url( 'css/frontend.css' );
		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
		$javascript = file_get_contents( self::get_assets_url( '/js/frontend-style-loader.js' ) );
		$script     = '<script id="carousel-slider-style-loader">' . PHP_EOL;
		$script    .= 'window.carouselSliderCssUrl = ' . wp_json_encode( $data ) . ';' . PHP_EOL;
		$script    .= $javascript . PHP_EOL;
		$script    .= '</script>' . PHP_EOL;

		return $script;
	}

	/**
	 * Global localize data both for admin and frontend
	 */
	public static function admin_localize_data() {
		$user              = wp_get_current_user();
		$is_user_logged_in = $user->exists();

		$data = [
			'homeUrl'  => home_url(),
			'ajaxUrl'  => admin_url( 'admin-ajax.php' ),
			'restRoot' => esc_url_raw( rest_url( 'carousel-slider/v1' ) ),
			'nonce'    => wp_create_nonce( 'carousel_slider_ajax_nonce' ),
		];

		if ( $is_user_logged_in ) {
			$data['restNonce'] = wp_create_nonce( 'wp_rest' );
		}

		if ( is_admin() ) {
			$slider_types = [];
			foreach ( Helper::get_slider_types() as $slug => $args ) {
				$slider_types[] = array_merge( [ 'slug' => $slug ], $args );
			}
			$data['sliderTypes'] = $slider_types;

			$data['l10n'] = [
				'confirmDelete' => __( 'Are you sure to delete it?', 'carousel-slider' ),
			];
		}

		echo '<script>window.CarouselSliderL10n = ' . wp_json_encode( $data ) . '</script>' . PHP_EOL;
	}
}
includes/Admin/Upgrader.php000064400000013470151727276450011711 0ustar00<?php
/**
 * The upgrade-specific functionality of the plugin.
 *
 * @package CarouselSlider
 */

namespace CarouselSlider\Admin;

defined( 'ABSPATH' ) || exit;

/**
 * Upgrader class
 */
class Upgrader {

	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'admin_notices', [ self::$instance, 'show_upgrade_notice' ] );
			add_action( 'wp_ajax_carousel_slider_upgrade', [ self::$instance, 'upgrade' ] );

			add_action(
				'in_plugin_update_message-carousel-slider/carousel-slider.php',
				[ self::$instance, 'in_plugin_update_message' ]
			);
		}

		return self::$instance;
	}


	/**
	 * Show in plugin update message
	 *
	 * @param array $plugin_data plugin info data.
	 */
	public function in_plugin_update_message( array $plugin_data ) {
		$current_version       = CAROUSEL_SLIDER_VERSION;
		$current_version_array = explode( '.', $current_version );
		$new_version           = $plugin_data['new_version'];
		$new_version_array     = explode( '.', $new_version );

		$html = '';
		if ( version_compare( $current_version_array[0], $new_version_array[0], '<' ) ) {
			$html .= '</p><div class="cs_plugin_upgrade_notice extensions_warning major_update">';
			$html .= '<div class="cs_plugin_upgrade_notice__title">';
			$html .= sprintf(
			/* translators: 1: plugin title, 2: plugin new version number */
				__( '%1$s version %2$s is a major update.', 'carousel-slider' ),
				'<strong>' . $plugin_data['Title'] . '</strong>',
				'<strong>' . $new_version . '</strong>'
			);
			$html .= '</div>';
			$html .= '<div class="cs_plugin_upgrade_notice__description">';
			$html .= __( 'We made a lot of major changes to this version.', 'carousel-slider' ) . ' ';
			$html .= __( 'We believe that all functionality will remain same after update (remember to refresh you cache plugin).', 'carousel-slider' ) . ' ';
			$html .= __( 'Still make sure that you took a backup so you can role back if anything happen wrong to you.', 'carousel-slider' );
			$html .= '</div>';
			$html .= '</div><p class="dummy" style="display: none">';
		}

		$message = apply_filters( 'carousel_slider/in_plugin_update_message', $html, $plugin_data );
		echo wp_kses_post( $message );
	}

	/**
	 * Show upgrade notice
	 */
	public function show_upgrade_notice() {
		$version = get_option( 'carousel_slider_version' );
		if ( ! ( false !== $version && version_compare( $version, '2.0', '<' ) ) ) {
			return;
		}
		$message     = __( 'Carousel Slider need to update database.', 'carousel-slider' );
		$message2    = __( 'We strongly recommend creating a backup of your site before updating.', 'carousel-slider' );
		$button_text = __( 'Update database', 'carousel-slider' );
		$update_url  = wp_nonce_url(
			add_query_arg( [ 'action' => 'carousel_slider_upgrade' ], admin_url( 'admin-ajax.php' ) ),
			'carousel_slider_upgrade'
		);
		$html        = '<div class="notice notice-info is-dismissible">';
		$html       .= '<p><strong>' . $message . '</strong> ' . $message2 . '</p>';
		$html       .= '<p><a href="' . $update_url . '" class="button">' . $button_text . '</a></p>';
		$html       .= '</div>';

		echo wp_kses_post( $html );
	}

	/**
	 * Run upgrade function
	 */
	public function upgrade() {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$nonce       = $_REQUEST['_wpnonce'] ? sanitize_text_field( $_REQUEST['_wpnonce'] ) : null;
		$is_verified = wp_verify_nonce( $nonce, 'carousel_slider_upgrade' );

		$message = '<h1>' . __( 'Carousel Slider', 'carousel-slider' ) . '</h1>';
		if ( ! ( current_user_can( 'manage_options' ) && $is_verified ) ) {
			$message .= '<p>' . __( 'Sorry. This link only for admin to perform upgrade tasks.', 'carousel-slider' ) . '</p>';
			_default_wp_die_handler( $message, '', [ 'back_link' => true ] );
		}

		$version = get_option( 'carousel_slider_version', '1.0.0' );
		if ( version_compare( $version, '1.10.0', '<=' ) ) {
			static::fix_meta_key_typo_error();
			static::fix_product_query_type_typo_error();
		}

		// Add a plugin version to the database.
		update_option( 'carousel_slider_version', CAROUSEL_SLIDER_VERSION );

		$message .= '<p>' . __( 'Database upgrade process has been started.', 'carousel-slider' ) . '</p>';
		_default_wp_die_handler( $message, '', [ 'back_link' => true ] );
	}

	/**
	 * Fix meta key typo error
	 *
	 * @return bool|int
	 */
	public function fix_meta_key_typo_error() {
		$ids = static::get_sliders_ids();
		if ( count( $ids ) ) {
			global $wpdb;
			$sql  = "UPDATE {$wpdb->postmeta} SET `meta_key`= '_infinity_loop' WHERE `meta_key` = '_inifnity_loop'";
			$sql .= ' AND post_id IN(' . implode( ',', $ids ) . ')';

			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
			return $wpdb->query( $sql );
		}

		return false;
	}

	/**
	 * Fix meta key typo error
	 *
	 * @return bool|int
	 */
	public function fix_product_query_type_typo_error() {
		$ids = static::get_sliders_ids();
		if ( count( $ids ) ) {
			global $wpdb;
			$sql  = "UPDATE {$wpdb->postmeta} SET `meta_value`= 'query_product' WHERE `meta_value` = 'query_porduct'";
			$sql .= " AND `meta_key` = '_product_query_type' AND post_id IN(" . implode( ',', $ids ) . ')';

			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
			return $wpdb->query( $sql );
		}

		return false;
	}

	/**
	 * Get sliders ids
	 *
	 * @return int[]
	 */
	public static function get_sliders_ids(): array {
		global $wpdb;
		$sql = $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s", CAROUSEL_SLIDER_POST_TYPE );
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		$results = $wpdb->get_results( $sql, ARRAY_A );
		$ids     = [];
		foreach ( $results as $result ) {
			$ids[] = intval( $result['ID'] );
		}

		return $ids;
	}
}
includes/Admin/MetaBoxConfig.php000064400000047300151727276450012624 0ustar00<?php

namespace CarouselSlider\Admin;

use CarouselSlider\Helper;
use CarouselSlider\Supports\Sanitize;
use WP_Post;

/**
 * MetaBoxConfig class
 */
class MetaBoxConfig {

	/**
	 * Get hook args
	 *
	 * @return array
	 */
	public static function get_args(): array {
		global $post;
		$data = [
			'id'   => 0,
			'type' => '',
		];
		if ( $post instanceof WP_Post ) {
			$slide_type = get_post_meta( $post->ID, '_slide_type', true );

			$data['id']   = $post->ID;
			$data['type'] = array_key_exists( $slide_type, Helper::get_slide_types() ) ? $slide_type : '';
		}

		return $data;
	}

	/**
	 * Get sections
	 *
	 * @return array[]
	 */
	public static function get_sections_settings(): array {
		return [
			'section_general_settings'    => [
				'hook'  => 'metabox_general_settings',
				'id'    => 'section_general_settings',
				'label' => __( 'General Settings', 'carousel-slider' ),
			],
			'section_navigation_settings' => [
				'hook'  => 'metabox_navigation_settings',
				'id'    => 'section_navigation_settings',
				'label' => __( 'Navigation Settings', 'carousel-slider' ),
			],
			'section_pagination_settings' => [
				'hook'  => 'metabox_pagination_settings',
				'id'    => 'section_pagination_settings',
				'label' => __( 'Pagination Settings', 'carousel-slider' ),
			],
			'section_autoplay_settings'   => [
				'hook'  => 'metabox_autoplay_settings',
				'id'    => 'section_autoplay_settings',
				'label' => __( 'Autoplay Settings', 'carousel-slider' ),
			],
			'section_color_settings'      => [
				'hook'  => 'metabox_color_settings',
				'id'    => 'section_color_settings',
				'label' => __( 'Color Settings', 'carousel-slider' ),
			],
		];
	}

	/**
	 * Get all settings
	 *
	 * @return array
	 */
	public static function get_fields_settings(): array {
		$settings = array_merge(
			self::get_general_settings(),
			self::get_navigation_settings(),
			self::get_pagination_settings(),
			self::get_autoplay_settings(),
			self::get_color_settings()
		);

		return apply_filters( 'carousel_slider/admin/metabox_config', $settings, self::get_args() );
	}

	/**
	 * Get general settings
	 *
	 * @return array
	 */
	public static function get_general_settings(): array {
		$settings = [
			'image_size'       => [
				'section'     => 'section_general_settings',
				'default'     => 'medium_large',
				'id'          => '_image_size',
				'label'       => esc_html__( 'Carousel Image size', 'carousel-slider' ),
				'description' => sprintf(
				/* translators: 1: setting media page link start, 2: setting media page link end */
					esc_html__( 'Choose "original uploaded image" for full size image or your desired image size for carousel image. You can change the default size for thumbnail, medium and large from %1$s Settings >> Media %2$s.', 'carousel-slider' ),
					'<a target="_blank" href="' . admin_url( 'options-media.php' ) . '">',
					'</a>'
				),
				'type'        => 'image_sizes',
			],
			'space_between'    => [
				'section'     => 'section_general_settings',
				'type'        => 'number',
				'id'          => '_margin_right',
				'label'       => esc_html__( 'Item Spacing.', 'carousel-slider' ),
				'description' => esc_html__( 'Space between two slide. Enter 10 for 10px', 'carousel-slider' ),
				'default'     => Helper::get_default_setting( 'margin_right' ),
			],
			'stage_padding'    => [
				'section'     => 'section_general_settings',
				'type'        => 'number',
				'id'          => '_stage_padding',
				'label'       => esc_html__( 'Stage Padding', 'carousel-slider' ),
				'description' => esc_html__( 'Add left and right padding on carousel slider stage wrapper.', 'carousel-slider' ),
				'default'     => 0,
			],
			'lazy_load'        => [
				'section'     => 'section_general_settings',
				'type'        => 'switch',
				'id'          => '_lazy_load_image',
				'label'       => esc_html__( 'Lazy Loading', 'carousel-slider' ),
				'description' => esc_html__( 'Enable image with lazy loading.', 'carousel-slider' ),
				'default'     => Helper::get_default_setting( 'lazy_load_image' ),
			],
			'loop'             => [
				'section'     => 'section_general_settings',
				'type'        => 'switch',
				'id'          => '_infinity_loop',
				'label'       => esc_html__( 'Infinity loop', 'carousel-slider' ),
				'description' => esc_html__( 'Enable or disable loop(circular) of carousel.', 'carousel-slider' ),
				'default'     => 'on',
			],
			'type_of_slider'   => [
				'section'     => 'section_general_settings',
				'type'        => 'button_group',
				'id'          => '_type_of_slider',
				'label'       => esc_html__( 'Slider Type', 'carousel-slider' ),
				'description' => esc_html__( 'Choose slider if you want to display one image/slide at a time. Choose carousel if you want to display multiple images/slides at a time.', 'carousel-slider' ),
				'default'     => 'carousel',
				'choices'     => [
					[
						'value' => 'carousel',
						'label' => esc_html__( 'Carousel', 'carousel-slider' ),
					],
					[
						'value' => 'slider',
						'label' => esc_html__( 'Slider', 'carousel-slider' ),
					],
				],
			],
			'auto_width'       => [
				'section'     => 'section_general_settings',
				'type'        => 'switch',
				'id'          => '_auto_width',
				'label'       => esc_html__( 'Auto Width', 'carousel-slider' ),
				'description' => esc_html__( 'Set item width according to its content width. Use width style on item to get the result you want. ', 'carousel-slider' ),
				'default'     => 'off',
				'condition'   => [
					'_type_of_slider' => 'carousel',
				],
			],
			'slides_per_view'  => [
				'section'           => 'section_general_settings',
				'type'              => 'responsive_control',
				'id'                => '_slides_per_view',
				'label'             => esc_html__( 'Slides Per View', 'carousel-slider' ),
				'description'       => esc_html__( 'Set number of slides to show per view. If you enable "Auto Width", this option will be disabled.', 'carousel-slider' ),
				'device_choices'    => [ 'xs', 'sm', 'md', 'lg', 'xl', '2xl' ],
				'default'           => [
					'xs'  => 1,
					'sm'  => 2,
					'md'  => 2,
					'lg'  => 3,
					'xl'  => 4,
					'2xl' => 5,
				],
				'condition'         => [
					'_type_of_slider' => 'carousel',
				],
				'sanitize_callback' => [ Sanitize::class, 'deep_int' ],
			],
			'slider_direction' => [
				'section'     => 'section_general_settings',
				'type'        => 'button_group',
				'id'          => '_slider_direction',
				'label'       => esc_html__( 'Slider Direction', 'carousel-slider' ),
				'description' => esc_html__( 'Choose slider direction.', 'carousel-slider' ),
				'default'     => 'horizontal',
				'pro_only'    => true,
				'choices'     => [
					[
						'value' => 'horizontal',
						'label' => esc_html__( 'Horizontal', 'carousel-slider' ),
					],
					[
						'value'    => 'vertical',
						'label'    => esc_html__( 'Vertical', 'carousel-slider' ),
						'pro_only' => true,
					],
				],
			],
			'slider_effect'    => [
				'section'     => 'section_general_settings',
				'type'        => 'button_group',
				'id'          => '_slider_effect',
				'label'       => esc_html__( 'Slider Effect', 'carousel-slider' ),
				'description' => esc_html__( 'Choose slider effect.', 'carousel-slider' ),
				'default'     => 'slide',
				'pro_only'    => true,
				'choices'     => [
					[
						'value' => 'slide',
						'label' => esc_html__( 'Slide', 'carousel-slider' ),
					],
					[
						'value'    => 'fade',
						'label'    => esc_html__( 'Fade', 'carousel-slider' ),
						'pro_only' => true,
					],
					[
						'value'    => 'cube',
						'label'    => esc_html__( 'Cube', 'carousel-slider' ),
						'pro_only' => true,
					],
					[
						'value'    => 'coverflow',
						'label'    => esc_html__( 'Coverflow', 'carousel-slider' ),
						'pro_only' => true,
					],
					[
						'value'    => 'flip',
						'label'    => esc_html__( 'Flip', 'carousel-slider' ),
						'pro_only' => true,
					],
					[
						'value'    => 'creative',
						'label'    => esc_html__( 'Creative', 'carousel-slider' ),
						'pro_only' => true,
					],
					[
						'value'    => 'cards',
						'label'    => esc_html__( 'Cards', 'carousel-slider' ),
						'pro_only' => true,
					],
				],
			],
		];

		return apply_filters( 'carousel_slider/admin/metabox_general_config', $settings, self::get_args() );
	}

	/**
	 * Get navigation settings
	 *
	 * @return array
	 */
	public static function get_navigation_settings(): array {
		$settings = [
			'nav_visibility' => [
				'section'     => 'section_navigation_settings',
				'type'        => 'button_group',
				'id'          => '_nav_button',
				'label'       => esc_html__( 'Show Navigation', 'carousel-slider' ),
				'description' => esc_html__( 'Choose when to show arrow navigator.', 'carousel-slider' ),
				'default'     => 'on',
				'choices'     => [
					'off'    => esc_html__( 'Never', 'carousel-slider' ),
					'on'     => esc_html__( 'Mouse Over', 'carousel-slider' ),
					'always' => esc_html__( 'Always', 'carousel-slider' ),
				],
			],
			'nav_steps'      => [
				'section'     => 'section_navigation_settings',
				'type'        => 'text',
				'id'          => '_slide_by',
				'label'       => esc_html__( 'Navigation Steps', 'carousel-slider' ),
				'description' => esc_html__( 'Steps to go for each navigation request. Write -1 to slide by page.', 'carousel-slider' ),
				'default'     => 1,
			],
			'nav_size'       => [
				'section'     => 'section_navigation_settings',
				'type'        => 'number',
				'id'          => '_arrow_size',
				'label'       => esc_html__( 'Navigation Size', 'carousel-slider' ),
				'description' => esc_html__( 'Enter arrow size in pixels.', 'carousel-slider' ),
				'default'     => 48,
			],
			'nav_position'   => [
				'section'     => 'section_navigation_settings',
				'type'        => 'button_group',
				'id'          => '_arrow_position',
				'label'       => esc_html__( 'Navigation Position', 'carousel-slider' ),
				'description' => esc_html__( 'Choose where to show arrow. Inside slider or outside slider.', 'carousel-slider' ),
				'default'     => Helper::is_using_swiper() ? 'inside' : 'outside',
				'choices'     => [
					[
						'value'    => 'outside',
						'label'    => esc_html__( 'Outside', 'carousel-slider' ),
						'disabled' => Helper::is_using_swiper(),
					],
					[
						'value' => 'inside',
						'label' => esc_html__( 'Inside', 'carousel-slider' ),
					],
				],
			],
		];

		return apply_filters( 'carousel_slider/admin/metabox_navigation_config', $settings, self::get_args() );
	}

	/**
	 * Get pagination settings
	 *
	 * @return array
	 */
	public static function get_pagination_settings(): array {
		$settings = [
			'pagination_visibility' => [
				'section'     => 'section_pagination_settings',
				'type'        => 'button_group',
				'id'          => '_dot_nav',
				'label'       => esc_html__( 'Show Pagination', 'carousel-slider' ),
				'description' => esc_html__( 'Choose when to show pagination.', 'carousel-slider' ),
				'default'     => 'off',
				'choices'     => [
					'off'   => esc_html__( 'Never', 'carousel-slider' ),
					'on'    => esc_html__( 'Always', 'carousel-slider' ),
					'hover' => esc_html__( 'Mouse Over', 'carousel-slider' ),
				],
			],
			'pagination_alignment'  => [
				'section'     => 'section_pagination_settings',
				'type'        => 'button_group',
				'id'          => '_bullet_position',
				'label'       => esc_html__( 'Pagination Alignment', 'carousel-slider' ),
				'description' => esc_html__( 'Choose pagination alignment.', 'carousel-slider' ),
				'default'     => 'center',
				'choices'     => [
					'left'   => esc_html__( 'Left', 'carousel-slider' ),
					'center' => esc_html__( 'Center', 'carousel-slider' ),
					'right'  => esc_html__( 'Right', 'carousel-slider' ),
				],
			],
			'pagination_size'       => [
				'section'     => 'section_pagination_settings',
				'type'        => 'number',
				'id'          => '_bullet_size',
				'label'       => esc_html__( 'Pagination Size', 'carousel-slider' ),
				'description' => esc_html__( 'Enter pagination size in pixels.', 'carousel-slider' ),
				'default'     => 10,
			],
			'pagination_shape'      => [
				'section'     => 'section_pagination_settings',
				'type'        => 'button_group',
				'id'          => '_bullet_shape',
				'label'       => esc_html__( 'Pagination Shape', 'carousel-slider' ),
				'description' => esc_html__( 'Choose pagination shape.', 'carousel-slider' ),
				'default'     => 'circle',
				'choices'     => [
					'square' => esc_html__( 'Square', 'carousel-slider' ),
					'circle' => esc_html__( 'Circle', 'carousel-slider' ),
				],
			],
		];

		$settings['pagination_position'] = [
			'section'     => 'section_pagination_settings',
			'type'        => 'button_group',
			'id'          => '_pagination_position',
			'label'       => esc_html__( 'Pagination Position', 'carousel-slider' ),
			'description' => esc_html__( 'Choose where to show pagination. Inside slider or outside slider.', 'carousel-slider' ),
			'default'     => Helper::is_using_swiper() ? 'inside' : 'outside',
			'pro_only'    => true,
			'choices'     => [
				[
					'value'    => 'outside',
					'label'    => esc_html__( 'Outside', 'carousel-slider' ),
					'disabled' => Helper::is_using_swiper(),
				],
				[
					'value' => 'inside',
					'label' => esc_html__( 'Inside', 'carousel-slider' ),
				],
			],
		];
		$settings['pagination_type']     = [
			'section'     => 'section_pagination_settings',
			'type'        => 'button_group',
			'id'          => '_pagination_type',
			'label'       => esc_html__( 'Pagination Type', 'carousel-slider' ),
			'description' => esc_html__( 'Choose pagination type.', 'carousel-slider' ),
			'default'     => 'bullets',
			'pro_only'    => true,
			'choices'     => [
				[
					'value' => 'bullets',
					'label' => esc_html__( 'Bullets', 'carousel-slider' ),
				],
				[
					'value'    => 'fraction',
					'label'    => esc_html__( 'Fraction', 'carousel-slider' ),
					'pro_only' => true,
				],
				[
					'value'    => 'progressbar',
					'label'    => esc_html__( 'progressbar', 'carousel-slider' ),
					'pro_only' => true,
				],
				[
					'value'    => 'custom',
					'label'    => esc_html__( 'custom', 'carousel-slider' ),
					'pro_only' => true,
				],
			],
		];

		return apply_filters( 'carousel_slider/admin/metabox_pagination_config', $settings, self::get_args() );
	}

	/**
	 * Get autoplay settings
	 *
	 * @return array
	 */
	public static function get_autoplay_settings(): array {
		$settings = [
			'autoplay'             => [
				'section'     => 'section_autoplay_settings',
				'type'        => 'switch',
				'id'          => '_autoplay',
				'label'       => esc_html__( 'AutoPlay', 'carousel-slider' ),
				'description' => esc_html__( 'Choose whether slideshow should play automatically.', 'carousel-slider' ),
				'default'     => 'on',
			],
			'autoplay_hover_pause' => [
				'section'     => 'section_autoplay_settings',
				'type'        => 'switch',
				'id'          => '_autoplay_pause',
				'label'       => esc_html__( 'Pause On Hover', 'carousel-slider' ),
				'description' => esc_html__( 'Pause automatic play on mouse hover.', 'carousel-slider' ),
				'default'     => 'on',
			],
			'autoplay_delay'       => [
				'section'     => 'section_autoplay_settings',
				'type'        => 'number',
				'id'          => '_autoplay_timeout',
				'label'       => esc_html__( 'Autoplay Timeout', 'carousel-slider' ),
				'description' => esc_html__( 'Automatic play interval timeout in millisecond.', 'carousel-slider' ),
				'default'     => 5000,
			],
			'autoplay_speed'       => [
				'section'     => 'section_autoplay_settings',
				'type'        => 'number',
				'id'          => '_autoplay_speed',
				'label'       => esc_html__( 'Autoplay Speed', 'carousel-slider' ),
				'description' => esc_html__( 'Automatic play speed in millisecond.', 'carousel-slider' ),
				'default'     => 500,
			],
		];

		return apply_filters( 'carousel_slider/admin/metabox_autoplay_config', $settings, self::get_args() );
	}

	/**
	 * Get color settings
	 *
	 * @return array
	 */
	public static function get_color_settings(): array {
		$settings = [
			'nav_color'        => [
				'section'     => 'section_color_settings',
				'type'        => 'color',
				'id'          => '_nav_color',
				'label'       => esc_html__( 'Navigation & Pagination Color', 'carousel-slider' ),
				'description' => esc_html__( 'Set theme color to use with navigation and pagination.', 'carousel-slider' ),
				'default'     => Helper::get_default_setting( 'nav_color' ),
			],
			'nav_active_color' => [
				'section'     => 'section_color_settings',
				'type'        => 'color',
				'id'          => '_nav_active_color',
				'label'       => esc_html__( 'Navigation & Pagination Hover Color', 'carousel-slider' ),
				'description' => esc_html__( 'Set theme color for hover and active state to use with navigation and pagination.', 'carousel-slider' ),
				'default'     => Helper::get_default_setting( 'nav_active_color' ),
			],
		];

		return apply_filters( 'carousel_slider/admin/metabox_color_config', $settings, self::get_args() );
	}

	/**
	 * Get responsive settings
	 *
	 * @return array
	 */
	public static function get_responsive_settings(): array {
		$settings = [
			'items_on_fullhd'       => [
				'section'     => 'section_responsive_settings',
				'type'        => 'number',
				'id'          => '_items',
				'label'       => esc_html__( 'Columns: Full HD', 'carousel-slider' ),
				'description' => esc_html__( 'The number of items you want to see on the Extra Large Desktop Layout (Screens size greater than 1921 pixels DP)', 'carousel-slider' ),
				'default'     => 4,
			],
			'items_on_widescreen'   => [
				'section'     => 'section_responsive_settings',
				'type'        => 'number',
				'id'          => '_items_desktop',
				'label'       => esc_html__( 'Columns : Desktop', 'carousel-slider' ),
				'description' => esc_html__( 'The number of items you want to see on the Desktop Layout (Screens size from 1200 pixels DP to 1920 pixels DP)', 'carousel-slider' ),
				'default'     => 4,
			],
			'items_on_desktop'      => [
				'section'     => 'section_responsive_settings',
				'type'        => 'number',
				'id'          => '_items_small_desktop',
				'label'       => esc_html__( 'Columns : Small Desktop', 'carousel-slider' ),
				'description' => esc_html__( 'The number of items you want to see on the Small Desktop Layout (Screens size from 993 pixels DP to 1199 pixels DP)', 'carousel-slider' ),
				'default'     => 3,
			],
			'items_on_tablet'       => [
				'section'     => 'section_responsive_settings',
				'type'        => 'number',
				'id'          => '_items_portrait_tablet',
				'label'       => esc_html__( 'Columns : Tablet', 'carousel-slider' ),
				'description' => esc_html__( 'The number of items you want to see on the Tablet Layout (Screens size from 768 pixels DP to 992 pixels DP)', 'carousel-slider' ),
				'default'     => 2,
			],
			'items_on_small_tablet' => [
				'section'     => 'section_responsive_settings',
				'type'        => 'number',
				'id'          => '_items_small_portrait_tablet',
				'label'       => esc_html__( 'Columns : Small Tablet', 'carousel-slider' ),
				'description' => esc_html__( 'The number of items you want to see on the Small Tablet Layout(Screens size from 600 pixels DP to 767 pixels DP)', 'carousel-slider' ),
				'default'     => 2,
			],
			'items_on_mobile'       => [
				'section'     => 'section_responsive_settings',
				'type'        => 'number',
				'id'          => '_items_portrait_mobile',
				'label'       => esc_html__( 'Columns : Mobile', 'carousel-slider' ),
				'description' => esc_html__( 'The number of items you want to see on the Mobile Layout (Screens size from 320 pixels DP to 599 pixels DP)', 'carousel-slider' ),
				'default'     => 1,
			],
		];

		return apply_filters( 'carousel_slider/admin/metabox_responsive_config', $settings, self::get_args() );
	}
}
includes/Admin/MetaBox.php000064400000026015151727276450011476 0ustar00<?php
/**
 * The slider meta box specific file of the plugin
 *
 * @package CarouselSlider/Admin
 */

namespace CarouselSlider\Admin;

use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\Helper;
use CarouselSlider\Supports\MetaBoxForm;
use WP_Post;

defined( 'ABSPATH' ) || exit;

/**
 * MetaBox class
 */
class MetaBox {

    /**
     * The instance of the class
     *
     * @var self
     */
    private static $instance = null;

    /**
     * Ensures only one instance of this class is loaded or can be loaded.
     *
     * @return MetaBox
     */
    public static function init() {
        if ( is_null( self::$instance ) ) {
            self::$instance = new self();

            add_action( 'add_meta_boxes', array( self::$instance, 'add_meta_boxes' ), 10, 2 );
            add_action( 'save_post', array( self::$instance, 'save_meta_box' ) );
        }

        return self::$instance;
    }

    /**
     * Save custom meta-box
     *
     * @param  int  $post_id  The WP_Post ID.
     */
    public function save_meta_box( int $post_id ) {
        // Check if the user has permissions to save data.
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            return;
        }

        if ( ! current_user_can( 'edit_post', $post_id ) ) {
            return;
        }

        $raw_data        = wp_unslash( $_POST );
        $nonce           = isset( $raw_data['_carousel_slider_nonce'] ) ? sanitize_text_field( $raw_data['_carousel_slider_nonce'] ) : '';
        $slider_settings = $raw_data['carousel_slider'] ?? [];

        if ( wp_verify_nonce( $nonce, 'carousel_slider_nonce' ) ) {
            $slider_type = get_post_meta( $post_id, '_slide_type', true );

            if ( apply_filters( 'carousel_slider/save_common_settings', true ) ) {
                $settings = new SliderSetting( $post_id, false );
                $settings->get_slider_type();
                $settings->read_http_post_variables( $slider_settings );
                $settings->write_metadata();
            }

            update_post_meta( $post_id, '_carousel_slider_version', CAROUSEL_SLIDER_VERSION );

            /**
             * Fires once a post has been saved.
             *
             * @param  int  $post_id  Slider post ID.
             * @param  array  $_POST  User submitted data.
             */
            do_action( "carousel_slider/save_slider/{$slider_type}", $post_id, $raw_data );

            /**
             * Fires once a post has been saved.
             *
             * @param  int  $post_id  Slider post ID.
             * @param  array  $_POST  User submitted data.
             * @param  string  $slider_type  Slider type.
             */
            do_action( 'carousel_slider/save_slider', $post_id, $raw_data, $slider_type );
        }
    }

    /**
     * Add carousel slider meta-box
     *
     * @param  string  $post_type  The post-type.
     * @param  WP_Post  $post  The WP_Post object.
     */
    public function add_meta_boxes( $post_type, $post ) {
        if ( CAROUSEL_SLIDER_POST_TYPE !== $post_type ) {
            return;
        }

        $slide_type = get_post_meta( $post->ID, '_slide_type', true );
        if ( empty( $slide_type ) ) {
            add_meta_box(
                    'carousel-slider-slide-types',
                    __( 'Slider Type', 'carousel-slider' ),
                    [ $this, 'carousel_slider_slide_types' ],
                    CAROUSEL_SLIDER_POST_TYPE,
                    'normal',
                    'high'
            );

            return;
        }

        $slide_types = Helper::get_slide_types();

        $meta_boxes = [
                'carousel-slider-meta-boxes' => [
                        'title'    => sprintf(
                        /* translators: 1 - Slider type label */
                                __( 'Carousel Slider : %s', 'carousel-slider' ),
                                $slide_types[ $slide_type ] ?? ''
                        ),
                        'callback' => [ $this, 'carousel_slider_meta_boxes' ],
                        'context'  => 'normal',
                        'priority' => 'high',
                ],
                'carousel-slider-settings'   => [
                        'title'    => __( 'Slider Settings', 'carousel-slider' ),
                        'callback' => [ $this, 'carousel_slider_settings' ],
                        'context'  => 'normal',
                        'priority' => 'low',
                ],
                'carousel-slider-usages'     => [
                        'title'    => __( 'Usage', 'carousel-slider' ),
                        'callback' => [ $this, 'usages_callback' ],
                        'priority' => 'low',
                ],
        ];
        foreach ( $meta_boxes as $id => $meta_box ) {
            add_meta_box(
                    $id,
                    $meta_box['title'],
                    $meta_box['callback'],
                    CAROUSEL_SLIDER_POST_TYPE,
                    'normal',
                    'low'
            );
        }
    }

    /**
     * Render short code meta-box content
     *
     * @param  WP_Post  $post  The WP_Post object.
     */
    public function usages_callback( WP_Post $post ) {
        $shortcode    = sprintf( '[carousel_slide id="%s"]', absint( $post->ID ) );
        $shortcode_in = sprintf( 'echo do_shortcode( \'[carousel_slide id="%s"]\' );', absint( $post->ID ) );
        ob_start();
        ?>
        <div class="shapla-columns">
            <div class="shapla-column is-6-tablet">
                <strong><?php esc_html_e( 'Shortcode:', 'carousel-slider' ); ?></strong>
                <div
                        class="input-copy-to-clipboard"><?php Helper::print_unescaped_internal_string( $shortcode ); ?></div>
            </div>
            <div class="shapla-column is-6-tablet">
                <strong><?php esc_html_e( 'Template Include:', 'carousel-slider' ); ?></strong>
                <div
                        class="input-copy-to-clipboard"><?php Helper::print_unescaped_internal_string( $shortcode_in ); ?></div>
            </div>
        </div>
        <?php
        Helper::print_unescaped_internal_string( ob_get_clean() );
        ?>
        <div>
            <a class="button button-primary button-cs-preview hidden" id="carousel-slider-update-preview"
               data-id="<?php echo esc_attr( $post->ID ); ?>" href="#">
                <span class="button-cs-preview__icon dashicons dashicons-image-rotate"></span>
                <span class="button-cs-preview__label">Update Preview</span>
            </a>
            <a class="button button-primary button-cs-preview hidden" id="carousel-slider-hide-preview"
               data-id="<?php echo esc_attr( $post->ID ); ?>" href="#">
                <span class="button-cs-preview__icon dashicons dashicons-hidden"></span>
                <span class="button-cs-preview__label">Hide Preview</span>
            </a>
            <a class="button button-primary button-cs-preview" id="carousel-slider-show-preview"
               data-id="<?php echo esc_attr( $post->ID ); ?>" href="#">
                <span class="button-cs-preview__icon dashicons dashicons-visibility"></span>
                <span class="button-cs-preview__label">Show Preview</span>
            </a>
        </div>
        <?php
    }

    /**
     * Post-type metabox.
     *
     * @return void
     */
    public function carousel_slider_slide_types() {
        wp_nonce_field( 'carousel_slider_nonce', '_carousel_slider_nonce' );
        $slide_types = Helper::get_slider_types();
        $html        = '<div class="carousel-slider-slider-type-container">';
        $html        .= '<div class="shapla-columns is-multiline">';
        foreach ( $slide_types as $slug => $args ) {
            $id    = sprintf( '_slide_type__%s', $slug );
            $attrs = [
                    'type'  => 'radio',
                    'name'  => 'carousel_slider[_slide_type]',
                    'id'    => $id,
                    'class' => 'screen-reader-text',
                    'value' => $slug,
            ];

            if ( false === $args['enabled'] ) {
                $attrs['disabled'] = true;
            }

            $is_pro = isset( $args['pro'] ) && true === $args['pro'];

            $html .= '<div class="shapla-column is-6-tablet is-4-desktop is-3-fullhd">';
            $html .= '<input ' . implode( ' ', Helper::array_to_attribute( $attrs ) ) . '>';
            $html .= '<label for="' . esc_attr( $id ) . '" class="option-slider-type">';
            $html .= '<span class="option-slider-type__content">';
            if ( isset( $args['icon'] ) ) {
                $html .= '<span class="option-slider-type__icon">' . $args['icon'] . '</span>';
            }
            $html .= '<span class="option-slider-type__label">' . esc_html( $args['label'] ) . '</span>';
            if ( $is_pro ) {
                $html .= '<span class="option-slider-type__pro">' . esc_html__( 'Pro', 'carousel-slider' ) . '</span>';
            }
            $html .= '</span>';
            $html .= '</label>';
            $html .= '</div>';
        }
        $html .= '</div>';
        $html .= '</div>';

        Helper::print_unescaped_internal_string( $html );
    }

    /**
     * Get slider settings
     *
     * @return void
     */
    public function carousel_slider_settings() {
        $sections = MetaBoxConfig::get_sections_settings();
        $fields   = MetaBoxConfig::get_fields_settings();

        $html = '<div class="shapla-section shapla-tabs shapla-tabs--normal">';
        $html .= '<div class="shapla-tab-inner">';
        $html .= '<ul class="shapla-nav shapla-clearfix">';
        foreach ( $sections as $section ) {
            $html .= '<li><a href="#' . esc_attr( $section['id'] ) . '">' . esc_html( $section['label'] ) . '</a></li>';
        }
        $html .= '</ul>';
        foreach ( $sections as $section ) {
            $html .= '<div id="' . esc_attr( $section['id'] ) . '" class="shapla-tab tab-content">';

            $section_html = '';
            foreach ( $fields as $field ) {
                if ( $field['section'] === $section['id'] ) {
                    $section_html .= MetaBoxForm::field( $field );
                }
            }

            $html .= apply_filters( 'carousel_slider/admin/' . $section['hook'], $section_html );
            $html .= '</div>';
        }
        $html .= '</div>';
        $html .= '</div>';

        Helper::print_unescaped_internal_string( $html );
    }

    /**
     * Load meta box content
     *
     * @param  WP_Post  $post  The WP_Post object.
     */
    public function carousel_slider_meta_boxes( WP_Post $post ) {
        wp_nonce_field( 'carousel_slider_nonce', '_carousel_slider_nonce' );

        $slide_type = get_post_meta( $post->ID, '_slide_type', true );
        $slide_type = array_key_exists( $slide_type, Helper::get_slide_types() ) ? $slide_type : 'image-carousel';

        do_action( 'carousel_slider/meta_box_content/' . $slide_type, $post->ID );
        /**
         * Allow third-party plugin to add custom fields
         */
        do_action( 'carousel_slider/meta_box_content', $post->ID, $slide_type );
    }
}
includes/Admin/Admin.php000064400000031126151727276450011166 0ustar00<?php

namespace CarouselSlider\Admin;

use CarouselSlider\Helper;
use WP_Post;

defined( 'ABSPATH' ) || exit;

/**
 * Admin class
 * The admin-functionality-specific class of the plugin
 *
 * @package CarouselSlider/Admin
 */
class Admin {

    const POST_TYPE = 'carousels';

    /**
     * The instance of the class
     *
     * @var self
     */
    protected static $instance;

    /**
     * Ensures only one instance of the class is loaded or can be loaded.
     *
     * @return self
     */
    public static function init() {
        if ( is_null( self::$instance ) ) {
            self::$instance = new self();

            // Modify carousel slider list table columns.
            add_filter( 'manage_edit-' . self::POST_TYPE . '_columns', [ self::$instance, 'columns_head' ] );
            add_filter(
                    'manage_' . self::POST_TYPE . '_posts_custom_column',
                    [ self::$instance, 'columns_content' ],
                    10,
                    2
            );
            // Remove view and Quick Edit from Carousels.
            add_filter( 'post_row_actions', [ self::$instance, 'post_row_actions' ], 10, 2 );
            add_filter( 'preview_post_link', [ self::$instance, 'preview_post_link' ], 10, 2 );

            add_action( 'admin_enqueue_scripts', [ self::$instance, 'admin_scripts' ], 10 );
            add_action( 'admin_menu', [ self::$instance, 'documentation_menu' ] );
            add_filter( 'admin_footer_text', [ self::$instance, 'admin_footer_text' ] );
            add_filter(
                    'plugin_action_links_' . plugin_basename( CAROUSEL_SLIDER_FILE ),
                    [ self::$instance, 'action_links' ]
            );

            add_filter( 'plugin_row_meta', [ self::$instance, 'plugin_row_meta' ], 10, 2 );
        }

        return self::$instance;
    }

    /**
     * Add custom links on the plugin page.
     *
     * @param  array  $links  An array of plugin action links.
     *
     * @return array
     */
    public function action_links( $links ) {
        $setting_url  = admin_url( 'edit.php?post_type=carousels&page=settings' );
        $plugin_links = [
                '<a href="' . $setting_url . '">' . __( 'Settings', 'carousel-slider' ) . '</a>',
        ];

        return array_merge( $plugin_links, $links );
    }

    /**
     * Filters the array of row meta for the plugin in the Plugins list table.
     *
     * @param  string[]  $plugin_meta  An array of the plugin's metadata, including
     *                             the version, author, author URI, and plugin URI.
     * @param  string  $plugin_file  Path to the plugin file relative to the plugins directory.
     *
     * @return array
     */
    public function plugin_row_meta( $plugin_meta, $plugin_file ) {
        if ( plugin_basename( CAROUSEL_SLIDER_FILE ) === $plugin_file ) {
            $plugin_meta[] = '<a href="https://wordpress.org/support/plugin/carousel-slider" target="_blank">' . __(
                            'Community support',
                            'carousel-slider'
                    ) . '</a>';
        }

        return $plugin_meta;
    }

    /**
     * Modify a preview post-link for the carousel slider
     *
     * @param  string  $preview_link  The preview link.
     * @param  WP_Post  $post  The WP_Post object.
     *
     * @return string
     */
    public function preview_post_link( string $preview_link, WP_Post $post ): string {
        if ( self::POST_TYPE === $post->post_type ) {
            $preview_link = Helper::get_preview_link( $post );
        }

        return $preview_link;
    }

    /**
     * Customize the Carousel slider list table head
     *
     * @return array A list of column headers.
     */
    public function columns_head(): array {
        return [
                'cb'         => '<input type="checkbox">',
                'title'      => __( 'Carousel Slide Title', 'carousel-slider' ),
                'usage'      => __( 'Shortcode', 'carousel-slider' ),
                'slide_type' => __( 'Slide Type', 'carousel-slider' ),
        ];
    }

    /**
     * Generate carousel slider list table content for each custom column
     *
     * @param  string  $column_name  The name of the column to display.
     * @param  int  $post_id  The current WP_Post ID.
     *
     * @return void
     */
    public function columns_content( string $column_name, int $post_id ) {
        $slide_types = Helper::get_slide_types();
        switch ( $column_name ) {

            case 'usage':
                ?>
                <label class="screen-reader-text" for="carousel_slider_usage_<?php echo esc_attr( $post_id ); ?>">
                    Copy shortcode
                </label>
                <input
                        id="carousel_slider_usage_<?php echo esc_attr( $post_id ); ?>"
                        type="text"
                        onmousedown="this.clicked = 1;"
                        onfocus="if (!this.clicked) this.select(); else this.clicked = 2;"
                        onclick="if (this.clicked === 2) this.select(); this.clicked = 0;"
                        value="[carousel_slide id='<?php echo esc_attr( $post_id ); ?>']"
                        style="background-color: #f1f1f1;min-width: 250px;padding: 5px 8px;"
                >
                <?php
                break;

            case 'slide_type':
                $slide_type = get_post_meta( $post_id, '_slide_type', true );
                echo isset( $slide_types[ $slide_type ] ) ? esc_attr( $slide_types[ $slide_type ] ) : '';

                break;
            default:
                break;
        }
    }

    /**
     * Hide view and quick edit from carousel slider admin
     *
     * @param  array  $actions  The post-row actions list.
     * @param  WP_Post  $post  The WP_Post object.
     *
     * @return array
     */
    public function post_row_actions( array $actions, WP_Post $post ): array {
        if ( self::POST_TYPE !== $post->post_type ) {
            return $actions;
        }

        $view_url        = Helper::get_preview_link( $post );
        $actions['view'] = '<a href="' . $view_url . '" target="_blank">' . esc_html__(
                        'Preview',
                        'carousel-slider'
                ) . '</a>';

        unset( $actions['inline hide-if-no-js'] );

        return $actions;
    }

    /**
     * Load admin scripts
     *
     * @param  string|mixed  $hook  Page hook.
     */
    public function admin_scripts( $hook ) {
        global $post;

        $_is_carousel    = is_a( $post, 'WP_Post' ) && ( CAROUSEL_SLIDER_POST_TYPE === $post->post_type );
        $_is_doc         = ( 'carousels_page_carousel-slider-documentation' === $hook );
        $_is_settings    = ( 'carousels_page_settings' === $hook );
        $_is_plugin_page = 'plugins.php' === $hook;

        if ( ! ( $_is_carousel || $_is_doc || $_is_plugin_page || $_is_settings ) ) {
            // Load the 'add new carousel' script and style on every page of admin.
            wp_enqueue_script( 'carousel-slider-admin-new-carousel' );
            wp_enqueue_style( 'carousel-slider-admin-new-carousel' );

            return;
        }

        wp_enqueue_media();
        wp_enqueue_style( 'carousel-slider-admin' );
        wp_enqueue_script( 'carousel-slider-admin' );
        wp_localize_script(
                'carousel-slider-admin',
                'CarouselSliderAdminL10n',
                [
                        'url'           => esc_html__( 'URL', 'carousel-slider' ),
                        'title'         => esc_html__( 'Title', 'carousel-slider' ),
                        'caption'       => esc_html__( 'Caption', 'carousel-slider' ),
                        'altText'       => esc_html__( 'Alt Text', 'carousel-slider' ),
                        'linkToUrl'     => esc_html__( 'Link To URL', 'carousel-slider' ),
                        'addNew'        => esc_html__( 'Add New Item', 'carousel-slider' ),
                        'moveCurrent'   => esc_html__( 'Move Current Item', 'carousel-slider' ),
                        'deleteCurrent' => esc_html__( 'Delete Current Item', 'carousel-slider' ),
                        'videoCarousel' => [
                                'YoutubeOrVimeoURL'  => esc_html__( 'Youtube or Vimeo URL', 'carousel-slider' ),
                                'AreYouSureToDelete' => esc_html__( 'Are you sure to delete?', 'carousel-slider' ),
                        ],
                ]
        );
    }

    /**
     * Add documentation menu
     */
    public function documentation_menu() {
        add_submenu_page(
                'edit.php?post_type=carousels',
                __( 'Documentation', 'carousel-slider' ),
                __( 'Documentation', 'carousel-slider' ),
                'manage_options',
                'carousel-slider-documentation',
                [ $this, 'documentation_page_callback' ]
        );
    }

    /**
     * Documentation page callback
     */
    public function documentation_page_callback() {
        $items = [
                [
                        'youtube_id' => '_hVsamgr1k4',
                        'title'      => __( 'Hero Image Carousel', 'carousel-slider' ),
                ],
                [
                        'youtube_id' => 'UOYK79yVrJ4',
                        'title'      => __( 'Image carousel (gallery images)', 'carousel-slider' ),
                ],
                [
                        'youtube_id' => 'a7hqn1yNzwM',
                        'title'      => __( 'Image carousel (custom URLs)', 'carousel-slider' ),
                ],
                [
                        'youtube_id' => 'ImJB946azy0',
                        'title'      => __( 'Posts Carousel', 'carousel-slider' ),
                ],
                [
                        'youtube_id' => 'yiAkvXyfakg',
                        'title'      => __( 'WooCommerce Product Carousel', 'carousel-slider' ),
                ],
                [
                        'youtube_id' => 'kYgp6wp27lM',
                        'title'      => __( 'In Widget Areas', 'carousel-slider' ),
                ],
                [
                        'youtube_id' => '-OaYQZfr1RM',
                        'title'      => __( 'With Page Builder by SiteOrigin', 'carousel-slider' ),
                ],
                [
                        'youtube_id' => '4LhDXH81whk',
                        'title'      => __( 'With Visual Composer Website Builder', 'carousel-slider' ),
                ],
        ];
        $html  = '<div class="wrap">';
        $html  .= '<h1 class="wp-heading">' . esc_html__(
                        'Carousel Slider Documentation',
                        'carousel-slider'
                ) . '</h1>';
        $html  .= '<div class="clear"></div>';
        $html  .= '<div class="postbox"><div class="inside">';
        $html  .= '<div class="carousel_slider_columns">';
        foreach ( $items as $item ) {
            $html .= '<div class="carousel_slider_column">';
            $html .= '<div class="carousel_slider_iframe">';
            $html .= sprintf(
                    '<iframe width="1280" height="720" src="https://www.youtube.com/embed/%s" allowfullscreen></iframe>',
                    $item['youtube_id']
            );
            $html .= '</div>';
            if ( ! empty( $item['title'] ) ) {
                $html .= '<label>' . esc_html( $item['title'] ) . '</label>';
            }
            if ( ! empty( $item['description'] ) ) {
                $html .= '<p class="description">' . esc_html( $item['description'] ) . '</p>';
            }
            $html .= '</div>';
        }
        $html .= '</div>';
        $html .= '</div></div>';
        $html .= '</div>';
        echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }

    /**
     * Add custom footer text on plugins page.
     *
     * @param  string|null  $text  The custom admin footer text.
     *
     * @return string|null Admin footer text
     */
    public function admin_footer_text( $text ) {
        global $post_type, $hook_suffix;

        $footer_text = sprintf(
        /* translators: 1: plugin review page link */
                __(
                        'If you like <strong>Carousel Slider</strong> please leave us a %s rating. A huge thanks in advance!',
                        'carousel-slider'
                ),
                '<a href="https://wordpress.org/support/view/plugin-reviews/carousel-slider?filter=5#postform" target="_blank" data-rated="Thanks :)">&starf;&starf;&starf;&starf;&starf;</a>'
        );

        if ( 'carousels' === $post_type || 'carousels_page_carousel-slider-documentation' === $hook_suffix ) {
            return $footer_text;
        }

        return $text;
    }
}
includes/Admin/Setting.php000064400000014313151727276450011552 0ustar00<?php

namespace CarouselSlider\Admin;

use CarouselSlider\Helper;
use CarouselSlider\Supports\SettingApi\DefaultSettingApi;
use Exception;

defined( 'ABSPATH' ) || exit;

/**
 * Setting class to register global setting.
 *
 * @package CarouselSlider/Admin
 */
class Setting {
	/**
	 * Instance of the current class
	 *
	 * @var self
	 */
	private static $instance;

	/**
	 * The only one instance of the class can be loaded
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			self::$instance->settings();
		}

		return self::$instance;
	}

	/**
	 * Get option
	 *
	 * @param  string $key  option key.
	 * @param  mixed  $default_value  default value.
	 *
	 * @return mixed
	 */
	public static function get_option( string $key, $default_value = '' ) {
		$default_args = array(
			'load_scripts'                        => 'optimized',
			'show_structured_data'                => 'on',
			'woocommerce_shop_loop_item_template' => 'v1-compatibility',
		);
		$options      = wp_parse_args( get_option( 'carousel_slider_settings', array() ), $default_args );

		return $options[ $key ] ?? $default_value;
	}

	/**
	 * Plugin setting fields
	 *
	 * @throws Exception It throws an exception if you don't set name and id field.
	 */
	public function settings() {
		$settings = new DefaultSettingApi();
		$settings->add_menu(
			array(
				'page_title'  => __( 'Carousel Slider Settings', 'carousel-slider' ),
				'menu_title'  => __( 'Settings', 'carousel-slider' ),
				'about_text'  => __(
					'Thank you for choosing Carousel Slider. We hope you enjoy it!',
					'carousel-slider'
				),
				'menu_slug'   => 'settings',
				'parent_slug' => 'edit.php?post_type=carousels',
				'option_name' => 'carousel_slider_settings',
			)
		);

		// Add settings page tab.
		$settings->set_panel(
			array(
				'id'       => 'general',
				'title'    => __( 'General', 'carousel-slider' ),
				'priority' => 10,
			)
		);
		$settings->set_panel(
			array(
				'id'       => 'woocommerce',
				'title'    => __( 'WooCommerce', 'carousel-slider' ),
				'priority' => 20,
			)
		);

		$settings->add_field(
			array(
				'id'          => 'load_scripts',
				'type'        => 'radio',
				'default'     => 'optimized',
				'title'       => __( 'Style & Scrips', 'carousel-slider' ),
				'description' => __(
					'If you choose <strong>Optimized</strong>, then scrips and styles will be loaded only on the page where
 				you are using shortcode. If <strong>Optimized</strong> is not working for you, then choose
 				<strong>Optimized with style loader</strong>. Then it will add a small JavaScript at footer to load the CSS
 				 file in the header. If none of these is not working for you, then choose <strong>Always</strong>',
					'carousel-slider'
				),
				'choices'     => array(
					'optimized'        => __( 'Optimized (recommended)', 'carousel-slider' ),
					'optimized-loader' => __( 'Optimized with style loader', 'carousel-slider' ),
					'always'           => __( 'Always', 'carousel-slider' ),
				),
				'panel'       => 'general',
				'priority'    => 10,
			)
		);
		$settings->add_field(
			array(
				'id'          => 'slider_js_package',
				'type'        => 'radio',
				'default'     => 'owl.carousel',
				'title'       => __( 'Slider JavaScript package', 'carousel-slider' ),
				'description' => __(
					'<strong>Swiper</strong>, is the most modern mobile touch slider without any third party dependencies.
 					<strong>Owl Carousel 2</strong> was great, but now it is <strong>PRETTY MUCH DEAD</strong> as there is
 					no development after Nov 12, 2018',
					'carousel-slider'
				),
				'choices'     => array(
					array(
						'value' => 'owl.carousel',
						'label' => __( 'Owl Carousel 2 + Magnific Popup', 'carousel-slider' ),
					),
					array(
						'value' => 'swiper',
						'label' => __( 'Swiper (experimental)', 'carousel-slider' ),
					),
				),
				'panel'       => 'general',
				'priority'    => 20,
			)
		);
		$settings->add_field(
			array(
				'id'          => 'show_structured_data',
				'type'        => 'switch',
				'default'     => 'on',
				'title'       => __( 'Show Structured Data', 'carousel-slider' ),
				'description' => __(
					'If you enable to show, then it will generate structured data for every slider for better SEO.
					But if you are using some other SEO plugin to handle SEO, then you can disabled it.',
					'carousel-slider'
				),
				'panel'       => 'general',
				'priority'    => 30,
			)
		);

		$choices = array(
			array(
				'value' => 'wc-default',
				'label' => __( 'WooCommerce Default (recommended)', 'carousel-slider' ),
			),
			array(
				'value' => 'v1-compatibility',
				'label' => __( 'Compatibility mode (with version 1)', 'carousel-slider' ),
			),
		);
		if ( Helper::is_pro_active() ) {
			$choices[] = array(
				'value' => 'template-parser',
				'label' => __( 'Custom Template (pro)', 'carousel-slider' ),
			);
		}
		$settings->add_field(
			array(
				'id'          => 'woocommerce_shop_loop_item_template',
				'type'        => 'radio',
				'default'     => 'v1-compatibility',
				'title'       => __( 'Slider item template', 'carousel-slider' ),
				'description' => array(
					__(
						'<strong>WooCommerce Default</strong> use hook to load shop loop template and does not allow
						hiding/showing title, rating, price, card button, sale tag using slider settings.',
						'carousel-slider'
					),
					__(
						'<strong>Compatibility mode</strong> use custom template and allow hiding/showing title,
						rating, price, card button, sale tag.',
						'carousel-slider'
					),
				),
				'choices'     => $choices,
				'panel'       => 'woocommerce',
			)
		);
	}

	/**
	 * Get modules choices
	 *
	 * @return array
	 */
	public function get_modules_choices(): array {
		$slider_types   = Helper::get_slider_types();
		$module_choices = array();
		foreach ( $slider_types as $value => $option ) {
			$choice = array(
				'value' => $value,
				'label' => isset( $option['pro'] ) && true === $option['pro'] ?
					sprintf( '%s - pro', $option['label'] ) : $option['label'],
			);
			if ( isset( $option['enabled'] ) && false === $option['enabled'] ) {
				$choice['readonly'] = true;
			}
			$module_choices[] = $choice;
		}

		return $module_choices;
	}
}
includes/Admin/GutenbergBlock.php000064400000004310151727276450013026 0ustar00<?php

namespace CarouselSlider\Admin;

use CarouselSlider\Helper;
use WP_Post;

defined( 'ABSPATH' ) || exit;

/**
 * GutenbergBlock class
 * The admin gutenberg editor functionality specific class of the plugin
 *
 * @package CarouselSlider/Admin
 */
class GutenbergBlock {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of this class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			self::$instance->gutenberg_block();
		}

		return self::$instance;
	}

	/**
	 * Register gutenberg block
	 */
	public function gutenberg_block() {
		if ( ! function_exists( 'register_block_type' ) ) {
			return;
		}
		wp_register_script(
			'carousel-slider-gutenberg-block',
			CAROUSEL_SLIDER_ASSETS . '/js/admin-gutenberg-block.js',
			[ 'wp-blocks', 'wp-components', 'wp-block-editor' ],
			CAROUSEL_SLIDER_VERSION,
			true
		);
		wp_register_style(
			'carousel-slider-gutenberg-style',
			CAROUSEL_SLIDER_ASSETS . '/css/admin-gutenberg-block.css',
			[ 'wp-edit-blocks' ],
			CAROUSEL_SLIDER_VERSION
		);
		wp_localize_script(
			'carousel-slider-gutenberg-block',
			'i18nCarouselSliderBlock',
			$this->block_localize_data()
		);

		register_block_type(
			'carousel-slider/slider',
			[
				'editor_script' => 'carousel-slider-gutenberg-block',
				'editor_style'  => 'carousel-slider-gutenberg-style',
			]
		);
	}

	/**
	 * Get localize data
	 *
	 * @return array
	 */
	private function block_localize_data(): array {
		$_sliders = Helper::get_sliders();
		$sliders  = [
			[
				'value' => '',
				'label' => __( 'Select a Slider', 'carousel-slider' ),
			],
		];
		foreach ( $_sliders as $form ) {
			if ( ! $form instanceof WP_Post ) {
				continue;
			}
			$sliders[] = [
				'value' => absint( $form->ID ),
				'label' => esc_attr( $form->post_title ),
			];
		}

		return [
			'sliders'       => $sliders,
			'site_url'      => site_url(),
			'block_logo'    => CAROUSEL_SLIDER_ASSETS . '/static-images/logo.svg',
			'block_title'   => __( 'Carousel Slider', 'carousel-slider' ),
			'select_slider' => __( 'Select a Slider', 'carousel-slider' ),
		];
	}
}
includes/Admin/PreviewMetaBox.php000064400000006465151727276450013047 0ustar00<?php

namespace CarouselSlider\Admin;

use CarouselSlider\Helper;
use CarouselSlider\Interfaces\SliderViewInterface;
use WP_Post;

/**
 * Admin live preview
 */
class PreviewMetaBox {

	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'add_meta_boxes', array( self::$instance, 'add_meta_boxes' ) );
			add_action( 'wp_ajax_carousel_slider_preview_meta_box', array( self::$instance, 'preview_meta_box' ) );
		}

		return self::$instance;
	}

	/**
	 * Add carousel slider meta box
	 *
	 * @param  string $post_type  The post-type.
	 */
	public function add_meta_boxes( $post_type ) {
		if ( CAROUSEL_SLIDER_POST_TYPE !== $post_type ) {
			return;
		}
		add_meta_box(
			'carousel-slider-live-preview',
			__( 'Live Preview', 'carousel-slider' ),
			[ $this, 'carousel_slider_live_preview' ],
			CAROUSEL_SLIDER_POST_TYPE,
			'normal',
			'high'
		);
	}

	/**
	 * Carousel slider live preview
	 *
	 * @return void
	 */
	public function carousel_slider_live_preview() {
		?>
		<div id="carousel_slider_preview_iframe_container" class="carousel_slider_preview_iframe_container"></div>
		<div id="carousel_slider_preview_meta_box"></div>
		<?php
	}

	/**
	 * Send preview meta-box
	 *
	 * @return void
	 */
	public function preview_meta_box() {
		$nonce = isset( $_REQUEST['cs_nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['cs_nonce'] ) ) : ''; // phpcs:ignore
		if ( ! wp_verify_nonce( $nonce, 'carousel_slider_ajax_nonce' ) ) {
			wp_send_json_error( __( 'Sorry, you are not allowed to access this resource.', 'carousel-slider' ), 403 );
		}
		$post_id = isset( $_REQUEST['post_ID'] ) ? absint( $_REQUEST['post_ID'] ) : 0;
		$post    = get_post( $post_id );
		if ( ! $post instanceof WP_Post ) {
			wp_send_json_error( __( 'Sorry, no item found for your request.', 'carousel-slider' ), 404 );
		}

		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			wp_send_json_error( __( 'Sorry, you are not allowed to access this resource.', 'carousel-slider' ), 403 );
		}

		if ( CAROUSEL_SLIDER_POST_TYPE !== $post->post_type ) {
			wp_send_json_error( __( 'Sorry, you are not allowed to access this resource.', 'carousel-slider' ), 401 );
		}

		$slider_type = get_post_meta( $post_id, '_slide_type', true );
		$view        = Helper::get_slider_view( $slider_type );
		if ( ! $view instanceof SliderViewInterface ) {
			wp_send_json_error( __( 'Sorry, no item found for your request.', 'carousel-slider' ), 422 );
		}

		$view->set_slider_id( $post_id );
		$view->set_slider_type( $slider_type );

		// Modify setting.
		$setting         = $view->get_slider_setting();
		$common_settings = $_POST['carousel_slider'] ?? [];
		$setting->read_http_post_variables( $common_settings );

		if ( 'image-carousel' === $slider_type ) {
			$image_carousel = $_POST['image_carousel'] ?? [];
			$setting->read_extra_http_post_variables( $image_carousel );
		}

		$view->set_slider_setting( $setting );

		// @TODO remove save option with temp
		MetaBox::init()->save_meta_box( $post_id );

		$response = [
			'slider_type' => $slider_type,
			'html'        => $view->render(),
		];

		wp_send_json_success( $response, 200 );
	}
}
includes/Traits/ApiResponse.php000064400000032555151727276450012613 0ustar00<?php

namespace CarouselSlider\Traits;

use WP_Error;
use WP_REST_Response;

trait ApiResponse {

	/**
	 * HTTP status code
	 *
	 * @var int
	 */
	protected $status_code = 200;

	/**
	 * The error code
	 *
	 * @var string
	 */
	protected $error_code = null;

	/**
	 * The message
	 *
	 * @var string
	 */
	protected $message = null;

	/**
	 * The data to be sent over HTTP
	 *
	 * @var mixed
	 */
	protected $data = null;

	/**
	 * Additional headers for response
	 *
	 * @var array
	 */
	protected $headers = [];

	/**
	 * Decode HTML entity
	 * WordPress encode HTML entity when saving to the database.
	 * Convert then back to character before sending data
	 *
	 * @param mixed $value The value to be decoded.
	 *
	 * @return mixed
	 */
	public function html_entity_decode( $value ) {
		if ( ! is_string( $value ) ) {
			return $value;
		}

		return html_entity_decode( $value, ENT_QUOTES | ENT_HTML5, get_option( 'blog_charset', 'UTF-8' ) );
	}

	/**
	 * Get HTTP status code.
	 *
	 * @return integer
	 */
	public function get_status_code(): int {
		return $this->status_code;
	}

	/**
	 * Set the HTTP status code.
	 *
	 * @param int $status_code The http status code.
	 *
	 * @return static
	 */
	public function set_status_code( int $status_code ) {
		$this->status_code = $status_code;

		return $this;
	}

	/**
	 * If it has error code
	 *
	 * @return bool
	 */
	public function has_error_code(): bool {
		return ! empty( $this->get_error_code() );
	}

	/**
	 * Get error code
	 *
	 * @return string
	 */
	public function get_error_code(): string {
		if ( is_string( $this->error_code ) && ! empty( $this->error_code ) ) {
			return $this->error_code;
		}
		$default = $this->get_default_error_message();

		return $default['code'] ?? '';
	}

	/**
	 * Set error code
	 *
	 * @param string|null $error_code The error code string.
	 */
	public function set_error_code( $error_code ) {
		if ( is_string( $error_code ) && ! empty( $error_code ) ) {
			$this->error_code = $error_code;
		}

		return $this;
	}

	/**
	 * If it has a message
	 *
	 * @return bool
	 */
	public function has_message(): bool {
		return ! empty( $this->get_message() );
	}

	/**
	 * Get message
	 *
	 * @return string
	 */
	public function get_message(): string {
		if ( is_string( $this->message ) && ! empty( $this->message ) ) {
			return $this->message;
		}
		$default = $this->get_default_error_message();

		return $default['message'] ?? '';
	}

	/**
	 * Set message
	 *
	 * @param string|null $message The message string.
	 */
	public function set_message( $message ) {
		if ( is_string( $message ) && ! empty( $message ) ) {
			$this->message = $message;
		}

		return $this;
	}

	/**
	 * If it has data
	 *
	 * @return bool
	 */
	public function has_data(): bool {
		return ! empty( $this->data );
	}

	/**
	 * Get data
	 *
	 * @return mixed
	 */
	public function get_data() {
		return $this->data;
	}

	/**
	 * Set data
	 *
	 * @param mixed $data The data for HTTP response body.
	 */
	public function set_data( $data ) {
		if ( ! empty( $data ) ) {
			$this->data = $data;
		}

		return $this;
	}

	/**
	 * Get additional response headers
	 *
	 * @return array
	 */
	public function get_headers(): array {
		return $this->headers;
	}

	/**
	 * Set additional response headers
	 *
	 * @param array $headers Additional headers.
	 *
	 * @return static
	 */
	public function set_headers( array $headers ) {
		foreach ( $headers as $key => $value ) {
			$this->headers[ $key ] = $value;
		}

		return $this;
	}

	/**
	 * Check if it is a success response
	 *
	 * @return bool
	 */
	public function is_success_response(): bool {
		return ( $this->get_status_code() >= 200 && $this->get_status_code() < 300 );
	}

	/**
	 * Get default error message
	 *
	 * @return array
	 */
	protected function get_default_error_message(): array {
		$messages = [
			401 => [
				'code'    => 'rest_forbidden_context',
				'message' => __( 'Sorry, you are not allowed to access this resource.', 'carousel-slider' ),
			],
			403 => [
				'code'    => 'rest_forbidden_context',
				'message' => __( 'Sorry, you are not allowed to access this resource.', 'carousel-slider' ),
			],
			404 => [
				'code'    => 'rest_no_item_found',
				'message' => __( 'Sorry, no item found for your request.', 'carousel-slider' ),
			],
			422 => [
				'code'    => 'rest_invalid_data_type',
				'message' => __( 'One or more fields has an error. Fix and try again.', 'carousel-slider' ),
			],
			500 => [
				'code'    => 'rest_server_error',
				'message' => __( 'Sorry, something went wrong.', 'carousel-slider' ),
			],
		];

		return $messages[ $this->get_status_code() ] ?? [
			'code'    => null,
			'message' => null,
		];
	}

	/**
	 * Get formatted response
	 *
	 * @return array
	 */
	protected function get_formatted_response(): array {
		$response = [
			'success' => $this->is_success_response(),
		];

		if ( $this->has_error_code() ) {
			$response['code'] = $this->get_error_code();
		}

		if ( $this->has_message() ) {
			$response['message'] = $this->get_message();
		}

		if ( $this->has_data() ) {
			if ( ! $this->is_success_response() ) {
				$response['errors'] = $this->get_data();
			} else {
				$response['data'] = is_array( $this->get_data() ) ?
					map_deep( $this->get_data(), [ $this, 'html_entity_decode' ] ) :
					$this->get_data();
			}
		}

		return $response;
	}

	/**
	 * Respond.
	 *
	 * @param mixed $data Response data. Default null.
	 * @param int   $status Optional. HTTP status code. Default 200.
	 * @param array $headers Optional. HTTP header map. Default empty array.
	 *
	 * @return WP_REST_Response
	 */
	public function respond( $data = null, $status = null, $headers = [] ): WP_REST_Response {
		if ( empty( $data ) ) {
			$data = $this->get_formatted_response();
		}
		if ( empty( $status ) ) {
			$status = $this->get_status_code();
		}
		if ( empty( $headers ) ) {
			$headers = $this->get_headers();
		}

		return new WP_REST_Response( $data, $status, $headers );
	}

	/**
	 * Response with WP_Error object
	 *
	 * @param WP_Error $error The error object.
	 *
	 * @return WP_REST_Response
	 */
	public function respond_with_wp_error( WP_Error $error ): WP_REST_Response {
		$this->set_message( $error->get_error_message() );
		$this->set_error_code( $error->get_error_code() );

		$error_data = $error->has_errors() && is_array( $error->get_error_data() ) ? $error->get_error_data() : [];
		if ( isset( $error_data['status'] ) ) {
			$status_code = is_numeric( $error_data['status'] ) ? intval( $error_data['status'] ) : 400;
			unset( $error_data['status'] );
		}

		if ( count( $error_data ) ) {
			$this->set_data( $error_data );
		}

		$this->set_status_code( $status_code ?? 400 );

		return $this->respond();
	}

	/**
	 * Response error message
	 *
	 * @param string|array|null $code The WP_Error object, or error data array, or error code string.
	 * @param string|null       $message The error message.
	 * @param mixed             $data Error data array.
	 *
	 * @return WP_REST_Response
	 */
	public function respond_with_error( $code = null, $message = null, $data = null ): WP_REST_Response {
		if ( $code instanceof WP_Error ) {
			return $this->respond_with_wp_error( $code );
		}

		if ( 1 === func_num_args() && is_array( $code ) ) {
			$this->set_data( $code );

			return $this->respond();
		}

		$this->set_error_code( $code );
		$this->set_message( $message );
		$this->set_data( $data );

		return $this->respond();
	}

	/**
	 * Response success message
	 *
	 * @param mixed       $data The response data. It Also can be set message if there is no data.
	 * @param string|null $message Additional message for the success response.
	 * @param array       $headers Additional http header.
	 *
	 * @return WP_REST_Response
	 */
	public function respond_with_success( $data = null, $message = null, $headers = array() ): WP_REST_Response {
		if ( 1 === func_num_args() && is_string( $data ) ) {
			list( $data, $message ) = array( null, $data );
		}

		$this->set_data( $data );
		$this->set_message( $message );
		$this->set_headers( $headers );

		return $this->respond();
	}

	/**
	 * 200 (OK)
	 * The request has succeeded.
	 * Use cases:
	 * --> update/retrieve data
	 * --> bulk creation
	 * --> bulk update
	 *
	 * @param mixed       $data The data to be sent for response.
	 * @param string|null $message Response message (Optional).
	 *
	 * @return WP_REST_Response
	 */
	public function respond_ok( $data = null, $message = null ): WP_REST_Response {
		return $this->set_status_code( 200 )->respond_with_success( $data, $message );
	}

	/**
	 * 201 (Created)
	 * The request has succeeded, and a new resource has been created as a result of it.
	 * This is typically the response sent after a POST request, or after some PUT requests.
	 *
	 * @param mixed       $data The data to be sent for response.
	 * @param string|null $message Response message (Optional).
	 *
	 * @return WP_REST_Response
	 */
	public function respond_created( $data = null, $message = null ): WP_REST_Response {
		return $this->set_status_code( 201 )->respond_with_success( $data, $message );
	}

	/**
	 * 202 (Accepted)
	 * The request has been received but not yet acted upon.
	 * The response should include the Location header with a link towards the location where
	 * the final response can be polled & later obtained.
	 * Use cases:
	 * --> asynchronous tasks (e.g., report generation)
	 * --> batch processing
	 * --> delete data that is NOT immediate
	 *
	 * @param mixed       $data The data to be sent for response.
	 * @param string|null $message Response message (Optional).
	 *
	 * @return WP_REST_Response
	 */
	public function respond_accepted( $data = null, $message = null ): WP_REST_Response {
		return $this->set_status_code( 202 )->respond_with_success( $data, $message );
	}

	/**
	 * 204 (No Content)
	 * There is no content to send for this request, but the headers may be useful.
	 * Use cases:
	 * --> deletion succeeded
	 *
	 * @param mixed       $data The data to be sent for response.
	 * @param string|null $message Response message (Optional).
	 *
	 * @return WP_REST_Response
	 */
	public function respond_no_content( $data = null, $message = null ): WP_REST_Response {
		return $this->set_status_code( 204 )->respond_with_success( $data, $message );
	}

	/**
	 * 400 (Bad request)
	 * Server could not understand the request due to invalid syntax.
	 * Use cases:
	 * --> invalid/incomplete request
	 * --> return multiple client errors at once
	 *
	 * @param string|null $code The WP_Error object, or error code string.
	 * @param string|null $message The error message.
	 * @param mixed       $data Additional error data.
	 *
	 * @return WP_REST_Response
	 */
	public function respond_bad_request( $code = null, $message = null, $data = null ): WP_REST_Response {
		return $this->set_status_code( 400 )->respond_with_error( $code, $message, $data );
	}

	/**
	 * 401 (Unauthorized)
	 * The request requires user authentication.
	 *
	 * @param string|null $code The WP_Error object, or error code string.
	 * @param string|null $message The error message.
	 * @param mixed       $data Additional error data.
	 *
	 * @return WP_REST_Response
	 */
	public function respond_unauthorized( $code = null, $message = null, $data = null ): WP_REST_Response {
		return $this->set_status_code( 401 )->respond_with_error( $code, $message, $data );
	}

	/**
	 * 403 (Forbidden)
	 * The client is authenticated but not authorized to perform the action.
	 *
	 * @param string|null $code The WP_Error object, or error code string.
	 * @param string|null $message The error message.
	 * @param mixed       $data Additional error data.
	 *
	 * @return WP_REST_Response
	 */
	public function respond_forbidden( $code = null, $message = null, $data = null ): WP_REST_Response {
		return $this->set_status_code( 403 )->respond_with_error( $code, $message, $data );
	}

	/**
	 * 404 (Not Found)
	 * The server cannot find the requested resource. In an API, this can also mean that the endpoint is valid but
	 * the resource itself does not exist. Servers may also send this response instead of 403 to hide
	 * the existence of a resource from an unauthorized client.
	 *
	 * @param string|null $code The WP_Error object, or error code string.
	 * @param string|null $message The error message.
	 * @param mixed       $data Additional error data.
	 *
	 * @return WP_REST_Response
	 */
	public function respond_not_found( $code = null, $message = null, $data = null ): WP_REST_Response {
		return $this->set_status_code( 404 )->respond_with_error( $code, $message, $data );
	}

	/**
	 * 422 (Unprocessable Entity)
	 * The request was well-formed but was unable to be followed due to semantic errors.
	 *
	 * @param string|null $code The WP_Error object, or error code string.
	 * @param string|null $message The error message.
	 * @param mixed       $data Additional error data.
	 *
	 * @return WP_REST_Response
	 */
	public function respond_unprocessable_entity( $code = null, $message = null, $data = null ): WP_REST_Response {
		return $this->set_status_code( 422 )->respond_with_error( $code, $message, $data );
	}

	/**
	 * 500 (Internal Server Error)
	 * The server has encountered a situation it doesn't know how to handle.
	 *
	 * @param string|null $code The WP_Error object, or error code string.
	 * @param string|null $message The error message.
	 * @param mixed       $data Additional error data.
	 *
	 * @return WP_REST_Response
	 */
	public function respond_internal_server_error( $code = null, $message = null, $data = null ): WP_REST_Response {
		return $this->set_status_code( 500 )->respond_with_error( $code, $message, $data );
	}
}
includes/Widget/CarouselSliderWidget.php000064400000010534151727276450014415 0ustar00<?php

namespace CarouselSlider\Widget;

use CarouselSlider\Frontend\Frontend;
use CarouselSlider\Helper;
use WP_Widget;

defined( 'ABSPATH' ) || exit;

/**
 * CarouselSliderWidget class
 */
class CarouselSliderWidget extends WP_Widget {

	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'widgets_init', [ self::$instance, 'register' ] );
		}

		return self::$instance;
	}

	/**
	 * Register current class as widget
	 */
	public static function register() {
		register_widget( __CLASS__ );
	}

	/**
	 * Get the list of carousel sliders
	 *
	 * @return array
	 */
	private static function carousels_list(): array {
		$posts = Helper::get_sliders();

		$items = [];
		foreach ( $posts as $post ) {
			$items[] = [
				'id'    => $post->ID,
				'title' => $post->post_title,
			];
		}

		return $items;
	}

	/**
	 * Sets up the widgets name etc
	 */
	public function __construct() {
		$widget_ops = array(
			'classname'   => 'widget_carousel_slider',
			'description' => __(
				'The easiest way to create image, video, post and WooCommerce product carousel.',
				'carousel-slider'
			),
		);
		parent::__construct( 'widget_carousel_slider', __( 'Carousel Slider', 'carousel-slider' ), $widget_ops );
	}

	/**
	 * Outputs the content of the widget
	 *
	 * @param  array $args  Display arguments including 'before_title', 'after_title',
	 *                       'before_widget', and 'after_widget'.
	 * @param  array $instance  The settings for the particular instance of the widget.
	 */
	public function widget( $args, $instance ) {
		$title       = isset( $instance['title'] ) ? esc_html( $instance['title'] ) : null;
		$carousel_id = isset( $instance['carousel_id'] ) ? absint( $instance['carousel_id'] ) : 0;

		if ( ! $carousel_id ) {
			return;
		}

		$html = $args['before_widget'];

		if ( ! empty( $title ) ) {
			$html .= $args['before_title'] . $title . $args['after_title'];
		}

		$html .= Frontend::init()->carousel_slide( [ 'id' => $carousel_id ] );
		$html .= $args['after_widget'];

		Helper::print_unescaped_internal_string( $html );
	}

	/**
	 * Outputs the settings update form.
	 *
	 * @param  array $instance  Current settings.
	 *
	 * @return void
	 */
	public function form( $instance ) {
		$carousels   = static::carousels_list();
		$carousel_id = ! empty( $instance['carousel_id'] ) ? absint( $instance['carousel_id'] ) : null;
		$title       = ! empty( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
		$html        = '';
		if ( count( $carousels ) > 0 ) {
			$html .= sprintf(
				'<p><label for="%1$s">%2$s</label>',
				$this->get_field_id( 'title' ),
				__( 'Title (optional):', 'carousel-slider' )
			);
			$html .= sprintf(
				'<input type="text" class="widefat" id="%1$s" name="%2$s" value="%3$s" /></p>',
				$this->get_field_id( 'title' ),
				$this->get_field_name( 'title' ),
				$title
			);

			$html .= sprintf( '<p><label>%s</label>', __( 'Choose Slide', 'carousel-slider' ) );
			$html .= sprintf( '<select class="widefat" name="%s">', $this->get_field_name( 'carousel_id' ) );
			foreach ( $carousels as $carousel ) {
				$selected = $carousel['id'] === $carousel_id ? 'selected="selected"' : '';
				$html    .= sprintf(
					'<option value="%1$d" %3$s>%2$s</option>',
					absint( $carousel['id'] ),
					esc_html( $carousel['title'] ),
					$selected
				);
			}
			$html .= '</select></p>';

		} else {
			$html .= sprintf(
				'<p>%1$s <a href="' . admin_url( 'post-new.php?post_type=carousels' ) . '">%3$s</a> %2$s</p>',
				__( 'You did not add any carousel slider yet.', 'carousel-slider' ),
				__( 'to create a new carousel slider now.', 'carousel-slider' ),
				__( 'click here', 'carousel-slider' )
			);
		}

		echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}

	/**
	 * Processing widget options on save
	 *
	 * @param  array $new_instance  The new options.
	 * @param  array $old_instance  The previous options.
	 *
	 * @return array
	 */
	public function update( $new_instance, $old_instance ) {
		$old_instance['title']       = sanitize_text_field( $new_instance['title'] );
		$old_instance['carousel_id'] = absint( $new_instance['carousel_id'] );

		return $old_instance;
	}
}
includes/CLI/Command.php000064400000025603151727276450011076 0ustar00<?php

namespace CarouselSlider\CLI;

use CarouselSlider\Helper;
use CarouselSlider\Modules\HeroCarousel\Template as TemplateHeroCarousel;
use CarouselSlider\Modules\ImageCarousel\Template as TemplateImageCarousel;
use CarouselSlider\Modules\ImageCarousel\TemplateUrl as TemplateUrlImageCarousel;
use CarouselSlider\Modules\PostCarousel\Template as TemplatePostCarousel;
use CarouselSlider\Modules\ProductCarousel\Template as TemplateProductCarousel;
use CarouselSlider\Modules\VideoCarousel\Template as TemplateVideoCarousel;
use WP_CLI;
use WP_CLI_Command;

defined( 'ABSPATH' ) || exit;

/**
 * Command class
 * The command line interface class handle plugin cli functionality
 *
 * @package CarouselSlider/CLI
 */
class Command extends WP_CLI_Command {
	/**
	 * Create a post-carousel
	 *
	 * @param  array  $args  The arguments.
	 * @param  string $slider_title  The slider title.
	 *
	 * @return int
	 */
	protected static function create_post_carousel( array $args, string $slider_title ): int {
		$post_query      = ! empty( $args['post-query'] ) ? $args['post-query'] : 'latest_posts';
		$date_from       = ! empty( $args['date-from'] ) ? $args['date-from'] : '';
		$date_to         = ! empty( $args['date-to'] ) ? $args['date-to'] : '';
		$post_categories = ! empty( $args['post-categories'] ) ? $args['post-categories'] : '';
		$post_tags       = ! empty( $args['post-tags'] ) ? $args['post-tags'] : '';
		$post_in         = ! empty( $args['post-in'] ) ? $args['post-in'] : '';
		$post_args       = array(
			'_created_via'      => 'wp-cli',
			'_post_query_type'  => $post_query,
			'_post_date_after'  => $date_from,
			'_post_date_before' => $date_to,
			'_post_categories'  => $post_categories,
			'_post_tags'        => $post_tags,
			'_post_in'          => $post_in,
		);

		return TemplatePostCarousel::create( $slider_title, $post_args );
	}

	/**
	 * Display Carousel Slider Information
	 *
	 * @subcommand info
	 */
	public function info() {
		WP_CLI::success( 'Welcome to the Carousel Slider WP-CLI Extension!' );
		WP_CLI::line( '' );
		WP_CLI::line( '- Carousel Slider Version: ' . CAROUSEL_SLIDER_VERSION );
		WP_CLI::line( '- Carousel Slider Directory: ' . CAROUSEL_SLIDER_PATH );
		WP_CLI::line( '- Carousel Slider Public URL: ' . CAROUSEL_SLIDER_URL );
		WP_CLI::line( '' );
	}

	/**
	 * Create Slider
	 *
	 * ## OPTIONS
	 *
	 * <name>
	 * : The name of the slider to create.
	 *
	 * [--type=<type>]
	 * : Carousel slider type.
	 * ---
	 * default: image-carousel
	 * options:
	 *  - image-carousel
	 *  - image-carousel-url
	 *  - post-carousel
	 *  - product-carousel
	 *  - video-carousel
	 *  - hero-banner-slider
	 * ---
	 *
	 * [--post-query=<post-query>]
	 * : Post carousel query type.
	 * ---
	 * default: latest_posts
	 * options:
	 *  - latest_posts
	 *  - date_range
	 *  - post_categories
	 *  - post_tags
	 *  - specific_posts
	 * ---
	 *
	 * [--date-from=<date-from>]
	 * : Post carousel query starting date.
	 *
	 * [--date-to=<date-to>]
	 * : Post carousel query starting date.
	 *
	 * [--post-categories=<post-categories>]
	 * : Comma separated post-category id
	 *
	 * [--post-tags=<post-tags>]
	 * : Comma separated post-tag id
	 *
	 * [--post-in=<post-in>]
	 * : Comma separated post id
	 *
	 * ## EXAMPLES
	 *
	 * wp carousel-slider create_slider 'Post Carousel - LP' --type='post-carousel'
	 * wp carousel-slider create_slider 'Post Carousel - LP' --type='post-carousel' --post-query='latest_posts'
	 * wp carousel-slider create_slider 'Post Carousel - SP' --type='post-carousel' --post-query='specific_posts'
	 * wp carousel-slider create_slider 'Post Carousel - DR' --type='post-carousel' --post-query='date_range'
	 * wp carousel-slider create_slider 'Post Carousel - PC' --type='post-carousel' --post-query='post_categories'
	 * wp carousel-slider create_slider 'Post Carousel - PT' --type='post-carousel' --post-query='post_tags'
	 *
	 * @param  mixed $args  The arguments.
	 * @param  mixed $assoc_args  The additional arguments.
	 *
	 * @throws WP_CLI\ExitException The Exception.
	 */
	public function create_slider( $args, $assoc_args ) {
		list( $slider_title ) = $args;
		$type                 = ! empty( $assoc_args['type'] ) ? $assoc_args['type'] : 'image-carousel';
		$slider_id            = 0;

		if ( 'image-carousel' === $type ) {
			$slider_id = TemplateImageCarousel::create(
				$slider_title,
				array(
					'_created_via' => 'wp-cli',
				)
			);
		}

		if ( 'image-carousel-url' === $type ) {
			$slider_id = TemplateUrlImageCarousel::create(
				$slider_title,
				array(
					'_created_via' => 'wp-cli',
				)
			);
		}

		if ( 'video-carousel' === $type ) {
			$slider_id = TemplateVideoCarousel::create(
				$slider_title,
				array(
					'_created_via' => 'wp-cli',
				)
			);
		}

		if ( 'post-carousel' === $type ) {
			$slider_id = self::create_post_carousel( $assoc_args, (string) $slider_title );
		}

		if ( ! $slider_id ) {
			WP_CLI::error( __( 'Could not create slider.', 'carousel-slider' ) );

			return;
		}

		$response = sprintf(
			/* translators: 1: the slider id, 2: the slider title */
			__( '#%1$s - %2$s has been created successfully.', 'carousel-slider' ),
			$slider_id,
			$slider_title
		);
		WP_CLI::success( $response );
	}

	/**
	 * Create sliders for testing
	 */
	public function create_sliders() {
		$ids     = [];
		$sliders = [
			[
				'type'  => 'hero-banner-slider',
				'title' => 'Test: Hero Carousel',
				'args'  => [],
			],
			[
				'type'  => 'image-carousel',
				'title' => 'Test: Image Carousel - Gallery',
				'args'  => [],
			],
			[
				'type'  => 'image-carousel-url',
				'title' => 'Test: Image Carousel - URL',
				'args'  => [],
			],
			[
				'type'  => 'video-carousel',
				'title' => 'Test: Video Carousel - Youtube',
				'args'  => [],
			],
			// Post Carousel.
			[
				'type'  => 'post-carousel',
				'title' => 'Test: Post Carousel - Latest Posts',
				'args'  => [ '_post_query_type' => 'latest_posts' ],
			],
			[
				'type'  => 'post-carousel',
				'title' => 'Test: Post Carousel - Date Range',
				'args'  => [ '_post_query_type' => 'date_range' ],
			],
			[
				'type'  => 'post-carousel',
				'title' => 'Test: Post Carousel - Categories',
				'args'  => [ '_post_query_type' => 'post_categories' ],
			],
			[
				'type'  => 'post-carousel',
				'title' => 'Test: Post Carousel - Tags',
				'args'  => [ '_post_query_type' => 'post_tags' ],
			],
			[
				'type'  => 'post-carousel',
				'title' => 'Test: Post Carousel - IDs',
				'args'  => [ '_post_query_type' => 'specific_posts' ],
			],
			// Product Carousel.
			[
				'type'  => 'product-carousel',
				'title' => 'Test: Product Carousel - IDs',
				'args'  => [ '_product_query_type' => 'specific_products' ],
			],
			[
				'type'  => 'product-carousel',
				'title' => 'Test: Product Carousel - Categories',
				'args'  => [ '_product_query_type' => 'product_categories' ],
			],
			[
				'type'  => 'product-carousel',
				'title' => 'Test: Product Carousel - Tags',
				'args'  => [ '_product_query_type' => 'product_tags' ],
			],
			[
				'type'  => 'product-carousel',
				'title' => 'Test: Product Carousel - Recent Products',
				'args'  => [
					'_product_query_type' => 'query_product',
					'_product_query'      => 'recent',
				],
			],
			[
				'type'  => 'product-carousel',
				'title' => 'Test: Product Carousel - Featured Products',
				'args'  => [
					'_product_query_type' => 'query_product',
					'_product_query'      => 'featured',
				],
			],
			[
				'type'  => 'product-carousel',
				'title' => 'Test: Product Carousel - Sale Products',
				'args'  => [
					'_product_query_type' => 'query_product',
					'_product_query'      => 'sale',
				],
			],
			[
				'type'  => 'product-carousel',
				'title' => 'Test: Product Carousel - Best Selling Products',
				'args'  => [
					'_product_query_type' => 'query_product',
					'_product_query'      => 'best_selling',
				],
			],
			[
				'type'  => 'product-carousel',
				'title' => 'Test: Product Carousel - Top Rated Products',
				'args'  => [
					'_product_query_type' => 'query_product',
					'_product_query'      => 'top_rated',
				],
			],
			[
				'type'  => 'product-carousel',
				'title' => 'Test: Product Carousel - Product Categories List',
				'args'  => [
					'_product_query_type' => 'query_product',
					'_product_query'      => 'product_categories_list',
				],
			],
		];

		foreach ( $sliders as $slider ) {
			switch ( $slider['type'] ) {
				case 'image-carousel':
					$ids[] = TemplateImageCarousel::create( $slider['title'], $slider['args'] );
					WP_CLI::line( "{$slider['title']} has been created successfully." );
					break;
				case 'image-carousel-url':
					$ids[] = TemplateUrlImageCarousel::create( $slider['title'], $slider['args'] );
					WP_CLI::line( "{$slider['title']} has been created successfully." );
					break;
				case 'video-carousel':
					$ids[] = TemplateVideoCarousel::create( $slider['title'], $slider['args'] );
					WP_CLI::line( "{$slider['title']} has been created successfully." );
					break;
				case 'post-carousel':
					$ids[] = TemplatePostCarousel::create( $slider['title'], $slider['args'] );
					WP_CLI::line( "{$slider['title']} has been created successfully." );
					break;
				case 'hero-banner-slider':
					$ids[] = TemplateHeroCarousel::create( $slider['title'], $slider['args'] );
					WP_CLI::line( "{$slider['title']} has been created successfully." );
					break;
				case 'product-carousel':
					$ids[] = TemplateProductCarousel::create( $slider['title'], $slider['args'] );
					WP_CLI::line( "{$slider['title']} has been created successfully." );
					break;
			}
		}

		Helper::create_test_page( $ids );

		WP_CLI::success( 'All test sliders has been created successfully.' );
	}

	/**
	 * Delete a slider by slider id
	 *
	 * ## OPTIONS
	 *
	 * <id>
	 * : The slider id.
	 *
	 * @param  array|mixed $args  The arguments.
	 */
	public function delete_slider( $args ) {
		list( $id ) = $args;

		if ( wp_delete_post( $id, true ) ) {
			WP_CLI::success( "#{$id} has been deleted successfully." );
		}
	}

	/**
	 * Delete all sliders
	 */
	public function delete_sliders() {
		$sliders = get_posts(
			[
				'post_type'   => 'carousels',
				'post_status' => 'any',
				'numberposts' => - 1,
			]
		);
		foreach ( $sliders as $slider ) {
			if ( wp_delete_post( $slider->ID, true ) ) {
				WP_CLI::line( "Carousel Slider #{$slider->ID} has been deleted successfully." );
			}
		}
		WP_CLI::success( 'Carousel Slider: all sliders has been deleted successfully.' );
	}

	/**
	 * Delete all slider settings
	 */
	public function delete_options() {
		$options = [
			'wp_carousel_free_version',
			'wp_carousel_free_db_version',
			'carousel_slider_settings',
			'carousel_slider_allow_tracking',
			'carousel_slider_tracking_notice',
			'carousel_slider_tracking_skipped',
			'widget_widget_carousel_slider',
		];
		foreach ( $options as $option ) {
			if ( delete_option( $option ) ) {
				WP_CLI::line( "Option '{$option}' has been deleted successfully." );
			}
		}
		WP_CLI::success( 'Carousel Slider: all options has been deleted successfully.' );
	}
}
includes/REST/CarouselController.php000064400000012450151727276450013503 0ustar00<?php

namespace CarouselSlider\REST;

use CarouselSlider\Helper;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

/**
 * CarouselController
 */
class CarouselController extends ApiController {

	/**
	 * Registers the routes for the objects of the controller.
	 */
	public function register_routes() {
		register_rest_route(
			$this->namespace,
			'/carousels',
			[
				[
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => [ $this, 'get_items' ],
					'permission_callback' => [ $this, 'get_items_permissions_check' ],
					'args'                => $this->get_collection_params(),
				],
				[
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => [ $this, 'create_item' ],
					'permission_callback' => [ $this, 'create_item_permissions_check' ],
					'args'                => [
						'title' => [
							'description'       => __( 'The carousel slider title', 'carousel-slider' ),
							'type'              => 'string',
							'required'          => true,
							'sanitize_callback' => 'sanitize_text_field',
							'validate_callback' => 'rest_validate_request_arg',
						],
						'type'  => [
							'description'       => __( 'The carousel slider type', 'carousel-slider' ),
							'type'              => 'string',
							'required'          => true,
							'sanitize_callback' => 'sanitize_text_field',
							'validate_callback' => 'rest_validate_request_arg',
							'enum'              => Helper::get_enabled_slider_types_slug(),
						],
					],
				],
			]
		);
		register_rest_route(
			$this->namespace,
			'/carousels/(?P<id>[\d]+)',
			[
				'args' => [
					'id' => [
						'description' => __( 'Unique identifier for the carousel.', 'carousel-slider' ),
						'type'        => 'integer',
					],
				],
				[
					'methods'             => WP_REST_Server::DELETABLE,
					'callback'            => [ $this, 'delete_item' ],
					'permission_callback' => [ $this, 'delete_item_permissions_check' ],
					'args'                => [
						'force' => [
							'type'        => 'boolean',
							'default'     => false,
							'description' => __( 'Whether to bypass Trash and force deletion.', 'carousel-slider' ),
						],
					],
				],
			]
		);
	}

	/**
	 * Retrieves a collection of items.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	public function get_items( $request ) {
		$search   = $request->get_param( 'search' );
		$page     = (int) $request->get_param( 'page' );
		$per_page = (int) $request->get_param( 'per_page' );

		$args = [
			'posts_per_page' => $per_page,
			'paged'          => $page,
		];
		if ( ! empty( $search ) ) {
			$args['s'] = $search;
		}
		$get_sliders = Helper::get_sliders( $args );

		$items = [];
		foreach ( $get_sliders as $slider ) {
			$items[] = [
				'id'        => $slider->ID,
				'title'     => $slider->post_title,
				'type'      => get_post_meta( $slider->ID, '_slide_type', true ),
				'edit_link' => get_edit_post_link( $slider ),
			];
		}

		$counts = wp_count_posts( CAROUSEL_SLIDER_POST_TYPE );
		$count  = $counts->publish ?? 0;

		return $this->respond_ok(
			[
				'pagination' => $this->get_pagination_data( $count, $per_page, $page ),
				'items'      => $items,
			]
		);
	}

	/**
	 * Creates one item from the collection.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	public function create_item( $request ) {
		$id = Helper::create_slider(
			$request->get_param( 'title' ),
			$request->get_param( 'type' )
		);

		if ( is_wp_error( $id ) ) {
			return $this->respond_unprocessable_entity( $id );
		}

		$post = get_post( $id );

		$response_data = [
			'id'        => $post->ID,
			'title'     => $post->post_title,
			'type'      => get_post_meta( $post->ID, '_slide_type', true ),
			'edit_link' => get_edit_post_link( $post ),
		];

		do_action( 'carousel_slider/rest_create_slider', $response_data, $request->get_params() );

		return $this->respond_created( $response_data );
	}

	/**
	 * Deletes one item from the collection.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	public function delete_item( $request ) {
		// As we validated slider existence on permission_callback, no need to validate again.
		$force = $request->get_param( 'force' );
		$post  = get_post( (int) $request->get_param( 'id' ) );

		if ( $force ) {
			wp_delete_post( $post->ID, true );

			return $this->respond_ok(
				[
					'deleted'  => true,
					'previous' => [ 'id' => $post->ID ],
				]
			);
		}

		// Otherwise, only trash if we haven't already.
		if ( 'trash' === $post->post_status ) {
			$this->set_status_code( 410 );

			return $this->respond_with_error(
				'rest_already_trashed',
				__( 'The post has already been deleted.', 'carousel-slider' )
			);
		}

		$result = wp_trash_post( $post->ID );
		if ( ! $result ) {
			return $this->respond_with_wp_error(
				new WP_Error(
					'rest_cannot_delete',
					__( 'The post cannot be deleted.', 'carousel-slider' ),
					[ 'status' => 500 ]
				)
			);
		}

		return $this->respond_ok( [ 'id' => $post->ID ] );
	}
}
includes/REST/ApiController.php000064400000016514151727276450012444 0ustar00<?php

namespace CarouselSlider\REST;

use CarouselSlider\Admin\MetaBoxConfig;
use CarouselSlider\Helper;
use CarouselSlider\Supports\Sanitize;
use CarouselSlider\Traits\ApiResponse;
use WP_Error;
use WP_REST_Controller;
use WP_REST_Request;

// If this file is called directly, abort.
defined( 'ABSPATH' ) || exit;

/**
 * ApiController Class
 *
 * @package CarouselSlider\REST
 */
class ApiController extends WP_REST_Controller {
	use ApiResponse;

	/**
	 * The namespace of this controller's route.
	 *
	 * @var string
	 */
	protected $namespace = 'carousel-slider/v1';

	/**
	 * Get general setting default data
	 *
	 * @var array
	 */
	protected $general_setting_defaults = [];

	/**
	 * Checks if a given request has access to get items.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return true|WP_Error True, if the request has read access, WP_Error object otherwise.
	 */
	public function get_items_permissions_check( $request ) {
		$post_type = get_post_type_object( CAROUSEL_SLIDER_POST_TYPE );
		if ( ! current_user_can( $post_type->cap->edit_posts ) ) {
			return new WP_Error(
				'rest_forbidden_context',
				__( 'Sorry, you are not allowed to edit sliders.', 'carousel-slider' ),
				array( 'status' => rest_authorization_required_code() )
			);
		}

		return true;
	}

	/**
	 * Checks if a given request has access to get a specific item.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return true|WP_Error True, if the request has access to delete the item, WP_Error object otherwise.
	 */
	public function get_item_permissions_check( $request ) {
		$post = get_post( $request['id'] );
		if ( ! $post instanceof \WP_Post ) {
			return new WP_Error(
				'rest_no_item_found',
				__( 'Sorry, no item found for your request.', 'carousel-slider' ),
				array( 'status' => 404 )
			);
		}

		$post_type = get_post_type_object( CAROUSEL_SLIDER_POST_TYPE );

		if ( ! current_user_can( $post_type->cap->read_post, $post ) ) {
			return new WP_Error(
				'rest_forbidden_context',
				__( 'Sorry, you are not allowed to view this post.', 'carousel-slider' ),
				array( 'status' => rest_authorization_required_code() )
			);
		}

		return true;
	}

	/**
	 * Checks if a given request has access to create items.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return true|WP_Error True, if the request has access to create items, WP_Error object otherwise.
	 */
	public function create_item_permissions_check( $request ) {
		$post_type = get_post_type_object( CAROUSEL_SLIDER_POST_TYPE );
		if ( ! current_user_can( $post_type->cap->create_posts ) ) {
			return new WP_Error(
				'rest_cannot_create',
				__( 'Sorry, you are not allowed to create posts as this user.', 'carousel-slider' ),
				[ 'status' => rest_authorization_required_code() ]
			);
		}

		return true;
	}

	/**
	 * Checks if a given request has access to delete a post.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return true|WP_Error True, if the request has access to delete the item, WP_Error object otherwise.
	 */
	public function delete_item_permissions_check( $request ) {
		$post = get_post( $request['id'] );
		if ( ! $post instanceof \WP_Post ) {
			return new WP_Error(
				'rest_no_item_found',
				__( 'Sorry, no item found for your request.', 'carousel-slider' ),
				array( 'status' => 404 )
			);
		}

		$post_type = get_post_type_object( CAROUSEL_SLIDER_POST_TYPE );

		if ( ! current_user_can( $post_type->cap->delete_post, $post ) ) {
			return new WP_Error(
				'rest_cannot_delete',
				__( 'Sorry, you are not allowed to delete this post.', 'carousel-slider' ),
				array( 'status' => rest_authorization_required_code() )
			);
		}

		return true;
	}

	/**
	 * Get general setting argument property
	 *
	 * @return array[]
	 */
	public function general_setting_args_properties(): array {
		$field_settings = MetaBoxConfig::get_fields_settings();
		$properties     = [];
		foreach ( $field_settings as $key => $args ) {
			$setting = [
				'required'    => false,
				'description' => $this->html_entity_decode( $args['label'] ),
			];
			if ( 'number' === $args['type'] ) {
				$setting['type'] = 'number';
			} elseif ( 'switch' === $args['type'] ) {
				$setting['type'] = 'string';
				$setting['enum'] = [ 'on', 'off' ];
			} elseif ( 'color' === $args['type'] ) {
				$setting['type'] = 'string';
			} elseif ( 'responsive_control' === $args['type'] ) {
				$setting['type'] = [ 'object', 'array' ];
			} elseif ( 'image_sizes' === $args['type'] ) {
				$setting['type'] = 'string';
				$setting['enum'] = array_keys( Helper::get_available_image_sizes() );
			}
			if ( isset( $args['default'] ) ) {
				$setting['default']                     = $args['default'];
				$this->general_setting_defaults[ $key ] = $args['default'];
			}
			if ( isset( $args['choices'] ) && is_array( $args['choices'] ) ) {
				$setting['type'] = 'string';
				foreach ( $args['choices'] as $choice_value => $choice ) {
					if ( is_string( $choice_value ) ) {
						$setting['enum'][] = $choice_value;
					} elseif ( isset( $choice['value'] ) ) {
						$setting['enum'][] = $choice['value'];
					}
				}
			}
			$properties[ $key ] = $setting;
		}

		return $properties;
	}

	/**
	 * Sanitize general settings.
	 *
	 * @param mixed $data Raw data.
	 *
	 * @return array
	 */
	public function sanitize_general_setting( $data ): array {
		if ( ! is_array( $data ) ) {
			return [];
		}

		$sanitized_data = [];
		$field_settings = MetaBoxConfig::get_fields_settings();
		foreach ( $field_settings as $key => $args ) {
			$default = $args['default'] ?? '';
			$value   = $data[ $key ] ?? $default;
			if ( 'number' === $args['type'] ) {
				$sanitized_data[ $key ] = Sanitize::number( $value );
			} elseif ( 'switch' === $args['type'] ) {
				$sanitized_data[ $key ] = Sanitize::checked( $value );
			} elseif ( 'color' === $args['type'] ) {
				$sanitized_data[ $key ] = Sanitize::color( $value );
			} elseif ( 'image_sizes' === $args['type'] ) {
				$sizes                  = array_keys( Helper::get_available_image_sizes() );
				$sanitized_data[ $key ] = in_array( $value, $sizes, true ) ? $value : 'medium_large';
			} else {
				$sanitized_data[ $key ] = Sanitize::deep( $value );
			}
		}

		return $sanitized_data;
	}

	/**
	 * Update slider general settings
	 *
	 * @param int   $slider_id The slider id.
	 * @param array $values The values to be saved.
	 *
	 * @return void
	 */
	public function update_general_setting( int $slider_id, array $values ) {
		$field_settings = MetaBoxConfig::get_fields_settings();
		foreach ( $field_settings as $key => $setting ) {
			$default = $setting['default'] ?? null;
			$value   = $values[ $key ] ?? $default;
			update_post_meta( $slider_id, $setting['id'], $value );
		}
	}

	/**
	 * Generate pagination metadata
	 *
	 * @param int $total_items Total available items.
	 * @param int $per_page Items to show per page.
	 * @param int $current_page The current page.
	 *
	 * @return array
	 */
	protected function get_pagination_data( $total_items = 0, $per_page = 20, $current_page = 1 ): array {
		$current_page = max( intval( $current_page ), 1 );
		$per_page     = max( intval( $per_page ), 1 );
		$total_items  = intval( $total_items );

		return [
			'total_items'  => $total_items,
			'per_page'     => $per_page,
			'current_page' => $current_page,
			'total_pages'  => ceil( $total_items / $per_page ),
		];
	}
}
includes/Helper.php000064400000033573151727276450010335 0ustar00<?php

namespace CarouselSlider;

use CarouselSlider\Interfaces\SliderViewInterface;
use CarouselSlider\Interfaces\TemplateParserInterface;
use WP_Error;
use WP_Post;

defined( 'ABSPATH' ) || exit;

/**
 * Helper class
 */
class Helper extends ViewHelper {
	/**
	 * Get global settings
	 *
	 * @var array
	 */
	protected static $global_settings = [];

	/**
	 * Get placeholder image source.
	 *
	 * Retrieve the source of the placeholder image.
	 *
	 * @return string The source of the default placeholder image used by Elementor.
	 */
	public static function get_placeholder_image_src(): string {
		return apply_filters(
			'carousel_slider/placeholder_image_src',
			CAROUSEL_SLIDER_ASSETS . '/static-images/placeholder.svg'
		);
	}

	/**
	 * Is Elementor plugin active?
	 *
	 * @return bool
	 */
	public static function is_elementor_active(): bool {
		return class_exists( \Elementor\Plugin::class );
	}

	/**
	 * Is Divi builder active?
	 *
	 * @return bool
	 */
	public static function is_divi_builder_active(): bool {
		return ( defined( 'ET_BUILDER_THEME' ) && ET_BUILDER_THEME ) ||
			   class_exists( \ET_Builder_Plugin::class );
	}

	/**
	 * Is WPBakery Page Builder active?
	 *
	 * @return bool
	 */
	public static function is_wp_bakery_page_builder_active(): bool {
		return defined( 'WPB_VC_VERSION' );
	}

	/**
	 * Check if the pro-version is active.
	 *
	 * @return bool
	 */
	public static function is_pro_active(): bool {
		return in_array( 'carousel-slider-pro/carousel-slider-pro.php', get_option( 'active_plugins' ), true );
	}

	/**
	 * Should it show pro-features?
	 *
	 * @return bool
	 */
	public static function show_pro_features(): bool {
		if ( defined( 'CAROUSEL_SLIDER_PRO_PROMOTION' ) ) {
			return CAROUSEL_SLIDER_PRO_PROMOTION;
		}

		return false;
	}

	/**
	 * Get sliders
	 *
	 * @param  array $args  Optional arguments.
	 *
	 * @return WP_Post[]|int[] Array of WP_Post objects or IDs.
	 */
	public static function get_sliders( array $args = [] ): array {
		$args = wp_parse_args(
			$args,
			[
				'post_status'    => 'publish',
				'posts_per_page' => - 1,
				'orderby'        => 'date',
				'order'          => 'DESC',
			]
		);

		$args['post_type'] = CAROUSEL_SLIDER_POST_TYPE;

		return get_posts( $args );
	}

	/**
	 * Get total sliders count
	 *
	 * @return int
	 */
	public static function get_sliders_count(): int {
		global $wpdb;
		$result = (array) $wpdb->get_row(
			$wpdb->prepare(
				"SELECT COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s",
				CAROUSEL_SLIDER_POST_TYPE
			),
			ARRAY_A
		);

		return isset( $result['num_posts'] ) ? intval( $result['num_posts'] ) : 0;
	}

	/**
	 * Get global settings
	 *
	 * @return array
	 */
	public static function get_global_settings(): array {
		if ( empty( static::$global_settings ) ) {
			$default_args = apply_filters(
				'carousel_slider/global_options/default_args',
				[
					'load_scripts'                        => 'optimized',
					'slider_js_package'                   => 'owl.carousel',
					'show_structured_data'                => '1',
					'woocommerce_shop_loop_item_template' => 'v1-compatibility',
					'breakpoints_width'                   => [],
				]
			);
			$options      = get_option( 'carousel_slider_settings', [] );
			$options      = is_array( $options ) ? $options : [];

			static::$global_settings = wp_parse_args( $options, $default_args );
		}

		return static::$global_settings;
	}

	/**
	 * Get setting
	 *
	 * @param  string $key  The setting key.
	 * @param  mixed  $default_value  Setting default value.
	 *
	 * @return mixed|null
	 */
	public static function get_setting( string $key, $default_value = null ) {
		$settings = self::get_global_settings();

		return $settings[ $key ] ?? $default_value;
	}

	/**
	 * Get breakpoint width
	 *
	 * @param  string $prefix  The breakpoint prefix.
	 *
	 * @return int
	 */
	public static function get_breakpoint_width( string $prefix ): int {
		$defaults    = [
			'xs'  => 300,
			'sm'  => 576,
			'md'  => 768,
			'lg'  => 1024,
			'xl'  => 1280,
			'2xl' => 1536,
		];
		$breakpoints = self::get_setting( 'breakpoints_width' );
		$breakpoints = is_array( $breakpoints ) ? $breakpoints : [];
		$breakpoints = wp_parse_args( $breakpoints, $defaults );

		return isset( $breakpoints[ $prefix ] ) && is_int( $breakpoints[ $prefix ] ) ? $breakpoints[ $prefix ] : 0;
	}

	/**
	 * Check if we are using swiper
	 *
	 * @return bool
	 */
	public static function is_using_swiper(): bool {
		$is_swiper = 'swiper' === self::get_setting( 'slider_js_package' );

		return apply_filters( 'carousel_slider/is_using_swiper', $is_swiper );
	}

	/**
	 * Get carousel slider available slide type
	 *
	 * @return array
	 */
	public static function get_slide_types(): array {
		$types = array_map( function ( $args ) {
			return $args['label'];
		}, self::get_slider_types() );

		return apply_filters( 'carousel_slider_slide_type', $types );
	}

	/**
	 * Get slider types
	 *
	 * @return array
	 */
	public static function get_slider_types(): array {
		$slider_types = [
			'image-carousel'     => [
				'label'   => __( 'Image Carousel', 'carousel-slider' ),
				'enabled' => true,
				'icon'    => '<span class="dashicons dashicons-format-image"></span>',
			],
			'image-carousel-url' => [
				'label'   => __( 'Image Carousel (URL)', 'carousel-slider' ),
				'enabled' => true,
				'icon'    => '<span class="dashicons dashicons-admin-links"></span>',
			],
			'post-carousel'      => [
				'label'   => __( 'Post Carousel', 'carousel-slider' ),
				'enabled' => true,
				'icon'    => '<span class="dashicons dashicons-admin-post"></span>',
			],
			'video-carousel'     => [
				'label'   => __( 'Video Carousel', 'carousel-slider' ),
				'enabled' => true,
				'icon'    => '<span class="dashicons dashicons-video-alt3"></span>',
			],
			'hero-banner-slider' => [
				'label'   => __( 'Hero Carousel', 'carousel-slider' ),
				'enabled' => true,
				'icon'    => '<span class="dashicons dashicons-media-interactive"></span>',
			],
			'product-carousel'   => [
				'label'   => __( 'Product Carousel', 'carousel-slider' ),
				'enabled' => self::is_woocommerce_active(),
				'icon'    => '<span class="dashicons dashicons-products"></span>',
			],
		];

		if ( self::show_pro_features() || self::is_pro_active() ) {
			$slider_types['product-carousel-pro'] = [
				'label'   => __( 'Product Carousel (Advance)', 'carousel-slider' ),
				'enabled' => self::is_woocommerce_active() && self::is_pro_active(),
				'icon'    => '<span class="dashicons dashicons-products"></span>',
				'pro'     => true,
			];

			$slider_types['product-categories-list-pro'] = [
				'label'   => __( 'Product Categories List', 'carousel-slider' ),
				'enabled' => self::is_woocommerce_active() && self::is_pro_active(),
				'icon'    => '<span class="dashicons dashicons-category"></span>',
				'pro'     => true,
			];
		}

		return apply_filters( 'carousel_slider/slider_types', $slider_types );
	}

	/**
	 * Get enabled slider types slug
	 *
	 * @return array
	 */
	public static function get_enabled_slider_types_slug(): array {
		$slugs = [];
		foreach ( self::get_slider_types() as $slug => $slider_type ) {
			if ( ! $slider_type['enabled'] ) {
				continue;
			}
			$slugs[] = $slug;
		}

		return $slugs;
	}

	/**
	 * Get slider view
	 *
	 * @param  string $key  The slider type slug.
	 *
	 * @return false|SliderViewInterface
	 */
	public static function get_slider_view( string $key ) {
		$views = apply_filters( 'carousel_slider/register_view', [] );

		return $views[ $key ] ?? false;
	}

	/**
	 * Get slider template parser
	 *
	 * @param  string $key  The slider type slug.
	 *
	 * @return false|TemplateParserInterface
	 */
	public static function get_template_parser( string $key ) {
		$views = apply_filters( 'carousel_slider/template_parser', [] );

		return $views[ $key ] ?? false;
	}

	/**
	 * Get default settings
	 *
	 * @return array
	 */
	public static function get_default_settings(): array {
		return apply_filters(
			'carousel_slider_default_settings',
			[
				'product_title_color'       => '#323232',
				'product_button_bg_color'   => '#00d1b2',
				'product_button_text_color' => '#f1f1f1',
				'nav_color'                 => '#f1f1f1',
				'nav_active_color'          => '#00d1b2',
				'margin_right'              => 10,
				'lazy_load_image'           => 'off',
			]
		);
	}

	/**
	 * Get default setting
	 *
	 * @param  string $key  The setting key.
	 * @param  mixed  $default_value  Default value.
	 *
	 * @return mixed|null
	 */
	public static function get_default_setting( string $key, $default_value = null ) {
		$settings = self::get_default_settings();

		return $settings[ $key ] ?? $default_value;
	}

	/**
	 * Get available image sizes
	 *
	 * @return array
	 */
	public static function get_available_image_sizes(): array {
		global $_wp_additional_image_sizes;

		$sizes = [];
		foreach ( get_intermediate_image_sizes() as $_size ) {
			if ( in_array( $_size, [ 'thumbnail', 'medium', 'medium_large', 'large' ], true ) ) {

				$width  = get_option( "{$_size}_size_w" );
				$height = get_option( "{$_size}_size_h" );
				$crop   = get_option( "{$_size}_crop" ) ? 'hard' : 'soft';

				$sizes[ $_size ] = sprintf( '%s - %s:%sx%s', $_size, $crop, $width, $height );

			} elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {

				$width  = $_wp_additional_image_sizes[ $_size ]['width'];
				$height = $_wp_additional_image_sizes[ $_size ]['height'];
				$crop   = $_wp_additional_image_sizes[ $_size ]['crop'] ? 'hard' : 'soft';

				$sizes[ $_size ] = sprintf( '%s - %s:%sx%s', $_size, $crop, $width, $height );
			}
		}

		return array_merge( $sizes, [ 'full' => 'original uploaded image' ] );
	}

	/**
	 * Check if WooCommerce is active
	 *
	 * @return bool
	 */
	public static function is_woocommerce_active(): bool {
		return in_array( 'woocommerce/woocommerce.php', get_option( 'active_plugins' ), true ) ||
			   defined( 'WC_VERSION' ) ||
			   defined( 'WOOCOMMERCE_VERSION' );
	}

	/**
	 * Creates Carousel Slider test page
	 *
	 * @param  array $ids  The sliders ids.
	 *
	 * @return int|WP_Error
	 */
	public static function create_test_page( array $ids = [] ) {
		$page_path    = 'carousel-slider-test';
		$page_title   = __( 'Carousel Slider Test', 'carousel-slider' );
		$page_content = '';

		if ( empty( $ids ) ) {
			$ids = self::get_sliders();
		}

		foreach ( $ids as $id ) {
			$_post         = get_post( $id );
			$page_content .= '<!-- wp:heading {"level":4} --><h4>' . $_post->post_title . '</h4><!-- /wp:heading -->';
			$page_content .= '<!-- wp:carousel-slider/slider {"sliderID":' . $id . ',"sliderName":"' . $_post->post_title . ' ( ID: ' . $id . ' )"} -->';
			$page_content .= '<div class="wp-block-carousel-slider-slider">[carousel_slide id=\'' . $id . '\']</div>';
			$page_content .= '<!-- /wp:carousel-slider/slider -->';
			$page_content .= '<!-- wp:spacer {"height":100} --><div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div><!-- /wp:spacer -->';
		}

		// Check that the page doesn't exist already.
		$_page     = get_page_by_path( $page_path );
		$page_data = [
			'post_content'   => $page_content,
			'post_name'      => $page_path,
			'post_title'     => $page_title,
			'post_status'    => 'publish',
			'post_type'      => 'page',
			'ping_status'    => 'closed',
			'comment_status' => 'closed',
		];

		if ( $_page instanceof WP_Post ) {
			$page_data['ID'] = $_page->ID;

			return wp_update_post( $page_data );
		}

		return wp_insert_post( $page_data );
	}

	/**
	 * What type of request is this?
	 *
	 * @param  string $type  admin, ajax, rest, cron or frontend.
	 *
	 * @return bool
	 */
	public static function is_request( string $type ): bool {
		switch ( $type ) {
			case 'admin':
				return is_admin();
			case 'ajax':
				return defined( 'DOING_AJAX' );
			case 'rest':
				return defined( 'REST_REQUEST' );
			case 'cron':
				return defined( 'DOING_CRON' );
			case 'frontend':
				return ( ! is_admin() || defined( 'DOING_AJAX' ) ) && ! defined( 'DOING_CRON' );
		}

		return false;
	}

	/**
	 * Create a new slider.
	 *
	 * @param  string $title  The slider title.
	 * @param  string $type  The slider type.
	 * @param  array  $args  Additional arguments.
	 *
	 * @return int|WP_Error The WP_Post ID on success. The value 0 or \WP_Error on failure.
	 */
	public static function create_slider( string $title, string $type = '', array $args = [] ) {
		$data = wp_parse_args(
			$args,
			[
				'post_status'    => 'publish',
				'post_type'      => 'carousels',
				'comment_status' => 'closed',
				'ping_status'    => 'closed',
			]
		);

		$data['post_title'] = $title;
		$data['post_type']  = CAROUSEL_SLIDER_POST_TYPE;

		$post_id = wp_insert_post( $data );

		if ( ! is_wp_error( $post_id ) ) {
			if ( ! empty( $type ) ) {
				update_post_meta( $post_id, '_slide_type', $type );
			}
			update_post_meta( $post_id, '_carousel_slider_version', CAROUSEL_SLIDER_VERSION );
		}

		return $post_id;
	}

	/**
	 * Get preview link
	 *
	 * @param  WP_Post $post  The WP_Post object.
	 *
	 * @return string
	 */
	public static function get_preview_link( WP_Post $post ): string {
		$args = [
			'carousel_slider_preview' => true,
			'carousel_slider_iframe'  => true,
			'slider_id'               => $post->ID,
		];

		return add_query_arg( $args, site_url( '/' ) );
	}

	/**
	 * Print internal content (not user input) without escaping.
	 *
	 * @param  string $html  The string to be print.
	 */
	public static function print_unescaped_internal_string( string $html ) {
		echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}

	/**
	 * Get slider ids from content
	 *
	 * @param  string $content  The content to be tested.
	 *
	 * @return array|int[]
	 */
	public static function get_slider_ids_from_content( string $content ): array {
		$slider_ids = [];
		if ( false === strpos( $content, '[carousel_slide' ) ) {
			return $slider_ids;
		}
		if ( preg_match_all(
			'/(\[carousel_slide)\s*.*id=(\'?\"?)(?P<slider_id>\d+)(\'?\"?)\s*.*(\])/',
			$content,
			$matches
		) ) {
			$slider_ids = array_map( 'intval', $matches['slider_id'] );
		}

		return $slider_ids;
	}
}
includes/Supports/Validate.php000064400000002066151727276450012477 0ustar00<?php

namespace CarouselSlider\Supports;

defined( 'ABSPATH' ) || exit;

/**
 * Validate class
 */
class Validate {
	/**
	 * Check if the url is valid as per RFC 2396 Generic Syntax
	 *
	 * @param mixed $url The URL string.
	 *
	 * @return bool
	 */
	public static function url( $url ): bool {
		return (bool) filter_var( $url, FILTER_VALIDATE_URL );
	}

	/**
	 * If a field has been 'checked' or not, meaning it contains
	 * one of the following values: 'yes', 'on', '1', 1, true, or 'true'.
	 * This can be used for determining if an HTML checkbox has been checked.
	 *
	 * @param mixed $value The value to be checked.
	 *
	 * @return boolean
	 */
	public static function checked( $value ): bool {
		return in_array( $value, [ 'yes', 'on', '1', 1, true, 'true' ], true );
	}

	/**
	 * Check if the value is JSON
	 *
	 * @param mixed $value The value to be checked.
	 *
	 * @return bool
	 */
	public static function json( $value ): bool {
		if ( ! is_string( $value ) ) {
			return false;
		}
		json_decode( $value );

		return ( json_last_error() === JSON_ERROR_NONE );
	}
}
includes/Supports/FormFields/ResponsiveControl.php000064400000012422151727276460016474 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

use CarouselSlider\Helper;

/**
 * ResponsiveControl class
 */
class ResponsiveControl extends BaseField {
	/**
	 * Render field html
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$devices = (array) $this->get_setting( 'device_choices', [] );
		$default = (array) $this->get_setting( 'default', [] );
		$value   = (array) $this->get_value();
		$name    = $this->get_name();

		$html = '<div>';
		foreach ( $devices as $key ) {
			$attr_name  = $name . '[' . $key . ']';
			$attr_value = $value[ $key ] ?? $default[ $key ];

			$html .= '<div class="shapla-dimension">';
			$html .= '<span class="add-on cs-tooltip" title="' . $this->get_breakpoints_label( $key ) . '">' . $this->get_breakpoints_icon( $key ) . '</span>';
			$html .= '<input type="text" name="' . esc_attr( $attr_name ) . '" value="' . esc_attr( $attr_value ) . '">';
			$html .= '</div>';
		}
		$html .= '</div>';

		return $html;
	}

	/**
	 * Get breakpoint info
	 *
	 * @param string $prefix The breakpoint prefix.
	 *
	 * @return string
	 */
	public function get_breakpoints_label( string $prefix ): string {
		$labels = [
			'xs'  => sprintf( 'Extra small device (Mobile): <%spx', Helper::get_breakpoint_width( 'sm' ) ),
			'sm'  => sprintf( 'Small device (Small Tablet): ≥%spx', Helper::get_breakpoint_width( 'sm' ) ),
			'md'  => sprintf( 'Medium device (Tablet): ≥%spx', Helper::get_breakpoint_width( 'md' ) ),
			'lg'  => sprintf( 'Large device (Desktop): ≥%spx', Helper::get_breakpoint_width( 'lg' ) ),
			'xl'  => sprintf( 'Extra large device (Widescreen): ≥%spx', Helper::get_breakpoint_width( 'xl' ) ),
			'2xl' => sprintf( '2X large device (Full HD): ≥%spx', Helper::get_breakpoint_width( '2xl' ) ),
		];

		return $labels[ $prefix ] ?? '';
	}

	/**
	 * Get breakpoint info
	 *
	 * @param string $prefix The breakpoint prefix.
	 *
	 * @return string
	 */
	public function get_breakpoints_icon( string $prefix ): string {
		$icons = [
			'xs'  => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path d="M13 46Q11.8 46 10.9 45.1Q10 44.2 10 43V5Q10 3.8 10.9 2.9Q11.8 2 13 2H35Q36.2 2 37.1 2.9Q38 3.8 38 5V43Q38 44.2 37.1 45.1Q36.2 46 35 46ZM13 38.5H35V9.5H13ZM13 41.5V43Q13 43 13 43Q13 43 13 43H35Q35 43 35 43Q35 43 35 43V41.5ZM13 6.5H35V5Q35 5 35 5Q35 5 35 5H13Q13 5 13 5Q13 5 13 5ZM13 5Q13 5 13 5Q13 5 13 5V6.5V5Q13 5 13 5Q13 5 13 5ZM13 43Q13 43 13 43Q13 43 13 43V41.5V43Q13 43 13 43Q13 43 13 43Z"/></svg>',
			'sm'  => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path d="M5 38Q3.8 38 2.9 37.1Q2 36.2 2 35V13Q2 11.8 2.9 10.9Q3.8 10 5 10H43Q44.2 10 45.1 10.9Q46 11.8 46 13V35Q46 36.2 45.1 37.1Q44.2 38 43 38ZM9.5 35H38.5V13H9.5ZM6.5 35V13H5Q5 13 5 13Q5 13 5 13V35Q5 35 5 35Q5 35 5 35ZM41.5 35H43Q43 35 43 35Q43 35 43 35V13Q43 13 43 13Q43 13 43 13H41.5ZM43 13Q43 13 43 13Q43 13 43 13H41.5H43Q43 13 43 13Q43 13 43 13ZM5 13Q5 13 5 13Q5 13 5 13H6.5H5Q5 13 5 13Q5 13 5 13Z"/></svg>',
			'md'  => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path d="M9 46Q7.75 46 6.875 45.125Q6 44.25 6 43V5Q6 3.75 6.875 2.875Q7.75 2 9 2H39Q40.25 2 41.125 2.875Q42 3.75 42 5V43Q42 44.25 41.125 45.125Q40.25 46 39 46ZM9 35.5H39V9.5H9ZM9 38.5V43Q9 43 9 43Q9 43 9 43H39Q39 43 39 43Q39 43 39 43V38.5ZM9 6.5H39V5Q39 5 39 5Q39 5 39 5H9Q9 5 9 5Q9 5 9 5ZM9 5Q9 5 9 5Q9 5 9 5V6.5V5Q9 5 9 5Q9 5 9 5ZM9 43Q9 43 9 43Q9 43 9 43V38.5V43Q9 43 9 43Q9 43 9 43ZM24 42.25Q24.65 42.25 25.075 41.825Q25.5 41.4 25.5 40.75Q25.5 40.1 25.075 39.675Q24.65 39.25 24 39.25Q23.35 39.25 22.925 39.675Q22.5 40.1 22.5 40.75Q22.5 41.4 22.925 41.825Q23.35 42.25 24 42.25Z"/></svg>',
			'lg'  => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path d="M2.85 40Q1.65 40 0.825 39.125Q0 38.25 0 37H7.05Q5.85 37 4.95 36.1Q4.05 35.2 4.05 34V9Q4.05 7.8 4.95 6.9Q5.85 6 7.05 6H40.95Q42.15 6 43.05 6.9Q43.95 7.8 43.95 9V34Q43.95 35.2 43.05 36.1Q42.15 37 40.95 37H48Q48 38.25 47.125 39.125Q46.25 40 45 40ZM40.95 34Q40.95 34 40.95 34Q40.95 34 40.95 34V9Q40.95 9 40.95 9Q40.95 9 40.95 9H7.05Q7.05 9 7.05 9Q7.05 9 7.05 9V34Q7.05 34 7.05 34Q7.05 34 7.05 34ZM24 38.9Q24.7 38.9 25.2 38.4Q25.7 37.9 25.7 37.2Q25.7 36.5 25.2 36Q24.7 35.5 24 35.5Q23.3 35.5 22.8 36Q22.3 36.5 22.3 37.2Q22.3 37.9 22.8 38.4Q23.3 38.9 24 38.9ZM7.05 34Q7.05 34 7.05 34Q7.05 34 7.05 34V9Q7.05 9 7.05 9Q7.05 9 7.05 9Q7.05 9 7.05 9Q7.05 9 7.05 9V34Q7.05 34 7.05 34Q7.05 34 7.05 34Z"/></svg>',
			'xl'  => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path d="M16.75 44V41H21.05V36H7.05Q5.85 36 4.95 35.1Q4.05 34.2 4.05 33V9Q4.05 7.8 4.95 6.9Q5.85 6 7.05 6H41.05Q42.25 6 43.15 6.9Q44.05 7.8 44.05 9V33Q44.05 34.2 43.15 35.1Q42.25 36 41.05 36H27.05V41H31.35V44ZM7.05 33H41.05Q41.05 33 41.05 33Q41.05 33 41.05 33V9Q41.05 9 41.05 9Q41.05 9 41.05 9H7.05Q7.05 9 7.05 9Q7.05 9 7.05 9V33Q7.05 33 7.05 33Q7.05 33 7.05 33ZM7.05 33Q7.05 33 7.05 33Q7.05 33 7.05 33V9Q7.05 9 7.05 9Q7.05 9 7.05 9Q7.05 9 7.05 9Q7.05 9 7.05 9V33Q7.05 33 7.05 33Q7.05 33 7.05 33Z"/></svg>',
			'2xl' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path d="M16.8 44V42.25L21 38H7Q5.8 38 4.9 37.1Q4 36.2 4 35V9Q4 7.8 4.9 6.9Q5.8 6 7 6H41Q42.2 6 43.1 6.9Q44 7.8 44 9V35Q44 36.2 43.1 37.1Q42.2 38 41 38H27L31.2 42.25V44ZM7 30.2H41V9Q41 9 41 9Q41 9 41 9H7Q7 9 7 9Q7 9 7 9ZM7 30.2V9Q7 9 7 9Q7 9 7 9Q7 9 7 9Q7 9 7 9V30.2Z"/></svg>',
		];

		return $icons[ $prefix ] ?? '';
	}
}
includes/Supports/FormFields/Breakpoint.php000064400000006561151727276460015103 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * Breakpoint class
 */
class Breakpoint extends BaseField {

	/**
	 * Render field
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$value = is_array( $this->get_value() ) ? $this->get_value() : $this->get_defaults();

		$html = '<div class="cs-field--rb-items" data-name="' . $this->get_name() . '">';
		foreach ( $value as $index => $item ) {
			$key_attrs = [
				'type'  => 'text',
				'class' => 'small-text',
				'name'  => sprintf( '%s[%s][key]', $this->get_name(), $index ),
				'value' => $item['key'],
			];

			$breakpoint_attrs = [
				'type'  => 'text',
				'class' => 'small-text',
				'name'  => sprintf( '%s[%s][breakpoint]', $this->get_name(), $index ),
				'value' => $item['breakpoint'],
			];

			$items_attrs = [
				'type'  => 'text',
				'class' => 'small-text',
				'name'  => sprintf( '%s[%s][items]', $this->get_name(), $index ),
				'value' => $item['items'],
			];

			$html .= '<div class="cs-field--rb-item cs-flex cs-mb-4 cs-items-center cs-space-x-1 cs-bg-gray-200 cs-p-2">';
			$html .= '<label>' . esc_html__( 'Key: ', 'carousel-slider' ) . '</label>';
			$html .= '<input ' . $this->array_to_attributes( $key_attrs ) . '>';
			$html .= '<label>' . esc_html__( 'Breakpoint: ', 'carousel-slider' ) . '</label>';
			$html .= '<input ' . $this->array_to_attributes( $breakpoint_attrs ) . '>';
			$html .= '<label>' . esc_html__( 'Items: ', 'carousel-slider' ) . '</label>';
			$html .= '<input ' . $this->array_to_attributes( $items_attrs ) . '>';
			$html .= '<div class="cs-field--rb-item-cross cs-text-red-600 cs-inline-flex cs-items-center cs-justify-center cs-w-8 cs-h-8">';
			$html .= '<span class="cs-field--rb-item-cross-icon dashicons dashicons-remove"></span>';
			$html .= '</div>';
			$html .= '</div>';
		}
		$html .= '</div>';
		$html .= '<div class="cs-mb-4"><button class="button btn--add-new-breakpoint" disabled>';
		$html .= esc_html__( 'Add New Breakpoint', 'carousel-slider' );
		$html .= '</button></div>';

		return $html;
	}

	/**
	 * Get default values
	 *
	 * @return array[]
	 */
	public function get_defaults(): array {
		return [
			[
				'key'        => 'xs',
				'breakpoint' => 300,
				'items'      => 1,
			],
			[
				'key'        => 'sm',
				'breakpoint' => 640,
				'items'      => 2,
			],
			[
				'key'        => 'md',
				'breakpoint' => 768,
				'items'      => 3,
			],
			[
				'key'        => 'lg',
				'breakpoint' => 1024,
				'items'      => 4,
			],
			[
				'key'        => 'xl',
				'breakpoint' => 1280,
				'items'      => 5,
			],
			[
				'key'        => '2xl',
				'breakpoint' => 1536,
				'items'      => 6,
			],
		];
	}

	/**
	 * Sanitized breakpoint value
	 *
	 * @param mixed $value The value to be sanitized.
	 *
	 * @return array
	 */
	public static function sanitize( $value ): array {
		$sanitized_value = [];
		if ( ! is_array( $value ) ) {
			return $sanitized_value;
		}
		foreach ( $value as $item ) {
			if ( ! isset( $item['key'], $item['breakpoint'], $item['items'] ) ) {
				continue;
			}
			$sanitized_value[] = [
				'key'        => sanitize_text_field( $item['key'] ),
				'breakpoint' => intval( $item['breakpoint'] ),
				'items'      => floatval( $item['items'] ),
			];
		}

		usort(
			$sanitized_value,
			function ( array $array1, array $array2 ) {
				return $array1['breakpoint'] - $array2['breakpoint'];
			}
		);

		return $sanitized_value;
	}
}
includes/Supports/FormFields/ImagesGallery.php000064400000002765151727276460015534 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * ImageGallery class
 */
class ImagesGallery extends BaseField {

	/**
	 * Render field html
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		global $post;
		$value = wp_strip_all_tags( rtrim( $this->get_value(), ',' ) );
		$html  = '';

		$button_attr = [
			'href'          => '#',
			'id'            => 'carousel_slider_gallery_btn',
			'class'         => 'button',
			'data-id'       => $post->ID,
			'data-ids'      => $value,
			'data-create'   => esc_html__( 'Create Gallery', 'carousel-slider' ),
			'data-edit'     => esc_html__( 'Edit Gallery', 'carousel-slider' ),
			'data-save'     => esc_html__( 'Save Gallery', 'carousel-slider' ),
			'data-progress' => esc_html__( 'Saving...', 'carousel-slider' ),
			'data-insert'   => esc_html__( 'Insert', 'carousel-slider' ),
		];

		$btn_text = $value ? 'Edit Gallery' : 'Add Gallery';

		$html .= '<div class="carousel_slider_images">';
		$html .= '<input type="hidden" value="' . esc_attr( $value ) . '" id="_carousel_slider_images_ids" name="' . $this->get_name() . '">';
		$html .= '<a ' . $this->array_to_attributes( $button_attr ) . '>' . esc_html( $btn_text ) . '</a>';
		$html .= '<ul class="carousel_slider_gallery_list">';
		if ( $value ) {
			$thumbs = array_map( 'intval', explode( ',', $value ) );
			foreach ( $thumbs as $thumb ) {
				$html .= '<li>' . wp_get_attachment_image( $thumb, [ 50, 50 ] ) . '</li>';
			}
		}
		$html .= '</ul>';
		$html .= '</div>';

		return $html;
	}
}
includes/Supports/FormFields/Textarea.php000064400000001014151727276460014546 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * Textarea class
 */
class Textarea extends BaseField {

	/**
	 * Render field html
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$this->set_setting( 'type', 'textarea' );
		$input_class = $this->get_setting( 'field_class' );
		$this->set_setting( 'field_class', str_replace( 'sp-input-text', 'sp-input-textarea', $input_class ) );

		return '<textarea ' . $this->build_attributes() . '>' . esc_textarea( $this->get_value() ) . '</textarea>';
	}
}
includes/Supports/FormFields/CheckboxSwitch.php000064400000001567151727276460015716 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * CheckboxSwitch class
 */
class CheckboxSwitch extends BaseField {

	/**
	 * Render html content
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$attributes = array(
			'type'    => 'checkbox',
			'id'      => $this->get_setting( 'id' ),
			'class'   => 'screen-reader-text',
			'name'    => $this->get_name(),
			'value'   => 'on',
			'checked' => 'on' === $this->get_value(),
		);

		$html  = '<div class="switch-container">';
		$html .= '<input type="hidden" name="' . $this->get_name() . '" value="off">';
		$html .= '<label for="' . $this->get_setting( 'id' ) . '" class="switch-label">';
		$html .= '<input ' . $this->array_to_attributes( $attributes ) . '>';
		$html .= '<span class="switch">' . $this->get_setting( 'label' ) . '</span>';
		$html .= '</label>';
		$html .= '</div>';

		return $html;
	}
}
includes/Supports/FormFields/Select.php000064400000002475151727276460014224 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

use CarouselSlider\Supports\Validate;

/**
 * Select class
 */
class Select extends BaseField {

	/**
	 * Render field html
	 *
	 * @inerhitDoc
	 */
	public function render(): string {
		$choices = $this->get_setting( 'choices' );
		if ( Validate::checked( $this->get_setting( 'searchable' ) ) ) {
			$this->set_setting( 'field_class', $this->get_setting( 'field_class' ) . ' select2' );
		}
		$this->set_setting( 'type', 'select' );

		$is_multiple = $this->get_setting( 'multiple' );
		$value       = $this->get_value();
		if ( $is_multiple && is_string( $value ) ) {
			$value = explode( ',', wp_strip_all_tags( rtrim( $value, ',' ) ) );
		}
		$html = '<select ' . $this->build_attributes() . '>';
		foreach ( $choices as $key => $choice ) {
			if ( ! is_array( $choice ) ) {
				$choice = [
					'value' => $key,
					'label' => $choice,
				];
			}
			if ( $is_multiple ) {
				$selected = in_array( $choice['value'], $value ) ? 'selected' : ''; // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
			} else {
				$selected = $this->get_value() === $choice['value'] ? 'selected' : '';
			}
			$html .= '<option value="' . esc_attr( $choice['value'] ) . '" ' . $selected . '>' . esc_html( $choice['label'] ) . '</option>';
		}
		$html .= '</select>';

		return $html;
	}
}
includes/Supports/FormFields/Radio.php000064400000002647151727276460014044 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * Radio class
 */
class Radio extends BaseField {

	/**
	 * Render html content
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$value = $this->get_value();
		$name  = $this->get_name();

		$html  = '<fieldset id="' . esc_attr( $this->get_setting( 'id' ) ) . '" class="radio-container">';
		$html .= '<legend class="screen-reader-text"><span>' . esc_html( $this->get_setting( 'label' ) ) . '</span></legend>';
		foreach ( $this->get_setting( 'choices' ) as $key => $choice ) {
			if ( ! is_array( $choice ) ) {
				$choice = [
					'value' => $key,
					'label' => $choice,
				];
			}
			$id          = sprintf( '%s-%s', $this->get_setting( 'id' ), $choice['value'] );
			$label_class = sprintf( 'radio-label radio-label-%s', ( $choice['value'] === $value ) ? 'on' : 'off' );
			$radio_attr  = [
				'type'    => 'radio',
				'name'    => $name,
				'id'      => $id,
				'class'   => 'radio-input',
				'value'   => $choice['value'],
				'checked' => $choice['value'] === $value,
			];

			$html .= '<label class="' . esc_attr( $label_class ) . '" for="' . esc_attr( $id ) . '">';
			$html .= '<input ' . $this->array_to_attributes( $radio_attr ) . ' />';
			$html .= '<span>' . esc_html( $choice['label'] ) . '</span>';
			$html .= '</label>';
			$html .= 'inline' === $this->get_setting( 'display' ) ? ' ' : '<br>';
		}

		$html .= '</fieldset>';

		return $html;
	}
}
includes/Supports/FormFields/ButtonGroup.php000064400000003565151727276460015276 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

use CarouselSlider\Helper;

/**
 * ButtonGroup class
 */
class ButtonGroup extends BaseField {

	/**
	 * Render field html
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$value = $this->get_value();
		$name  = $this->get_name();

		$html = '<div id="' . esc_attr( $this->get_setting( 'id' ) ) . '" class="buttonset">';
		foreach ( $this->get_setting( 'choices' ) as $key => $choice ) {
			if ( ! is_array( $choice ) ) {
				$choice = [
					'value' => $key,
					'label' => $choice,
				];
			}
			$is_pro_only = isset( $choice['pro_only'] ) && $choice['pro_only'];
			if ( $is_pro_only && Helper::show_pro_features() === false ) {
				continue;
			}
			if ( $is_pro_only && ! Helper::is_pro_active() ) {
				$name = sprintf( 'need_pro_%s', $name );
			}
			$id          = sprintf( '%s-%s', $this->get_setting( 'id' ), $choice['value'] );
			$label_class = sprintf( 'switch-label switch-label-%s', ( $choice['value'] === $value ) ? 'on' : 'off' );
			$radio_attr  = [
				'type'    => 'radio',
				'name'    => $name,
				'id'      => $id,
				'class'   => 'switch-input screen-reader-text',
				'value'   => $choice['value'],
				'checked' => $choice['value'] === $value,
			];
			if (
				( isset( $choice['disabled'] ) && $choice['disabled'] ) ||
				( $is_pro_only && ! Helper::is_pro_active() )
			) {
				$radio_attr['disabled'] = true;
			}
			if ( $is_pro_only ) {
				$label_class .= ' has-pro-tag';
				$label        = esc_html( $choice['label'] ) . '<span class="pro-only">' . esc_html__( 'pro', 'carousel-slider' ) . '</span>';
			} else {
				$label = esc_html( $choice['label'] );
			}
			$html .= '<input ' . $this->array_to_attributes( $radio_attr ) . ' />';
			$html .= '<label class="' . esc_attr( $label_class ) . '" for="' . esc_attr( $id ) . '">' . $label . '</label>';
		}

		$html .= '</div>';

		return $html;
	}
}
includes/Supports/FormFields/BaseField.php000064400000013552151727276460014621 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

use CarouselSlider\Interfaces\FieldInterface;

/**
 * BaseField class
 */
abstract class BaseField implements FieldInterface {
	/**
	 * Field settings
	 *
	 * @var array
	 */
	protected $settings = [];

	/**
	 * The name to be used for input field name
	 *
	 * @var string
	 */
	protected $name;

	/**
	 * The value of the field
	 *
	 * @var mixed
	 */
	protected $value;

	/**
	 * Render field
	 *
	 * @return string
	 */
	abstract public function render(): string;

	/**
	 * Get setting
	 *
	 * @param string $key The setting key.
	 * @param mixed  $default_value The default value for the setting.
	 *
	 * @return mixed
	 */
	public function get_setting( string $key, $default_value = null ) {
		return $this->settings[ $key ] ?? $default_value;
	}

	/**
	 * Set setting
	 *
	 * @param string $key The setting key.
	 * @param mixed  $value The value for the setting.
	 */
	public function set_setting( string $key, $value ) {
		$this->settings[ $key ] = $value;
	}

	/**
	 * Get settings
	 *
	 * @return array
	 */
	public function get_settings(): array {
		return $this->settings;
	}

	/**
	 * Set Settings
	 *
	 * @param array $settings The field settings.
	 */
	public function set_settings( array $settings ) {
		$default        = [
			'type'        => 'text',
			'id'          => '',
			'section'     => 'default',
			'label'       => '',
			'description' => '',
			'priority'    => 10,
			'default'     => '',
			'choices'     => [],
			'field_class' => 'sp-input-text',
			'label_class' => '',
		];
		$this->settings = wp_parse_args( $settings, $default );
	}

	/**
	 * Get name
	 *
	 * @return string
	 */
	public function get_name(): string {
		return $this->name;
	}

	/**
	 * Set name
	 *
	 * @param string $name The name of the field.
	 */
	public function set_name( string $name ) {
		$this->name = $name;
	}

	/**
	 * Get value
	 *
	 * @return mixed
	 */
	public function get_value() {
		return $this->value;
	}

	/**
	 * Set value
	 *
	 * @param mixed $value The value of the field.
	 */
	public function set_value( $value ) {
		$this->value = $value;
	}

	/**
	 * Generate input attribute
	 *
	 * @param bool $to_string Convert attribute to string.
	 *
	 * @return array|string
	 */
	protected function build_attributes( bool $to_string = true ) {
		$input_type = $this->get_setting( 'type' );
		$attributes = [
			'id'          => $this->get_setting( 'id' ),
			'class'       => $this->get_setting( 'field_class' ),
			'name'        => $this->get_name(),
			'placeholder' => $this->get_setting( 'placeholder' ),
		];

		if ( ! in_array( $input_type, [ 'textarea', 'select' ], true ) ) {
			$attributes['type'] = $input_type;
		}

		$this->add_extra_attributes( $attributes );

		$input_attributes = (array) $this->get_setting( 'input_attributes' );
		foreach ( $input_attributes as $attr_name => $attr_val ) {
			$attributes[ $attr_name ] = $attr_val;
		}

		if ( $to_string ) {
			return $this->array_to_attributes( $attributes );
		}

		return array_filter( $attributes );
	}

	/**
	 * Convert array to input attributes
	 *
	 * @param array $attributes The attribute list.
	 *
	 * @return string
	 */
	protected function array_to_attributes( array $attributes ): string {
		$string = array_map(
			function ( $key, $value ) {
				if ( empty( $value ) && 'value' !== $key ) {
					return null;
				}
				if ( in_array( $key, array( 'required', 'checked', 'multiple', 'disabled' ), true ) && $value ) {
					return $key;
				}

				// If boolean value.
				if ( is_bool( $value ) ) {
					return sprintf( '%s="%s"', $key, $value ? 'true' : 'false' );
				}

				// If array value.
				if ( is_array( $value ) ) {
					return sprintf( '%s="%s"', $key, implode( ',', $value ) );
				}

				// If string value.
				return sprintf( '%s="%s"', $key, esc_attr( $value ) );
			},
			array_keys( $attributes ),
			array_values( $attributes )
		);

		return implode( ' ', array_filter( $string ) );
	}

	/**
	 * Add extra attributes
	 *
	 * @param array $attributes The attribute list.
	 */
	protected function add_extra_attributes( array &$attributes ) {
		$input_type       = $this->get_setting( 'type' );
		$extra_attributes = [
			[
				'include_types' => [ 'textarea' ],
				'attrs'         => [ 'rows' => $this->get_setting( 'rows' ) ],
			],
			[
				'include_types' => [ 'file' ],
				'attrs'         => [ 'accept' => $this->get_setting( 'accept' ) ],
			],
			[
				'include_types' => [ 'number', 'date' ],
				'attrs'         => [
					'max' => $this->get_setting( 'max' ),
					'min' => $this->get_setting( 'min' ),
				],
			],
			[
				'include_types' => [ 'number' ],
				'attrs'         => [ 'step' => $this->get_setting( 'step' ) ],
			],
			[
				'include_types' => [ 'email', 'file', 'select' ],
				'attrs'         => [ 'multiple' => $this->get_setting( 'multiple' ) ],
			],
			[
				'include_types' => [ 'hidden' ],
				'attrs'         => [
					'spellcheck'   => 'false',
					'tabindex'     => '-1',
					'autocomplete' => 'off',
				],
			],
			[
				'exclude_types' => [ 'textarea', 'file' ],
				'attrs'         => [ 'autocomplete' => $this->get_setting( 'autocomplete' ) ],
			],
			[
				'exclude_types' => [ 'textarea', 'file', 'password', 'select' ],
				'attrs'         => [ 'value' => $this->get_value() ],
			],
			[
				'exclude_types' => [ 'hidden', 'image', 'submit', 'reset', 'button' ],
				'attrs'         => [ 'required' => $this->get_setting( 'required' ) ],
			],
		];

		foreach ( $extra_attributes as $attribute ) {
			if ( isset( $attribute['include_types'] ) && in_array( $input_type, $attribute['include_types'], true ) ) {
				foreach ( $attribute['attrs'] as $attr_key => $attr_val ) {
					$attributes[ $attr_key ] = $attr_val;
				}
			}
			if ( isset( $attribute['exclude_types'] ) && ! in_array( $input_type, $attribute['exclude_types'], true ) ) {
				foreach ( $attribute['attrs'] as $attr_key => $attr_val ) {
					$attributes[ $attr_key ] = $attr_val;
				}
			}
		}
	}
}
includes/Supports/FormFields/ImageUrl.php000064400000001372151727276460014505 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * ImageUrl class
 */
class ImageUrl extends BaseField {

	/**
	 * Render html content
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$value    = $this->get_value();
		$btn_text = $value ? __( 'Edit URLs', 'carousel-slider' ) : __( 'Add URLs', 'carousel-slider' );

		$html  = sprintf( '<a id="_images_urls_btn" class="button" href="#">%s</a>', $btn_text );
		$html .= '<ul class="carousel_slider_url_images_list">';
		if ( is_array( $value ) && count( $value ) > 0 ) {
			foreach ( $value as $image ) {
				$html .= '<li><img src="' . esc_url( $image['url'] ) . '" alt="' . esc_attr( $image['alt'] ) . '" width="75" height="75"></li>';
			}
		}
		$html .= '</ul>';

		return $html;
	}
}
includes/Supports/FormFields/SelectTerms.php000064400000001171151727276460015227 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * TermsList class
 */
class SelectTerms extends Select {
	/**
	 * Render field html
	 *
	 * @inerhitDoc
	 */
	public function render(): string {
		$this->set_setting( 'searchable', true );
		$terms   = get_terms( [ 'taxonomy' => $this->get_setting( 'taxonomy', 'category' ) ] );
		$choices = [];
		if ( ! is_wp_error( $terms ) ) {
			foreach ( $terms as $term ) {
				$choices[] = [
					'value' => $term->term_id,
					'label' => sprintf( '%s (%s)', $term->name, $term->count ),
				];
			}
		}
		$this->set_setting( 'choices', $choices );

		return parent::render();
	}
}
includes/Supports/FormFields/Color.php000064400000001174151727276470014057 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * Color class
 */
class Color extends BaseField {

	/**
	 * Render field html
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$input_attributes = (array) $this->get_setting( 'input_attributes' );
		$this->set_setting( 'type', 'text' );
		$this->set_setting( 'field_class', 'color-picker' );
		$this->set_setting(
			'input_attributes',
			array_merge(
				$input_attributes,
				[
					'data-alpha-enabled' => 'true',
					'data-default-color' => $this->get_setting( 'default' ),
				]
			)
		);

		return '<br><input ' . $this->build_attributes() . ' />';
	}
}
includes/Supports/FormFields/MultiCheckbox.php000064400000002466151727276470015547 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * MultiCheckbox class
 */
class MultiCheckbox extends BaseField {

	/**
	 * Render field
	 *
	 * @return string
	 */
	public function render(): string {
		$this->set_setting( 'multiple', true );
		$choices = $this->get_setting( 'choices' );
		$value   = $this->get_value();
		if ( is_string( $value ) ) {
			$value = explode( ',', wp_strip_all_tags( rtrim( $value, ',' ) ) );
		}
		$html = '';
		foreach ( $choices as $key => $choice ) {
			if ( ! is_array( $choice ) ) {
				$choice = [
					'value' => $key,
					'label' => $choice,
				];
			}
			$id         = sprintf( '%s_%s', $this->get_setting( 'id' ), $choice['value'] );
			$selected   = in_array( $choice['value'], $value ) ? 'selected' : ''; // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
			$attributes = array(
				'type'    => 'checkbox',
				'id'      => $id,
				'name'    => $this->get_name() . '[]',
				'value'   => $choice['value'],
				'checked' => $selected,
			);
			if ( isset( $choice['readonly'] ) ) {
				$attributes['disabled'] = true;
			}
			$html .= '<label for="' . $id . '">';
			$html .= '<input ' . $this->array_to_attributes( $attributes ) . '>';
			$html .= '<span>' . esc_html( $choice['label'] ) . '</span></label><br>';
		}
		$html .= '</select>';

		return $html;
	}
}
includes/Supports/FormFields/Checkbox.php000064400000001562151727276470014530 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * Checkbox class
 */
class Checkbox extends BaseField {

	/**
	 * Render field html
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$true_value  = $this->get_setting( 'true_value', 'on' );
		$false_value = $this->get_setting( 'false_value', 'off' );

		$attributes = array(
			'type'    => 'checkbox',
			'id'      => $this->get_setting( 'id' ),
			'name'    => $this->get_name(),
			'value'   => $true_value,
			'checked' => $true_value === $this->get_value(),
		);

		$html  = '<input type="hidden" name="' . $this->get_name() . '" value="' . esc_attr( $false_value ) . '">';
		$html .= '<label for="' . $this->get_setting( 'id' ) . '">';
		$html .= '<input ' . $this->array_to_attributes( $attributes ) . '>';
		$html .= '<span>' . $this->get_setting( 'label' ) . '</span></label>';

		return $html;
	}
}
includes/Supports/FormFields/ImageUploader.php000064400000002101151727276470015506 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

use CarouselSlider\Helper;

/**
 * ImageUploader class
 */
class ImageUploader extends BaseField {

	/**
	 * Render html content
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$value       = $this->get_value();
		$button_text = $value ? __( 'Update Image', 'carousel-slider' ) : __( 'Set Image', 'carousel-slider' );
		global $post;
		$attrs = [
			'class'            => 'button slide_image_add',
			'href'             => esc_url( get_upload_iframe_src( 'image', $post->ID ) ),
			'data-title'       => esc_attr__( 'Select or Upload Slide Background Image', 'carousel-slider' ),
			'data-button-text' => esc_attr( $button_text ),
		];

		$input_attrs = [
			'type'  => 'hidden',
			'class' => $this->get_setting( 'field_class' ),
			'name'  => $this->get_name(),
			'value' => $value,
		];

		$html  = '<input ' . implode( ' ', Helper::array_to_attribute( $input_attrs ) ) . ' />';
		$html .= '<a ' . implode( ' ', Helper::array_to_attribute( $attrs ) ) . '>' . esc_html( $button_text ) . '</a>';

		return $html;
	}
}
includes/Supports/FormFields/Html.php000064400000000466151727276470013710 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * HTML class
 */
class Html extends BaseField {

	/**
	 * Render field
	 *
	 * @return string
	 */
	public function render(): string {
		$html = $this->get_setting( 'html', '' );
		if ( ! is_string( $html ) ) {
			return '';
		}

		return $html;
	}
}
includes/Supports/FormFields/Text.php000064400000000401151727276500013707 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * Text class
 */
class Text extends BaseField {

	/**
	 * Render field html
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		return '<input ' . $this->build_attributes() . ' />';
	}
}
includes/Supports/FormFields/Spacing.php000064400000002272151727276500014357 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * Spacing class
 */
class Spacing extends BaseField {

	/**
	 * Render field html
	 *
	 * @inheritDoc
	 */
	public function render(): string {
		$default = (array) $this->get_setting( 'default', [] );
		$value   = (array) $this->get_value();
		$name    = $this->get_name();

		$html       = '';
		$dimensions = [ 'top', 'right', 'bottom', 'left' ];
		foreach ( $dimensions as $dimension ) {
			if ( ! array_key_exists( $dimension, $default ) ) {
				continue;
			}

			$attr_name  = $name . '[' . $dimension . ']';
			$attr_value = $value[ $dimension ] ?? $default[ $dimension ];
			if ( 'top' === $dimension ) {
				$icon_class = 'dashicons dashicons-arrow-up-alt';
			} elseif ( 'bottom' === $dimension ) {
				$icon_class = 'dashicons dashicons-arrow-down-alt';
			} else {
				$icon_class = 'dashicons dashicons-arrow-' . $dimension . '-alt';
			}

			$html .= '<div class="shapla-dimension">';
			$html .= '<span class="add-on"><i class="' . esc_attr( $icon_class ) . '"></i></span>';
			$html .= '<input type="text" name="' . esc_attr( $attr_name ) . '" value="' . esc_attr( $attr_value ) . '">';
			$html .= '</div>';
		}

		return $html;
	}
}
includes/Supports/FormFields/SelectImageSize.php000064400000000533151727276500016006 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

use CarouselSlider\Helper;

/**
 * SelectImageSize class
 */
class SelectImageSize extends Select {
	/**
	 * Render field html
	 *
	 * @inerhitDoc
	 */
	public function render(): string {
		$this->set_setting( 'choices', Helper::get_available_image_sizes() );

		return parent::render();
	}
}
includes/Supports/FormFields/SelectPosts.php000064400000001171151727276500015240 0ustar00<?php

namespace CarouselSlider\Supports\FormFields;

/**
 * PostsList class
 */
class SelectPosts extends Select {
	/**
	 * Render field html
	 *
	 * @inerhitDoc
	 */
	public function render(): string {
		$this->set_setting( 'searchable', true );
		$posts = get_posts(
			[
				'post_type'      => $this->get_setting( 'post_type', 'post' ),
				'post_status'    => 'publish',
				'posts_per_page' => - 1,
			]
		);

		$choices = [];
		foreach ( $posts as $post ) {
			$choices[] = [
				'value' => $post->ID,
				'label' => $post->post_title,
			];
		}

		$this->set_setting( 'choices', $choices );

		return parent::render();
	}
}
includes/Supports/MetaBoxForm.php000064400000015564151727276500013134 0ustar00<?php

namespace CarouselSlider\Supports;

use CarouselSlider\Helper;
use CarouselSlider\Interfaces\FieldInterface;
use CarouselSlider\Supports\FormFields\BaseField;
use CarouselSlider\Supports\FormFields\Breakpoint;
use CarouselSlider\Supports\FormFields\ButtonGroup;
use CarouselSlider\Supports\FormFields\Checkbox;
use CarouselSlider\Supports\FormFields\CheckboxSwitch;
use CarouselSlider\Supports\FormFields\Color;
use CarouselSlider\Supports\FormFields\ResponsiveControl;
use CarouselSlider\Supports\FormFields\ImagesGallery;
use CarouselSlider\Supports\FormFields\ImageUploader;
use CarouselSlider\Supports\FormFields\ImageUrl;
use CarouselSlider\Supports\FormFields\Radio;
use CarouselSlider\Supports\FormFields\SelectImageSize;
use CarouselSlider\Supports\FormFields\SelectPosts;
use CarouselSlider\Supports\FormFields\Select;
use CarouselSlider\Supports\FormFields\Spacing;
use CarouselSlider\Supports\FormFields\SelectTerms;
use CarouselSlider\Supports\FormFields\Text;
use CarouselSlider\Supports\FormFields\Textarea;

defined( 'ABSPATH' ) || exit;

/**
 * MetaBoxForm class
 *
 * @method void text( array $args )
 * @method void date( array $args )
 * @method void textarea( array $args )
 * @method void spacing( array $args )
 * @method void button_group( array $args )
 * @method void color( array $args )
 * @method void images_gallery( array $args )
 * @method void upload_iframe( array $args )
 * @method void images_url( array $args )
 * @method void posts_list( array $args )
 * @method void number( array $args )
 * @method void checkbox( array $args )
 * @method void post_terms( array $args )
 * @method void image_sizes( array $args )
 * @method void radio( array $args )
 * @method void switch ( array $args )
 * @method void select( array $args )
 * @method void breakpoint( array $args )
 */
class MetaBoxForm {

	/**
	 * Map field settings
	 *
	 * @param array $settings The settings arguments.
	 *
	 * @return array
	 */
	private static function map_field_settings( array $settings ): array {
		$attrs = [
			'name'    => 'label',
			'title'   => 'label',
			'desc'    => 'description',
			'class'   => 'field_class',
			'options' => 'choices',
			'std'     => 'default',
		];
		foreach ( $settings as $key => $value ) {
			if ( isset( $attrs[ $key ] ) ) {
				$settings[ $attrs[ $key ] ] = $value;
				unset( $settings[ $key ] );
			}
		}

		return $settings;
	}

	/**
	 * Get field class
	 *
	 * @param string $type The field type.
	 *
	 * @return BaseField|FieldInterface
	 */
	private static function get_field_class( string $type = 'text' ) {
		$types = [
			'text'               => Text::class,
			'textarea'           => Textarea::class,
			'spacing'            => Spacing::class,
			'checkbox'           => Checkbox::class,
			'button_group'       => ButtonGroup::class,
			'color'              => Color::class,
			'images_gallery'     => ImagesGallery::class,
			'upload_iframe'      => ImageUploader::class,
			'images_url'         => ImageUrl::class,
			'select'             => Select::class,
			'posts_list'         => SelectPosts::class,
			'post_terms'         => SelectTerms::class,
			'image_sizes'        => SelectImageSize::class,
			'radio'              => Radio::class,
			'switch'             => CheckboxSwitch::class,
			'breakpoint'         => Breakpoint::class,
			'responsive_control' => ResponsiveControl::class,
		];

		$class = array_key_exists( $type, $types ) ? $types[ $type ] : $types['text'];

		return new $class();
	}

	/**
	 * Generate field name and field value
	 *
	 * @param array $args The settings arguments.
	 *
	 * @return array
	 */
	private static function get_name_and_value( array $args ): array {
		global $post;
		$input_attributes = $args['input_attributes'] ?? [];
		// Meta Name.
		if ( isset( $input_attributes['name'] ) ) {
			$name = $input_attributes['name'];
		} else {
			$group    = $args['group'] ?? 'carousel_slider';
			$multiple = isset( $args['multiple'] ) ? '[]' : '';
			$name     = sprintf( '%s[%s]%s', $group, $args['id'], $multiple );
		}

		// Meta Value.
		$default = $args['default'] ?? '';
		if ( isset( $input_attributes['value'] ) ) {
			$value = ! empty( $input_attributes['value'] ) ? $input_attributes['value'] : $default;
		} else {
			$meta  = get_post_meta( $post->ID, $args['id'], true );
			$value = ! empty( $meta ) ? $meta : $default;
		}

		if ( 'zero' === $value ) {
			$value = 0;
		}

		return [ $name, $value ];
	}

	/**
	 * Generate field before template
	 *
	 * @param array $args The settings arguments.
	 *
	 * @return string
	 */
	private static function field_before( array $args ): string {
		$_normal  = sprintf( '<div class="sp-input-group" id="field-%s">', $args['id'] );
		$_normal .= '<div class="sp-input-label">';
		$_normal .= sprintf( '<label for="%1$s">%2$s</label>', $args['id'], $args['label'] ?? '' );
		if ( ! empty( $args['description'] ) ) {
			$_normal .= sprintf( '<p class="sp-input-desc">%s</p>', $args['description'] );
		}
		$_normal .= '</div>';
		$_normal .= '<div class="sp-input-field">';

		if ( isset( $args['context'] ) && 'side' === $args['context'] ) {
			$_side  = '<div id="field-' . $args['id'] . '" class="cs-flex cs-flex-wrap cs-justify-between cs-my-4">';
			$_side .= '<span class="cs-inline-flex cs-space-x-1">';
			$_side .= '<label for="' . $args['id'] . '"><strong>' . $args['label'] . '</strong></label>';
			if ( ! empty( $args['description'] ) ) {
				$_side .= '<span class="cs-tooltip" title="' . esc_attr( $args['description'] ) . '"></span>';
			}
			$_side .= '</span>';

			return $_side;
		}

		return $_normal;
	}

	/**
	 * Generate field after template
	 *
	 * @param array $args The settings arguments.
	 *
	 * @return string
	 */
	private static function field_after( array $args = [] ): string {

		if ( isset( $args['context'] ) && 'side' === $args['context'] ) {
			return '</div>';
		}

		return '</div></div>';
	}

	/**
	 * Generate text field
	 *
	 * @param array $args The settings arguments.
	 *
	 * @return string
	 */
	public static function field( array $args ): string {
		$is_pro_only = isset( $args['pro_only'] ) && $args['pro_only'];
		if ( $is_pro_only && Helper::show_pro_features() === false ) {
			return '';
		}
		$settings = self::map_field_settings( $args );

		list( $name, $value ) = self::get_name_and_value( $settings );

		$field = self::get_field_class( $args['type'] ?? 'text' );
		$field->set_settings( $settings );
		$field->set_name( $name );
		$field->set_value( $value );

		$html  = self::field_before( $settings );
		$html .= $field->render();
		$html .= self::field_after( $settings );

		return $html;
	}

	/**
	 * Handle wildcard method call
	 *
	 * @param string $name The method name.
	 * @param array  $arguments The arguments for the method.
	 *
	 * @return void
	 */
	public function __call( string $name, array $arguments = [] ) {
		$args = array_merge( ( is_array( $arguments[0] ) ? $arguments[0] : [] ), [ 'type' => $name ] );
		Helper::print_unescaped_internal_string( self::field( $args ) );
	}
}
includes/Supports/SettingApi/DefaultSettingApi.php000064400000025152151727276500016366 0ustar00<?php

namespace CarouselSlider\Supports\SettingApi;

use CarouselSlider\Helper;
use CarouselSlider\Interfaces\FormBuilderInterface;

defined( 'ABSPATH' ) || exit;

/**
 * DefaultSettingApi class
 */
class DefaultSettingApi extends SettingApi {

    /**
     * Setting page form action attribute value
     *
     * @var string
     */
    protected $action = 'options.php';

    /**
     * The FormBuilder class
     *
     * @var FormBuilder
     */
    protected $form_builder;

    /**
     * Class constructor
     */
    public function __construct() {
        if ( is_admin() ) {
            add_action( 'admin_init', array( $this, 'register_setting' ) );
            add_action( 'admin_menu', array( $this, 'add_menu_page' ) );
        }
    }

    /**
     * Register setting and its sanitized callback.
     */
    public function register_setting() {
        register_setting(
                $this->get_option_name(),
                $this->get_option_name(),
                array( 'sanitize_callback' => array( $this, 'sanitize_callback' ) )
        );
    }

    /**
     * Sanitize each setting field as needed
     *
     * @param  array|mixed  $input  Contains all settings fields as array keys.
     *
     * @return array
     */
    public function sanitize_callback( $input ): array {
        return $this->sanitize_options( is_array( $input ) ? $input : array() );
    }

    /**
     * Create admin menu
     */
    public function add_menu_page() {
        $page_title  = $this->menu_fields['page_title'];
        $menu_title  = $this->menu_fields['menu_title'];
        $menu_slug   = $this->menu_fields['menu_slug'];
        $capability  = $this->menu_fields['capability'] ?? 'manage_options';
        $parent_slug = $this->menu_fields['parent_slug'] ?? null;

        if ( $parent_slug ) {
            add_submenu_page(
                    $parent_slug,
                    $page_title,
                    $menu_title,
                    $capability,
                    $menu_slug,
                    array( $this, 'page_content' )
            );
        } else {
            add_menu_page( $page_title, $menu_title, $capability, $menu_slug, array( $this, 'page_content' ) );
        }
    }

    /**
     * Load page content
     */
    public function page_content() {
        $options     = $this->get_options();
        $option_name = $this->get_option_name();

        $has_sections = false;
        $panel        = '';
        $sections     = array();
        if ( $this->has_panels() ) {
            $panels_ids   = wp_list_pluck( $this->get_panels(), 'id' );
            $current_tab  = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $panel        = in_array( $current_tab, $panels_ids, true ) ? $current_tab : $panels_ids[0];
            $sections     = $this->get_sections_by_panel( $panel );
            $has_sections = count( $sections ) > 0;
        }
        $panel_setting      = $this->get_panel( $panel );
        $hide_submit_button = false;
        if ( is_array( $panel_setting ) ) {
            $hide_submit_button = isset( $panel_setting['hide_submit_button'] ) && $panel_setting['hide_submit_button'];
        }
        ob_start(); ?>
        <div class="wrap">
            <h1><?php echo esc_html( $this->menu_fields['page_title'] ); ?></h1>
            <hr class="wp-header-end">
            <?php if ( ! empty( $this->menu_fields['about_text'] ) ) { ?>
                <div class="about-text"><?php echo esc_html( $this->menu_fields['about_text'] ); ?></div>
            <?php } ?>
            <?php
            if ( $this->has_panels() ) {
                Helper::print_unescaped_internal_string( $this->option_page_tabs() );
            }
            ?>
            <form autocomplete="off" method="POST" action="<?php echo esc_attr( $this->action ); ?>">
                <?php
                settings_fields( $option_name );
                if ( $has_sections ) {
                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                    $html = $this->get_fields_html_by_section( $sections, $panel );
                } else {
                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                    $html = $this->get_form_builder()->get_fields_html(
                            $this->filter_fields_by_tab(),
                            $option_name,
                            $options
                    );
                }
                Helper::print_unescaped_internal_string( $html );
                if ( false === $hide_submit_button ) {
                    submit_button();
                }
                ?>
            </form>
        </div>
        <?php
        echo ob_get_clean(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }

    /**
     * Get field HTML by section
     *
     * @param  array  $sections  Array of a section.
     * @param  string|null  $panel  Panel id.
     *
     * @return string
     */
    public function get_fields_html_by_section( array $sections = array(), string $panel = '' ): string {
        $options     = $this->get_options();
        $option_name = $this->get_option_name();

        $table = '';
        foreach ( $sections as $section ) {
            if ( ! empty( $section['title'] ) ) {
                $table .= '<h2 id="title--' . esc_attr( $section['id'] ) . '" class="title">' . esc_html( $section['title'] ) . '</h2>';
            }
            if ( ! empty( $section['description'] ) ) {
                $table .= '<p class="description">' . esc_js( $section['description'] ) . '</p>';
            }

            $fields = $this->get_fields_by( $section['id'], $panel );
            $table  .= $this->get_form_builder()->get_fields_html( $fields, $option_name, $options );
        }

        return $table;
    }

    /**
     * Generate Option Page Tabs
     *
     * @return string
     */
    private function option_page_tabs(): string {
        $panels = $this->get_panels();
        if ( count( $panels ) < 1 ) {
            return '';
        }

        $current_tab = $_GET['tab'] ? wp_unslash( $_GET['tab'] ) : $panels[0]['id'];  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $page        = $this->menu_fields['menu_slug'];

        $html = '<h2 class="nav-tab-wrapper wp-clearfix">';
        foreach ( $panels as $tab ) {
            $class    = ( $tab['id'] === $current_tab ) ? ' nav-tab-active' : '';
            $page_url = esc_url(
                    add_query_arg(
                            array(
                                    'page' => $page,
                                    'tab'  => $tab['id'],
                            ),
                            admin_url( $this->menu_fields['parent_slug'] )
                    )
            );
            $html     .= '<a class="nav-tab' . $class . '" href="' . $page_url . '">' . $tab['title'] . '</a>';
        }
        $html .= '</h2>';

        return $html;
    }

    /**
     * Filter settings fields by page tab
     *
     * @param  string|null  $current_tab  The current tab slug.
     *
     * @return array
     */
    public function filter_fields_by_tab( string $current_tab = '' ): array {
        if ( ! $this->has_panels() ) {
            return $this->get_fields();
        }

        if ( empty( $current_tab ) ) {
            $panels      = $this->get_panels();
            $current_tab = $_GET['tab'] ? wp_unslash( $_GET['tab'] ) : $panels[0]['id']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        }

        return $this->get_fields_by_panel( $current_tab );
    }

    /**
     * Add a new field
     *
     * @param  array  $field  The field settings.
     */
    public function add_field( array $field ) {
        $this->set_field( $field );
    }

    /**
     * Check if it has panels
     *
     * @return bool
     */
    public function has_panels(): bool {
        return count( $this->panels ) > 0;
    }

    /**
     * Check if it has sections
     *
     * @return bool
     */
    public function has_sections(): bool {
        return count( $this->sections ) > 0;
    }

    /**
     * Get sections for current panel
     *
     * @param  string  $panel  The panel slug.
     *
     * @return array
     */
    public function get_sections_by_panel( string $panel = '' ): array {
        if ( empty( $panel ) || ! $this->has_panels() ) {
            return $this->get_sections();
        }

        $panels = array();
        foreach ( $this->get_sections() as $section ) {
            if ( $section['panel'] === $panel ) {
                $panels[] = $section;
            }
        }

        return $panels;
    }

    /**
     * Get a field for the current section
     *
     * @param  string|null  $section  The section slug.
     * @param  string|null  $panel  The panel slug.
     *
     * @return array
     */
    public function get_fields_by( $section = '', $panel = '' ): array {
        if ( ( empty( $section ) || ! $this->has_sections() ) && empty( $panel ) ) {
            return $this->get_fields();
        }

        $fields = array();
        foreach ( $this->get_fields() as $field ) {
            if (
                    ( isset( $field['section'] ) && $field['section'] === $section ) ||
                    ( ! empty( $panel ) && isset( $field['panel'] ) && $panel === $field['panel'] )
            ) {
                $fields[ $field['id'] ] = $field;
            }
        }

        return $fields;
    }

    /**
     * Filter settings fields by page tab
     *
     * @param  string|null  $panel  The panel slug.
     *
     * @return array
     */
    public function get_fields_by_panel( string $panel = '' ): array {
        $sections = $this->get_sections_by_panel( $panel );

        if ( count( $sections ) < 1 ) {
            return $this->get_fields_by( null, $panel );
        }

        $fields = array();
        foreach ( $sections as $section ) {
            $_section = $this->get_fields_by( $section['id'], $panel );
            $fields   = array_merge( $fields, $_section );
        }

        return $fields;
    }

    /**
     * Get for builder class
     *
     * @return FormBuilderInterface
     */
    public function get_form_builder(): FormBuilderInterface {
        if ( ! $this->form_builder instanceof FormBuilderInterface ) {
            $this->set_form_builder( new FormBuilder() );
        }

        return $this->form_builder;
    }

    /**
     * Set form builder class
     *
     * @param  FormBuilderInterface  $form_builder  The form builder class.
     */
    public function set_form_builder( FormBuilderInterface $form_builder ) {
        $this->form_builder = $form_builder;
    }
}
includes/Supports/SettingApi/SettingApi.php000064400000020776151727276500015070 0ustar00<?php

namespace CarouselSlider\Supports\SettingApi;

use CarouselSlider\Supports\Sanitize;
use WP_Error;

defined( 'ABSPATH' ) || exit;

/**
 * Very simple WordPress Settings API wrapper class
 *
 * WordPress Option Page Wrapper class that implements WordPress Settings API and
 *  gives you an easy way to create a multi tabs admin menu and
 * add setting fields with build in validation.
 *
 * @author  Sayful Islam <sayful.islam001@gmail.com>
 * @link    https://sayfulislam.com
 */
class SettingApi {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	private static $instance = null;

	/**
	 * Settings options array
	 *
	 * @var array
	 */
	protected $options = array();

	/**
	 * Settings menu fields array
	 *
	 * @var array
	 */
	protected $menu_fields = array();

	/**
	 * Settings fields array
	 *
	 * @var array
	 */
	protected $fields = array();

	/**
	 * Settings tabs array
	 *
	 * @var array
	 */
	protected $panels = array();

	/**
	 * The setting sections
	 *
	 * @var array
	 */
	protected $sections = array();

	/**
	 * Option name
	 *
	 * @var string
	 */
	protected $option_name = '';

	/**
	 * The only one instance of the class can be loaded
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Add a new admin menu
	 *
	 * This method is accessible outside the class for creating a menu
	 *
	 * @param  array $menu_fields  The setting arguments.
	 *
	 * @return WP_Error|SettingApi
	 */
	public function add_menu( array $menu_fields ) {
		if ( ! isset( $menu_fields['page_title'], $menu_fields['menu_title'], $menu_fields['menu_slug'] ) ) {
			return new WP_Error( 'field_not_set', 'Required key is not set properly for creating menu.' );
		}

		$this->menu_fields = $menu_fields;

		if ( ! empty( $menu_fields['option_name'] ) ) {
			$this->set_option_name( $menu_fields['option_name'] );
		}

		return $this;
	}

	/**
	 * Sanitize options values
	 *
	 * @param  array $input  The setting arguments.
	 *
	 * @return array
	 */
	public function sanitize_options( array $input ): array {
		$output_array = array();
		$fields       = $this->get_fields();
		$options      = $this->get_options();
		foreach ( $fields as $field ) {
			$key     = $field['id'] ?? null;
			$default = $field['default'] ?? null;
			$type    = $field['type'] ?? 'text';
			$value   = $input[ $field['id'] ] ?? $options[ $field['id'] ];

			if ( isset( $field['options'] ) && is_array( $field['options'] ) ) {
				$output_array[ $key ] = in_array( $value, array_keys( $field['options'] ), true ) ? $value : $default;
				continue;
			}

			if ( isset( $field['sanitize_callback'] ) && is_callable( $field['sanitize_callback'] ) ) {
				$output_array[ $key ] = call_user_func( $field['sanitize_callback'], $value );
				continue;
			}

			$output_array[ $key ] = $this->sanitize_by_input_type( $value, $field['type'] );
		}

		return $output_array;
	}

	/**
	 * Validate the option's value
	 *
	 * @param  mixed  $value  The value.
	 * @param  string $type  The input field type.
	 *
	 * @return string|numeric
	 */
	private function sanitize_by_input_type( $value, string $type = 'text' ) {
		switch ( $type ) {
			case 'number':
				return Sanitize::number( $value );

			case 'url':
				return Sanitize::url( $value );

			case 'email':
				return Sanitize::email( $value );

			case 'date':
				return Sanitize::date( $value );

			case 'textarea':
				return Sanitize::textarea( $value );

			case 'text':
				return Sanitize::text( $value );

			default:
				return Sanitize::deep( $value );
		}
	}

	/**
	 * Get fields default values
	 *
	 * @return array
	 */
	public function get_default_options(): array {
		$defaults = array();

		foreach ( $this->get_fields() as $field ) {
			$defaults[ $field['id'] ] = $field['default'] ?? '';
		}

		return $defaults;
	}

	/**
	 * Get options parsed with the default value
	 *
	 * @return array
	 */
	public function get_options(): array {
		if ( empty( $this->options ) ) {
			$defaults      = $this->get_default_options();
			$options       = get_option( $this->get_option_name() );
			$this->options = wp_parse_args( $options, $defaults );
		}

		return $this->options;
	}

	/**
	 * Update options
	 *
	 * @param  array $options  The options.
	 * @param  bool  $sanitize  If it should sanitize options.
	 */
	public function update_options( array $options, bool $sanitize = true ) {
		if ( $sanitize ) {
			$options = $this->sanitize_options( $options );
		}
		update_option( $this->get_option_name(), $options );
	}

	/**
	 * Get settings panels
	 *
	 * @return array
	 */
	public function get_panels(): array {
		$panels = apply_filters( 'carousel_slider/settings/panels', $this->panels );

		// Sort by priority.
		usort( $panels, array( $this, 'sort_by_priority' ) );

		return $panels;
	}

	/**
	 * Set panels
	 *
	 * @param  array $panels  The setting arguments.
	 *
	 * @return self
	 */
	public function set_panels( array $panels ): SettingApi {
		foreach ( $panels as $panel ) {
			$this->set_panel( $panel );
		}

		return $this;
	}

	/**
	 * Get settings sections
	 *
	 * @return array
	 */
	public function get_sections(): array {
		$sections = apply_filters( 'carousel_slider/settings/sections', $this->sections );

		// Sort by priority.
		usort( $sections, array( $this, 'sort_by_priority' ) );

		return $sections;
	}

	/**
	 * Set sections
	 *
	 * @param  array $sections  The setting arguments.
	 *
	 * @return self
	 */
	public function set_sections( array $sections ): SettingApi {
		foreach ( $sections as $section ) {
			$this->set_section( $section );
		}

		return $this;
	}

	/**
	 * Get settings fields
	 *
	 * @return array
	 */
	public function get_fields(): array {
		$fields = apply_filters( 'carousel_slider/settings/fields', $this->fields );

		// Sort by priority.
		usort( $fields, array( $this, 'sort_by_priority' ) );

		return $fields;
	}

	/**
	 * Set fields
	 *
	 * @param  array $fields  The setting arguments.
	 *
	 * @return self
	 */
	public function set_fields( array $fields ): SettingApi {
		foreach ( $fields as $field ) {
			$this->set_field( $field );
		}

		return $this;
	}

	/**
	 * Get panel by panel id
	 *
	 * @param  string $panel_id  The panel id.
	 *
	 * @return false|array
	 */
	public function get_panel( string $panel_id ) {
		$current_panel = false;
		foreach ( $this->panels as $panel ) {
			if ( $panel_id === $panel['id'] ) {
				$current_panel = $panel;
			}
		}

		return $current_panel;
	}

	/**
	 * Add setting page tab
	 *
	 * This method is accessible outside the class for creating a page tab
	 *
	 * @param  array $panel  The setting arguments.
	 *
	 * @return self
	 */
	public function set_panel( array $panel ): SettingApi {
		$panel = wp_parse_args(
			$panel,
			array(
				'id'          => '',
				'title'       => '',
				'description' => '',
				'priority'    => 200,
			)
		);

		$this->panels[] = $panel;

		return $this;
	}

	/**
	 * Add a Setting page section
	 *
	 * @param  array $section  The setting arguments.
	 *
	 * @return self
	 */
	public function set_section( array $section ): SettingApi {
		$section = wp_parse_args(
			$section,
			array(
				'id'          => 'general',
				'panel'       => '',
				'title'       => '',
				'description' => '',
				'priority'    => 200,
			)
		);

		$this->sections[] = $section;

		return $this;
	}

	/**
	 * Add a new settings field
	 * This method is accessible outside the class for creating settings field
	 *
	 * @param  array $field  The setting arguments.
	 *
	 * @return self
	 */
	public function set_field( array $field ): SettingApi {
		$field = wp_parse_args(
			$field,
			array(
				'type'        => 'text',
				'section'     => 'general',
				'id'          => '',
				'title'       => '',
				'description' => '',
				'priority'    => 200,
			)
		);

		$this->fields[ $field['id'] ] = $field;

		return $this;
	}

	/**
	 * Sort array by its priority field
	 *
	 * @param  array $array1  First array.
	 * @param  array $array2  Second array.
	 *
	 * @return mixed
	 */
	public function sort_by_priority( array $array1, array $array2 ) {
		return $array1['priority'] - $array2['priority'];
	}

	/**
	 * Get option name
	 *
	 * @return string
	 */
	public function get_option_name(): string {
		if ( ! empty( $this->menu_fields['option_name'] ) ) {
			return $this->menu_fields['option_name'];
		}

		return $this->option_name;
	}

	/**
	 * Set an option name
	 *
	 * @param  string $option_name  The option name.
	 *
	 * @return SettingApi
	 */
	public function set_option_name( string $option_name ): SettingApi {
		$this->option_name = $option_name;

		return $this;
	}
}
includes/Supports/SettingApi/FormBuilder.php000064400000011276151727276500015226 0ustar00<?php

namespace CarouselSlider\Supports\SettingApi;

use CarouselSlider\Interfaces\FieldInterface;
use CarouselSlider\Interfaces\FormBuilderInterface;
use CarouselSlider\Supports\FormFields\BaseField;
use CarouselSlider\Supports\FormFields\Breakpoint;
use CarouselSlider\Supports\FormFields\ButtonGroup;
use CarouselSlider\Supports\FormFields\Checkbox;
use CarouselSlider\Supports\FormFields\CheckboxSwitch;
use CarouselSlider\Supports\FormFields\Color;
use CarouselSlider\Supports\FormFields\ImagesGallery;
use CarouselSlider\Supports\FormFields\ImageUploader;
use CarouselSlider\Supports\FormFields\ImageUrl;
use CarouselSlider\Supports\FormFields\MultiCheckbox;
use CarouselSlider\Supports\FormFields\Radio;
use CarouselSlider\Supports\FormFields\Select;
use CarouselSlider\Supports\FormFields\SelectImageSize;
use CarouselSlider\Supports\FormFields\SelectPosts;
use CarouselSlider\Supports\FormFields\SelectTerms;
use CarouselSlider\Supports\FormFields\Spacing;
use CarouselSlider\Supports\FormFields\Text;
use CarouselSlider\Supports\FormFields\Textarea;

// If this file is called directly, abort.
defined( 'ABSPATH' ) || die;

/**
 * FormBuilder class
 */
class FormBuilder implements FormBuilderInterface {

	/**
	 * The option name
	 *
	 * @var string|null
	 */
	protected $option_name = null;

	/**
	 * The field settings
	 *
	 * @var array
	 */
	protected $fields_settings = [];

	/**
	 * The values of the fields
	 *
	 * @var array
	 */
	protected $values = [];

	/**
	 * Set field settings
	 *
	 * @param  array $settings  The settings arguments.
	 *
	 * @return void
	 */
	public function set_fields_settings( array $settings ) {
		$this->fields_settings = $settings;
	}

	/**
	 * Set an option name
	 *
	 * @param  string $option_name  The option name.
	 *
	 * @return void
	 */
	public function set_option_name( string $option_name ) {
		$this->option_name = $option_name;
	}

	/**
	 * Set fields values
	 *
	 * @param  array $values  The values.
	 *
	 * @return void
	 */
	public function set_values( array $values ) {
		$this->values = $values;
	}

	/**
	 * Render settings html
	 *
	 * @return string
	 */
	public function render(): string {
		$table = "<table class='form-table'>";

		foreach ( $this->fields_settings as $field ) {
			$type        = $field['type'] ?? 'text';
			$field_class = self::get_field_class( $type );
			if ( ! $field_class instanceof FieldInterface ) {
				continue;
			}
			$name  = sprintf( '%s[%s]', $this->option_name, $field['id'] );
			$value = $this->values[ $field['id'] ] ?? '';

			$table .= '<tr>';
			if ( ! empty( $field['title'] ) ) {
				$table .= sprintf(
					'<th scope="row"><label for="%1$s">%2$s</label></th>',
					$field['id'],
					$field['title']
				);
			}
			$table .= '<td>';

			$field_class->set_settings( $field );
			$field_class->set_name( $name );
			$field_class->set_value( $value );
			$table .= $field_class->render();

			if ( ! empty( $field['description'] ) ) {
				$desc   = is_array( $field['description'] ) ?
					implode( '<br>', $field['description'] ) :
					$field['description'];
				$table .= sprintf( '<p class="description">%s</p>', $desc );
			}
			$table .= '</td>';
			$table .= '</tr>';
		}

		$table .= '</table>';

		return $table;
	}

	/**
	 * Settings fields
	 *
	 * @param  array  $fields  The field settings.
	 * @param  string $option_name  The option name.
	 * @param  array  $values  The values.
	 *
	 * @return string
	 */
	public function get_fields_html( array $fields, string $option_name, array $values = [] ): string {
		$this->set_fields_settings( $fields );
		$this->set_option_name( $option_name );
		$this->set_values( $values );

		return $this->render();
	}

	/**
	 * Get field class
	 *
	 * @param  string $type  The field type.
	 *
	 * @return BaseField|FieldInterface|null
	 */
	public function get_field_class( string $type = 'text' ) {
		$types = apply_filters(
			'carousel_slider/settings/available_fields',
			[
				'text'           => Text::class,
				'textarea'       => Textarea::class,
				'spacing'        => Spacing::class,
				'checkbox'       => Checkbox::class,
				'multi_checkbox' => MultiCheckbox::class,
				'button_group'   => ButtonGroup::class,
				'color'          => Color::class,
				'images_gallery' => ImagesGallery::class,
				'upload_iframe'  => ImageUploader::class,
				'images_url'     => ImageUrl::class,
				'select'         => Select::class,
				'posts_list'     => SelectPosts::class,
				'post_terms'     => SelectTerms::class,
				'image_sizes'    => SelectImageSize::class,
				'radio'          => Radio::class,
				'switch'         => CheckboxSwitch::class,
				'breakpoint'     => Breakpoint::class,
			]
		);

		if ( array_key_exists( $type, $types ) ) {
			return new $types[ $type ]();
		}

		return new $types['text']();
	}
}
includes/Supports/Sanitize.php000064400000014715151727276510012535 0ustar00<?php

namespace CarouselSlider\Supports;

defined( 'ABSPATH' ) || exit;

/**
 * Sanitize class
 */
class Sanitize {

	/**
	 * Sanitize number options.
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return int|float
	 */
	public static function number( $value ) {
		if ( ! is_numeric( $value ) ) {
			return 0;
		}

		if ( preg_match( '/^\\d+\\.\\d+$/', $value ) === 1 ) {
			return floatval( $value );
		}

		return intval( $value );
	}

	/**
	 * Sanitize float number
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return float
	 */
	public static function float( $value ): float {
		if ( ! is_numeric( $value ) ) {
			return 0;
		}

		return floatval( $value );
	}

	/**
	 * Sanitize integer number
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return int
	 */
	public static function int( $value ): int {
		if ( ! is_numeric( $value ) ) {
			return 0;
		}

		return intval( $value );
	}

	/**
	 * Sanitize email
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return string
	 */
	public static function email( $value ): string {
		return sanitize_email( $value );
	}

	/**
	 * Sanitize url
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return string
	 */
	public static function url( $value ): string {
		return esc_url_raw( trim( $value ) );
	}

	/**
	 * Sanitizes a string
	 *
	 * - Checks for invalid UTF-8,
	 * - Converts single `<` characters to entities
	 * - Strips all tags
	 * - Removes line breaks, tabs, and extra whitespace
	 * - Strips octets
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return string
	 */
	public static function text( $value ): string {
		return sanitize_text_field( $value );
	}

	/**
	 * Sanitizes a multiline string
	 *
	 * The function is like sanitize_text_field(), but preserves
	 * new lines (\n) and other whitespace, which are legitimate
	 * input in textarea elements.
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return string
	 */
	public static function textarea( $value ): string {
		return sanitize_textarea_field( $value );
	}

	/**
	 * If a field has been 'checked' or not, meaning it contains
	 * one of the following values: 'yes', 'on', '1', 1, true, or 'true'.
	 * This can be used for determining if an HTML checkbox has been checked.
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return mixed|boolean|string
	 */
	public static function checked( $value ) {
		$true_values  = [ 'yes', 'on', '1', 1, true, 'true' ];
		$false_values = [ 'no', 'off', '0', 0, false, 'false' ];

		return in_array( $value, array_merge( $true_values, $false_values ), true ) ? $value : '';
	}

	/**
	 * Check if the given input is a valid date.
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return boolean
	 */
	public static function date( $value ) {
		$time = strtotime( $value );

		if ( $time ) {
			return gmdate( 'Y-m-d', $time );
		}

		return '';
	}

	/**
	 * Sanitize short block HTML input
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return string
	 */
	public static function html( $value ): string {
		return wp_kses_post( $value );
	}

	/**
	 * Sanitize colors.
	 *
	 * @param  mixed $value  The color.
	 *
	 * @return string
	 */
	public static function color( $value ): string {
		// If the value is empty, then return empty.
		if ( '' === $value || ! is_string( $value ) ) {
			return '';
		}

		// Trim unneeded whitespace.
		$value = str_replace( ' ', '', $value );

		// This pattern will check and match 3/6/8-character hex, rgb, rgba, hsl, & hsla colors.
		$pattern  = '/^(\#[\da-f]{3}|\#[\da-f]{6}|\#[\da-f]{8}|';
		$pattern .= 'rgba\(((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*){2}((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*)(,\s*(0\.\d+|1))\)|';
		$pattern .= 'hsla\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)(,\s*(0\.\d+|1))\)|';
		$pattern .= 'rgb\(((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*){2}((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*)\)|';
		$pattern .= 'hsl\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)\))$/';

		// Return the 1st match found.
		if ( 1 === preg_match( $pattern, $value ) ) {
			return $value;
		}

		// If no match was found, return an empty string.
		return '';
	}


	/**
	 * Sanitize meta value
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return mixed
	 */
	public static function deep( $value ) {
		if ( empty( $value ) ) {
			return $value;
		}
		if ( is_scalar( $value ) ) {
			if ( is_numeric( $value ) ) {
				return self::number( $value );
			}

			return sanitize_text_field( $value );
		}

		$sanitized_value = [];
		if ( is_array( $value ) ) {
			foreach ( $value as $index => $item ) {
				$sanitized_value[ $index ] = self::deep( $item );
			}
		}

		return $sanitized_value;
	}

	/**
	 * Sanitize an array of integer
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return array
	 */
	public static function deep_int( $value ): array {
		if ( ! is_array( $value ) ) {
			return [];
		}

		return map_deep( $value, 'intval' );
	}

	/**
	 * Sanitizes css dimensions.
	 *
	 * @param  mixed $value  The value to be sanitized.
	 *
	 * @return string
	 */
	public static function css_dimension( $value ): string {
		if ( ! ( is_string( $value ) || is_numeric( $value ) ) ) {
			return '';
		}
		// Trim it.
		$value = trim( $value );

		// If the value is round, then return 50%.
		if ( 'round' === $value ) {
			$value = '50%';
		}

		// If the value is empty, return empty.
		if ( '' === $value ) {
			return '';
		}

		// If auto, inherit or initial, return the value.
		if ( 'auto' === $value || 'initial' === $value || 'inherit' === $value ) {
			return $value;
		}

		// Return empty if there are no numbers in the value.
		if ( ! preg_match( '#[0-9]#', $value ) ) {
			return '';
		}

		// The raw value without the units.
		$raw_value = filter_var( $value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION );
		$unit_used = '';

		// An array of all valid CSS units. Their order was carefully chosen for this evaluation, don't mix it up!!!
		$units = array(
			'rem',
			'em',
			'ex',
			'%',
			'px',
			'cm',
			'mm',
			'in',
			'pt',
			'pc',
			'ch',
			'vh',
			'vw',
			'vmin',
			'vmax',
		);
		foreach ( $units as $unit ) {
			if ( false !== strpos( $value, $unit ) ) {
				$unit_used = $unit;
			}
		}

		// Hack for rem values.
		if ( 'em' === $unit_used && false !== strpos( $value, 'rem' ) ) {
			$unit_used = 'rem';
		}

		return $raw_value . $unit_used;
	}
}
includes/Interfaces/FormBuilderInterface.php000064400000001121151727276510015211 0ustar00<?php

namespace CarouselSlider\Interfaces;

defined( 'ABSPATH' ) || exit;

interface FormBuilderInterface {
	/**
	 * Set fields settings
	 *
	 * @param array $settings The setting array.
	 */
	public function set_fields_settings( array $settings );

	/**
	 * Set an option name
	 *
	 * @param string $option_name The option name.
	 */
	public function set_option_name( string $option_name );

	/**
	 * Set values
	 *
	 * @param array $values The values.
	 */
	public function set_values( array $values );

	/**
	 * Render form
	 *
	 * @return string
	 */
	public function render(): string;
}
includes/Interfaces/FieldInterface.php000064400000001155151727276510014031 0ustar00<?php

namespace CarouselSlider\Interfaces;

defined( 'ABSPATH' ) || exit;

interface FieldInterface {
	/**
	 * Set settings
	 *
	 * @param array $settings The settings array.
	 *
	 * @return mixed
	 */
	public function set_settings( array $settings );

	/**
	 * Set field name
	 *
	 * @param string $name the field name.
	 *
	 * @return mixed
	 */
	public function set_name( string $name );

	/**
	 * Set field value
	 *
	 * @param mixed $value The field value.
	 *
	 * @return mixed
	 */
	public function set_value( $value );

	/**
	 * Render field html
	 *
	 * @return string
	 */
	public function render(): string;
}
includes/Interfaces/SliderViewInterface.php000064400000001563151727276510015066 0ustar00<?php

namespace CarouselSlider\Interfaces;

use CarouselSlider\Abstracts\SliderSetting;

defined( 'ABSPATH' ) || exit;

interface SliderViewInterface {
	/**
	 * Set slider id
	 *
	 * @param  int $slider_id  The slider id.
	 */
	public function set_slider_id( int $slider_id );

	/**
	 * Set slider type
	 *
	 * @param  string $slider_type  The slider type.
	 */
	public function set_slider_type( string $slider_type );

	/**
	 * Get slider setting
	 *
	 * @return SliderSettingInterface|SliderSetting
	 */
	public function get_slider_setting();

	/**
	 * Set slider setting class
	 *
	 * @param  SliderSettingInterface $slider_setting  The SliderSetting class.
	 */
	public function set_slider_setting( SliderSettingInterface $slider_setting );

	/**
	 * Render element.
	 * Generates the final HTML on the frontend.
	 *
	 * @return string
	 */
	public function render(): string;
}
includes/Interfaces/TemplateParserInterface.php000064400000000413151727276510015732 0ustar00<?php

namespace CarouselSlider\Interfaces;

/**
 * TemplateParserInterface class
 */
interface TemplateParserInterface {
	/**
	 * Render template to HTML.
	 * Generates the final HTML on the frontend.
	 *
	 * @return string
	 */
	public function render(): string;
}
includes/Interfaces/SliderSettingInterface.php000064400000002742151727276510015571 0ustar00<?php

namespace CarouselSlider\Interfaces;

use ArrayAccess;
use JsonSerializable;

defined( 'ABSPATH' ) || exit;

/**
 * SliderSettingInterface class
 */
interface SliderSettingInterface extends ArrayAccess, JsonSerializable {
	/**
	 * Get slider Id
	 *
	 * @return int
	 */
	public function get_slider_id(): int;

	/**
	 * Get slider type
	 *
	 * @return string
	 */
	public function get_slider_type(): string;

	/**
	 * Get the global option for a key
	 *
	 * @param  string $key  option key.
	 * @param  mixed  $default_value  default value to return if a data key does not exist.
	 *
	 * @return mixed The key's value, or the default value
	 */
	public function get_global_option( string $key, $default_value = '' );

	/**
	 * Get option for key
	 * If there is no option for a key, return from the global option.
	 *
	 * @param  string $key  option key.
	 * @param  mixed  $default_value  default value to return if the data key does not exist.
	 *
	 * @return mixed The key's value, or the default value
	 */
	public function get_option( string $key, $default_value = '' );

	/**
	 * Read data from HTTP POST variable
	 *
	 * @param  array $values  The values from HTTP POST variables.
	 *
	 * @return void
	 */
	public function read_http_post_variables( array $values = array() );

	/**
	 * Read data from HTTP POST variable
	 *
	 * @param  array $values  The values from HTTP POST variables.
	 *
	 * @return void
	 */
	public function read_extra_http_post_variables( array $values = array() );
}
includes/TemplateParserBase.php000064400000011554151727276520012632 0ustar00<?php

namespace CarouselSlider;

use CarouselSlider\Abstracts\SliderSetting;
use CarouselSlider\Interfaces\SliderSettingInterface;
use CarouselSlider\Interfaces\TemplateParserInterface;

/**
 * TemplateParserBase class
 */
class TemplateParserBase implements TemplateParserInterface {
	/**
	 * The template string
	 *
	 * @var string
	 */
	protected $template = '';

	/**
	 * The object that will be used to replace the placeholder
	 *
	 * @var mixed
	 */
	protected $object;

	/**
	 * Placeholders
	 *
	 * @var array
	 */
	protected $placeholders = [];

	/**
	 * Slider settings object
	 *
	 * @var SliderSetting
	 */
	protected $slider_setting;

	/**
	 * Should use conditional checking
	 *
	 * @var bool
	 */
	protected $use_condition = false;

	/**
	 * Extra data to pass to the template
	 *
	 * @var array
	 */
	protected $extra_vars = [];

	/**
	 * The class constructor
	 *
	 * @param SliderSetting|null $setting The setting object.
	 */
	public function __construct( $setting = null ) {
		if ( $setting instanceof SliderSettingInterface ) {
			$this->set_slider_settings( $setting );
		}
	}

	/**
	 * Set the template file name
	 *
	 * @param string $template The template file name.
	 */
	public function set_template( string $template ) {
		$this->template = $template;
	}

	/**
	 * Set object
	 *
	 * @param mixed $data_object The object to replace placeholder.
	 */
	public function set_object( $data_object ) {
		$this->object = $data_object;
	}

	/**
	 * Get slider setting
	 *
	 * @return SliderSetting
	 */
	public function get_slider_setting(): SliderSetting {
		return $this->slider_setting;
	}

	/**
	 * Set slider settings.
	 *
	 * @param SliderSetting $setting The setting class.
	 *
	 * @return void
	 */
	public function set_slider_settings( SliderSetting $setting ) {
		$this->slider_setting = $setting;
	}

	/**
	 * Get object
	 *
	 * @return mixed
	 */
	public function get_object() {
		return $this->object;
	}

	/**
	 * Global placeholder
	 *
	 * @return array
	 */
	public function global_placeholders(): array {
		return [
			'{site_title}' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ),
			'{site_url}'   => wp_parse_url( home_url(), PHP_URL_HOST ),
			'{slider_id}'  => $this->get_slider_setting()->get_slider_id(),
		];
	}

	/**
	 * Get template base directory
	 *
	 * @return string
	 */
	public function get_template_base_directory(): string {
		$dir = apply_filters( 'carousel_slider/template_directory', CAROUSEL_SLIDER_PATH . '/templates' );

		return rtrim( $dir, '/' );
	}

	/**
	 * Get template file path
	 *
	 * @return string
	 */
	public function get_template_file(): string {
		$theme_dir     = apply_filters( 'carousel_slider/theme_template_directory', 'carousel-slider' );
		$template_file = $theme_dir . DIRECTORY_SEPARATOR . $this->template;
		$template      = locate_template( $template_file );
		if ( '' !== $template ) {
			return $template;
		}

		return $this->get_template_base_directory() . DIRECTORY_SEPARATOR . $this->template;
	}

	/**
	 * Get template content
	 *
	 * @return string
	 */
	public function get_template_content(): string {
		$setting = $this->get_slider_setting();
		$object  = $this->get_object();
		if ( count( $this->extra_vars ) ) {
			extract( $this->extra_vars, EXTR_OVERWRITE ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
		}
		ob_start();
		include $this->get_template_file();

		return ob_get_clean();
	}

	/**
	 * Render final html string
	 *
	 * @return string
	 */
	public function render(): string {
		$subject = str_replace(
			array_keys( $this->placeholders ),
			array_values( $this->placeholders ),
			$this->get_template_content()
		);

		if ( $this->use_condition ) {
			return $this->handle_conditional_tags( $subject );
		}

		return $subject;
	}

	/**
	 * Handle conditional tags
	 *
	 * @param string $subject The HTML content to check.
	 *
	 * @return string|null
	 */
	public function handle_conditional_tags( string $subject ) {
		$regex  = '/'; // Start of Regex.
		$regex .= '<!--\s*{if\s*\((?P<condition>\s*.*)\)}\s*-->\s*'; // Start of condition.
		$regex .= '(?P<html>\s*.*)'; // Grab the HTML.
		$regex .= '\s*<!--\s{endif}\s-->'; // End of condition.
		$regex .= '/i'; // Regex options.

		return preg_replace_callback(
			$regex,
			function ( $matches ) {
				$html = $matches['html'];

				list( $value1, $operator, $value2 ) = explode( ' ', trim( $matches['condition'] ) );

				$value1 = str_replace( [ '"', "'" ], '', $value1 );
				$value2 = str_replace( [ '"', "'" ], '', $value2 );

				// phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
				if ( '==' === $operator && $value1 == $value2 ) {
					return $html;
				}

				return '';
			},
			$subject
		);
	}

	/**
	 * Set extra variables
	 *
	 * @param string $key The extra variable key.
	 * @param mixed  $value The value to replace placeholder.
	 */
	public function set_extra_vars( string $key, $value ) {
		$this->extra_vars[ $key ] = $value;
	}
}
includes/Autoloader.php000064400000007777151727276520011222 0ustar00<?php

namespace CarouselSlider;

defined( 'ABSPATH' ) || exit;

/**
 * Autoloader class
 */
class Autoloader {
	/**
	 * An associative array where the key is a namespace prefix and the value
	 * is an array of base directories for classes in that namespace.
	 *
	 * @var array
	 */
	protected $prefixes = [];

	/**
	 * Register loader with SPL autoloader stack.
	 *
	 * @return void
	 */
	public function register() {
		spl_autoload_register( [ $this, 'load_class' ] );
	}

	/**
	 * Adds a base directory for a namespace prefix.
	 *
	 * @param  string  $prefix  The namespace prefix.
	 * @param  string  $base_dir  A base directory for class files in the namespace.
	 * @param  bool  $prepend  If true, prepend the base directory to the stack instead of appending it;
	 *                         this causes it to be searched first rather than last.
	 *
	 * @return void
	 */
	public function add_namespace( $prefix, $base_dir, $prepend = false ) {
		// normalize namespace prefix.
		$prefix = trim( $prefix, '\\' ) . '\\';

		// normalize the base directory with a trailing separator.
		$base_dir = rtrim( $base_dir, DIRECTORY_SEPARATOR ) . '/';

		// initialize the namespace prefix array.
		if ( isset( $this->prefixes[ $prefix ] ) === false ) {
			$this->prefixes[ $prefix ] = array();
		}

		// retain the base directory for the namespace prefix.
		if ( $prepend ) {
			array_unshift( $this->prefixes[ $prefix ], $base_dir );
		} else {
			array_push( $this->prefixes[ $prefix ], $base_dir );
		}
	}

	/**
	 * Loads the class file for a given class name.
	 *
	 * @param  string  $class_name  The fully qualified class name.
	 *
	 * @return mixed The mapped file name on success, or boolean false on
	 * failure.
	 */
	public function load_class( $class_name ) {
		// the current namespace prefix.
		$prefix = $class_name;

		// work backwards through the namespace names of the fully qualified
		// class name to find a mapped file name.
		// phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
		while ( false !== $pos = strrpos( $prefix, '\\' ) ) {

			// retain the trailing namespace separator in the prefix.
			$prefix = substr( $class_name, 0, $pos + 1 );

			// the rest is the relative class name.
			$relative_class = substr( $class_name, $pos + 1 );

			// try to load a mapped file for the prefix and relative class.
			$mapped_file = $this->load_mapped_file( $prefix, $relative_class );
			if ( $mapped_file ) {
				return $mapped_file;
			}

			// remove the trailing namespace separator for the next iteration
			// of strrpos().
			$prefix = rtrim( $prefix, '\\' );
		}

		// never found a mapped file.
		return false;
	}

	/**
	 * Load the mapped file for a namespace prefix and relative class.
	 *
	 * @param  string  $prefix  The namespace prefix.
	 * @param  string  $relative_class  The relative class name.
	 *
	 * @return false|string Boolean false if no mapped file can be loaded, or the
	 * name of the mapped file that was loaded.
	 */
	protected function load_mapped_file( $prefix, $relative_class ) {
		// are there any base directories for this namespace prefix?
		if ( isset( $this->prefixes[ $prefix ] ) === false ) {
			return false;
		}

		// look through base directories for this namespace prefix.
		foreach ( $this->prefixes[ $prefix ] as $base_dir ) {

			// replace the namespace prefix with the base directory,
			// replace namespace separators with directory separators
			// in the relative class name, append with .php extension.
			$file = $base_dir
			        . str_replace( '\\', '/', $relative_class )
			        . '.php';

			// if the mapped file exists, require it.
			if ( $this->require_file( $file ) ) {
				// yes, we're done.
				return $file;
			}
		}

		// never found it.
		return false;
	}

	/**
	 * If a file exists, require it from the file system.
	 *
	 * @param  string  $file  The file to require.
	 *
	 * @return bool True if the file exists, false if not.
	 */
	protected function require_file( $file ) {
		if ( file_exists( $file ) ) {
			require $file;

			return true;
		}

		return false;
	}
}
includes/ViewHelper.php000064400000002500151727276520011150 0ustar00<?php

namespace CarouselSlider;

use CarouselSlider\Supports\Validate;

defined( 'ABSPATH' ) || exit;

/**
 * ViewHelper class
 */
class ViewHelper {


	/**
	 * Array to style
	 *
	 * @param  array  $styles  The styles array.
	 *
	 * @return string
	 */
	public static function array_to_style( array $styles ): string {
		$_styles = [];
		foreach ( $styles as $key => $value ) {
			if ( ! is_string( $key ) || empty( $value ) ) {
				continue;
			}
			$_styles[] = sprintf( '%s:%s', $key, esc_attr( $value ) );
		}

		return implode( ';', $_styles );
	}

	/**
	 * Convert array to html data attribute
	 *
	 * @param  array  $attributes  The attribute list.
	 *
	 * @return array
	 */
	public static function array_to_attribute( array $attributes ): array {
		return array_map(
			function ( $key, $value ) {
				// If boolean value.
				if ( is_bool( $value ) ) {
					return sprintf( '%s="%s"', $key, ( $value ? 'true' : 'false' ) );
				}
				// If array value.
				if ( is_array( $value ) ) {
					return sprintf( '%s="%s"', $key, implode( ' ', $value ) );
				}

				if ( is_string( $value ) && Validate::json( $value ) ) {
					return sprintf( "%s='%s'", $key, $value );
				}

				// If string value.
				return sprintf( '%s="%s"', $key, esc_attr( $value ) );
			},
			array_keys( $attributes ),
			array_values( $attributes )
		);
	}
}
includes/Ajax.php000064400000001553151727276520007770 0ustar00<?php
/**
 * The ajax-specific functionality of the plugin.
 *
 * @package CarouselSlider
 */

namespace CarouselSlider;

defined( 'ABSPATH' ) || exit;

/**
 * Ajax class
 */
class Ajax {

	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'wp_ajax_carousel_slider_test', [ self::$instance, 'test' ] );
		}

		return self::$instance;
	}

	/**
	 * An AJAX method just to test some data
	 */
	public function test() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Sorry. This link only for developer to do some testing.' );
		}

		var_dump( 'Testing some data on AJAX' ); // phpcs:ignore
		die();
	}
}
includes/Frontend/Preview.php000064400000006552151727276530012312 0ustar00<?php

namespace CarouselSlider\Frontend;

use CarouselSlider\Helper;
use CarouselSlider\Interfaces\SliderViewInterface;

defined( 'ABSPATH' ) || exit;

/**
 * Preview class
 */
class Preview {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of this class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'template_redirect', [ self::$instance, 'show_preview' ] );
		}

		return self::$instance;
	}

	/**
	 * Include custom template
	 *
	 * @return void
	 */
	public function show_preview() {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( ! isset( $_GET['carousel_slider_preview'], $_GET['carousel_slider_iframe'], $_GET['slider_id'] ) ) {
			return;
		}
		if ( ! current_user_can( 'edit_pages' ) ) {
			return;
		}
		add_filter( 'carousel_slider_load_scripts', '__return_true' );
		echo $this->preview_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		exit();
	}

	/**
	 * Preview HTML
	 *
	 * @return string
	 */
	public function preview_html(): string {
		ob_start();
		wp_head();
		$wp_head = ob_get_clean();

		ob_start();
		wp_footer();
		$wp_footer = ob_get_clean();

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$slider_id = isset( $_GET['slider_id'] ) ? intval( $_GET['slider_id'] ) : 0;

		$slide_type = get_post_meta( $slider_id, '_slide_type', true );
		$slide_type = array_key_exists( $slide_type, Helper::get_slide_types() ) ? $slide_type : 'image-carousel';

		$view = Helper::get_slider_view( $slide_type );
		if ( $view instanceof SliderViewInterface ) {
			$view->set_slider_id( $slider_id );
			$view->set_slider_type( $slide_type );

			$slider_html = $view->render();
		} else {
			$slider_html = '';
		}

		$html = '<!DOCTYPE html>' . PHP_EOL;
		$html .= '<html ' . get_language_attributes() . '>' . PHP_EOL;
		$html .= '<head>' . PHP_EOL;
		$html .= '<meta charset="' . get_bloginfo( 'charset' ) . '">' . PHP_EOL;
		$html .= '<meta name="viewport" content="width=device-width, initial-scale=1">' . PHP_EOL;
		$html .= $wp_head . PHP_EOL;
		$html .= '<style type="text/css" media="screen">
				html {margin-top: 0 !important;}
				* html body {margin-top: 0 !important;}
				#wpadminbar {display: none !important;}
				.carousel-slider-preview-container {max-width: 1024px;margin-left: auto;margin-right: auto;}
				@media screen and ( max-width: 782px ) {
					html {margin-top: 0 !important;}
					* html body {margin-top: 0 !important;}
				}
			</style>' . PHP_EOL;
		$html .= '</head>' . PHP_EOL;
		$html .= '</body>' . PHP_EOL;
		$html .= '<div class="carousel-slider-preview-container">' . PHP_EOL;
		$html .= $slider_html . PHP_EOL;
		$html .= '</div>' . PHP_EOL;
		$html .= $wp_footer . PHP_EOL;
		$html .= '<script type="text/javascript">
			(function () {
				if (window.frameElement) {
					window.frameElement.height = document.querySelector(".carousel-slider-preview-container").offsetHeight;
				}
                window.addEventListener("load", () => {
					if (window.frameElement) {
						window.frameElement.height = document.querySelector(".carousel-slider-preview-container").offsetHeight;
					}
				});
			})();
		</script>' . PHP_EOL;
		$html .= '</body>' . PHP_EOL;
		$html .= '</html>';

		return $html;
	}
}
includes/Frontend/StructuredData.php000064400000017200151727276530013617 0ustar00<?php
/**
 * The structure-data specific file of the plugin
 *
 * @package CarouselSlider/Frontend
 */

namespace CarouselSlider\Frontend;

use CarouselSlider\Helper;
use CarouselSlider\Supports\Validate;
use WC_Product;
use WP_Post;

defined( 'ABSPATH' ) || exit;

/**
 * StructuredData class
 *
 * The structure-data-specific class of the plugin
 */
class StructuredData {
	/**
	 * The instance of the class
	 *
	 * @var null | self
	 */
	private static $instance = null;

	/**
	 * Product structured data
	 *
	 * @var array
	 */
	private $product_data = [];

	/**
	 * Image structured data
	 *
	 * @var array
	 */
	private $image_data = [];

	/**
	 * Post structured data
	 *
	 * @var array
	 */
	private $post_data = [];

	/**
	 * Ensures only one instance of this class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			$show = Validate::checked( Helper::get_setting( 'show_structured_data', '1' ) );

			if ( $show ) {
				add_action( 'carousel_slider_image_gallery_loop', [ self::$instance, 'generate_image_data' ] );
				add_action( 'carousel_slider_post_loop', [ self::$instance, 'generate_post_data' ] );
				add_action( 'carousel_slider_after_shop_loop_item', [ self::$instance, 'generate_product_data' ] );
				// Output structured data.
				add_action( 'wp_footer', [ self::$instance, 'output_structured_data' ], 90 );
			}
		}

		return self::$instance;
	}

	/**
	 * Outputs structured data.
	 *
	 * Hooked into `wp_footer` action hook.
	 */
	public function output_structured_data() {
		$data = $this->get_structured_product_data();
		if ( $data ) {
			echo '<script type="application/ld+json">' . wp_json_encode( $data ) . '</script>' . "\n";
		}
		$gallery_data = $this->get_structured_image_data();
		if ( $gallery_data ) {
			echo '<script type="application/ld+json">' . wp_json_encode( $gallery_data ) . '</script>' . "\n";
		}
		$post_data = $this->get_structured_post_data();
		if ( $post_data ) {
			echo '<script type="application/ld+json">' . wp_json_encode( $post_data ) . '</script>' . "\n";
		}
	}

	/**
	 * Structures and returns product data.
	 *
	 * @return array
	 */
	private function get_structured_product_data(): array {
		$data = [
			'@context' => 'https://schema.org/',
			'@graph'   => $this->get_product_data(),
		];

		return $this->get_product_data() ? $data : [];
	}

	/**
	 * Gets product data.
	 *
	 * @return array
	 */
	private function get_product_data(): array {
		return $this->product_data;
	}

	/**
	 * Structures and returns image data.
	 *
	 * @return array
	 */
	private function get_structured_image_data(): array {
		$data = [
			'@context'        => 'https://schema.org/',
			'@type'           => 'ImageGallery',
			'associatedMedia' => $this->get_image_data(),
		];

		return $this->get_image_data() ? $data : [];
	}

	/**
	 * Get image data
	 *
	 * @return array
	 */
	private function get_image_data(): array {
		return $this->image_data;
	}

	/**
	 * Get structured data for post
	 *
	 * @return array
	 */
	private function get_structured_post_data(): array {
		$data = array(
			'@context' => 'https://schema.org/',
			'@graph'   => $this->get_post_data(),
		);

		return $this->get_post_data() ? $data : array();
	}

	/**
	 * Get post data
	 *
	 * @return array
	 */
	private function get_post_data(): array {
		return $this->post_data;
	}

	/**
	 * Generates Image structured data.
	 *
	 * Hooked into `carousel_slider_image_gallery_loop` action hook.
	 *
	 * @param WP_Post $post Post data (default: null).
	 */
	public function generate_image_data( WP_Post $post ) {
		$image                = wp_get_attachment_image_src( $post->ID, 'full' );
		$markup['@type']      = 'ImageObject';
		$markup['contentUrl'] = $image[0];
		$markup['name']       = $post->post_title;

		$this->set_data( apply_filters( 'carousel_slider_structured_data_image', $markup, $post ) );
	}

	/**
	 * Sets data.
	 *
	 * @param array $data Structured data.
	 *
	 * @return void
	 */
	private function set_data( array $data ) {
		if ( ! isset( $data['@type'] ) || ! preg_match( '|^[a-zA-Z]{1,20}$|', $data['@type'] ) ) {
			return;
		}

		if ( 'ImageObject' === $data['@type'] ) {
			if ( ! $this->maybe_image_added( $data['contentUrl'] ) ) {
				$this->image_data[] = $data;
			}
		}

		if ( 'Product' === $data['@type'] ) {
			if ( ! $this->maybe_product_added( $data['@id'] ) ) {
				$this->product_data[] = $data;
			}
		}

		if ( 'BlogPosting' === $data['@type'] ) {
			if ( ! $this->maybe_post_added( $data['mainEntityOfPage']['@id'] ) ) {
				$this->post_data[] = $data;
			}
		}
	}

	/**
	 * Check if an image is already added to the list
	 *
	 * @param string|null $image_id The image id.
	 *
	 * @return boolean
	 */
	private function maybe_image_added( string $image_id ): bool {
		$image_data = $this->get_image_data();
		if ( count( $image_data ) > 0 ) {
			$image_data = array_map(
				function ( $data ) {
					return $data['contentUrl'];
				},
				$image_data
			);

			return in_array( $image_id, $image_data, true );
		}

		return false;
	}

	/**
	 * Check if a product is already added to the list
	 *
	 * @param string $product_id The product id.
	 *
	 * @return boolean
	 */
	private function maybe_product_added( string $product_id ): bool {
		$product_data = $this->get_product_data();
		if ( count( $product_data ) > 0 ) {
			$product_data = array_map(
				function ( $data ) {
					return $data['@id'];
				},
				$product_data
			);

			return in_array( $product_id, $product_data, true );
		}

		return false;
	}

	/**
	 * Check if a post is already added to the list
	 *
	 * @param string $post_id The post id.
	 *
	 * @return boolean
	 */
	private function maybe_post_added( string $post_id ): bool {
		$post_data = $this->get_post_data();
		if ( count( $post_data ) > 0 ) {
			$post_data = array_map(
				function ( $data ) {
					return $data['mainEntityOfPage']['@id'];
				},
				$post_data
			);

			return in_array( $post_id, $post_data, true );
		}

		return false;
	}

	/**
	 * Generates post structured data.
	 *
	 * Hooked into `carousel_slider_post_loop` action hook.
	 *
	 * @param WP_Post|mixed $post The WP_Post object.
	 */
	public function generate_post_data( $post ) {
		if ( ! $post instanceof WP_Post ) {
			return;
		}

		$image = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), 'normal' );

		$json['@type'] = 'BlogPosting';

		$json['mainEntityOfPage'] = array(
			'@type' => 'webpage',
			'@id'   => get_the_permalink(),
		);

		$json['publisher'] = array(
			'@type' => 'organization',
			'name'  => get_bloginfo( 'name' ),
		);

		$json['author'] = array(
			'@type' => 'person',
			'name'  => get_the_author(),
		);

		if ( $image ) {
			$json['image'] = array(
				'@type'  => 'ImageObject',
				'url'    => $image[0],
				'width'  => $image[1],
				'height' => $image[2],
			);
		}

		$json['datePublished'] = get_post_time( 'c' );
		$json['dateModified']  = get_the_modified_date( 'c' );
		$json['name']          = get_the_title();
		$json['headline']      = $json['name'];
		$json['description']   = get_the_excerpt();

		$this->set_data( apply_filters( 'carousel_slider_structured_data_post', $json, $post ) );
	}

	/**
	 * Generates Product structured data.
	 *
	 * @param WC_Product|mixed $product Product data (default: null).
	 */
	public function generate_product_data( $product ) {
		if ( ! $product instanceof WC_Product ) {
			return;
		}

		$name      = $product->get_name();
		$permalink = get_permalink( $product->get_id() );

		$markup['@type'] = 'Product';
		$markup['@id']   = $permalink;
		$markup['url']   = $markup['@id'];
		$markup['name']  = $name;

		$this->set_data( apply_filters( 'carousel_slider_structured_data_product', $markup, $product ) );
	}
}
includes/Frontend/Frontend.php000064400000006335151727276530012447 0ustar00<?php

namespace CarouselSlider\Frontend;

use CarouselSlider\Assets;
use CarouselSlider\Helper;
use CarouselSlider\Interfaces\SliderViewInterface;
use WP_Post;

defined( 'ABSPATH' ) || exit;

/**
 * Frontend class
 *
 * The frontend-functionality-specific class of the plugin
 */
class Frontend {

	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	protected static $instance;

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_shortcode( 'carousel_slide', [ self::$instance, 'carousel_slide' ] );
			add_action( 'wp_enqueue_scripts', [ self::$instance, 'frontend_scripts' ], 15 );
		}

		return self::$instance;
	}

	/**
	 * A shortcode for rendering the carousel slide.
	 *
	 * @param array $attributes Shortcode attributes.
	 *
	 * @return string  The shortcode output
	 */
	public function carousel_slide( array $attributes ): string {
		if ( empty( $attributes['id'] ) ) {
			return '';
		}

		$slider_id = intval( $attributes['id'] );

		// Check if id is valid or not.
		$post = get_post( $slider_id );
		if ( ! ( $post instanceof WP_Post && CAROUSEL_SLIDER_POST_TYPE === $post->post_type ) ) {
			return '';
		}

		$slide_type = get_post_meta( $slider_id, '_slide_type', true );
		$slide_type = array_key_exists( $slide_type, Helper::get_slide_types() ) ? $slide_type : 'image-carousel';

		// If the scripts and styles are not enqueued yet, then enqueued it now.
		$this->load_scripts_if_not_loaded();

		$view = Helper::get_slider_view( $slide_type );
		if ( $view instanceof SliderViewInterface ) {
			$view->set_slider_id( $slider_id );
			$view->set_slider_type( $slide_type );

			return $view->render();
		}

		return apply_filters( 'carousel_slider/view', '', $slider_id, $slide_type );
	}

	/**
	 * Load frontend scripts
	 */
	public function frontend_scripts() {
		if ( ! $this->should_load_scripts() ) {
			return;
		}

		if ( Helper::is_using_swiper() ) {
			wp_enqueue_style( 'carousel-slider-frontend-v2' );
			wp_enqueue_script( 'carousel-slider-frontend-v2' );
		} else {
			wp_enqueue_style( 'carousel-slider-frontend' );
			wp_enqueue_script( 'carousel-slider-frontend' );
		}
	}

	/**
	 * Check if it should load frontend scripts
	 *
	 * @return bool
	 */
	private function should_load_scripts(): bool {
		$load_scripts = Helper::get_setting( 'load_scripts', 'optimized' );
		if ( 'always' === $load_scripts ) {
			return true;
		}

		global $post;
		$load_scripts = is_active_widget( false, false, 'widget_carousel_slider', true ) ||
						( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'carousel_slide' ) );

		return apply_filters( 'carousel_slider_load_scripts', $load_scripts );
	}

	/**
	 * Load scripts if not loaded yet
	 *
	 * @return void
	 */
	protected function load_scripts_if_not_loaded() {
		if ( wp_script_is( 'carousel-slider-frontend', 'enqueued' ) ) {
			return;
		}
		if ( 'optimized-loader' !== Helper::get_setting( 'load_scripts' ) ) {
			return;
		}
		wp_enqueue_script( 'carousel-slider-frontend' );
		add_action(
			'wp_footer',
			function () {
				Helper::print_unescaped_internal_string( Assets::get_style_loader_script() );
			},
			0
		);
	}
}
includes/Integration/Elementor/ElementorExtension.php000064400000002352151727276530017150 0ustar00<?php

namespace CarouselSlider\Integration\Elementor;

use CarouselSlider\Assets;
use Elementor\Plugin;

defined( 'ABSPATH' ) || exit;

/**
 * ElementorExtension class
 */
class ElementorExtension {

	/**
	 * The instance of the class.
	 *
	 * @var self
	 */
	private static $instance = null;

	/**
	 * The instance of the class
	 *
	 * @return ElementorExtension|null
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'elementor/frontend/after_register_scripts', [ self::$instance, 'widget_scripts' ] );
			add_action( 'elementor/widgets/widgets_registered', [ self::$instance, 'register_widgets' ] );
		}

		return self::$instance;
	}

	/**
	 * Widget scrips
	 */
	public function widget_scripts() {
		wp_register_script(
			'carousel-slider-elementor',
			Assets::get_assets_url( 'js/frontend.js' ),
			[ 'elementor-frontend', 'jquery' ],
			'1.0.0',
			true
		);
		wp_register_style(
			'carousel-slider-elementor',
			Assets::get_assets_url( 'css/frontend.css' ),
			[],
			CAROUSEL_SLIDER_VERSION
		);
	}

	/**
	 * Register Elementor widgets
	 */
	public function register_widgets() {
		Plugin::instance()->widgets_manager->register_widget_type( new ElementorWidget() );
	}
}
includes/Integration/Elementor/ElementorWidget.php000064400000010443151727276530016417 0ustar00<?php

namespace CarouselSlider\Integration\Elementor;

use CarouselSlider\Frontend\Frontend;
use CarouselSlider\Helper;
use Elementor\Controls_Manager;
use Elementor\Widget_Base;

defined( 'ABSPATH' ) || exit;

/**
 * ElementorWidget class
 */
class ElementorWidget extends Widget_Base {

    /**
     * Get element name.
     *
     * @inheritDoc
     */
    public function get_name(): string {
        return 'carousel-slider-elementor';
    }

    /**
     * Get element title.
     *
     * @inheritDoc
     */
    public function get_title(): string {
        return esc_html__( 'Carousel Slider - Elementor', 'carousel-slider' );
    }

    /**
     * Get widget icon.
     *
     * @inheritDoc
     */
    public function get_icon(): string {
        return 'eicon-carousel';
    }

    /**
     * Get script dependencies.
     *
     * @inheritDoc
     */
    public function get_script_depends(): array {
        return [ 'carousel-slider-frontend' ];
    }

    /**
     * Get style dependencies.
     *
     * @inheritDoc
     */
    public function get_style_depends(): array {
        return [ 'carousel-slider-frontend' ];
    }

    /**
     * Get widget keywords.
     *
     * @inheritDoc
     */
    public function get_keywords(): array {
        return [ 'image', 'photo', 'carousel', 'slider' ];
    }

    /**
     * Register controls.
     *
     * @inheritDoc
     */
    protected function register_controls() {
        $posts   = Helper::get_sliders();
        $options = [];
        foreach ( $posts as $post ) {
            $options[ $post->ID ] = $post->post_title;
        }

        $this->start_controls_section(
                'content_section',
                [
                        'label' => __( 'Slider Settings', 'carousel-slider' ),
                        'tab'   => Controls_Manager::TAB_CONTENT,
                ]
        );

        $this->add_control(
                'slider_id',
                [
                        'label'      => __( 'Choose slider', 'carousel-slider' ),
                        'type'       => Controls_Manager::SELECT,
                        'input_type' => 'url',
                        'options'    => $options,
                ]
        );

        $this->add_control(
                'site_url',
                [
                        'type'       => Controls_Manager::HIDDEN,
                        'input_type' => 'hidden',
                        'value'      => site_url(),
                ]
        );

        $this->end_controls_section();
    }

    /**
     * Render element output in the editor.
     *
     * @inheritDoc
     */
    public function content_template() {
        ?>
        <div class="carousel-slider-iframe-container">
            <div class="carousel-slider-iframe-overlay"></div>
            <iframe class="carousel-slider-iframe"
                    src="{{settings.site_url}}?carousel_slider_preview=1&carousel_slider_iframe=1&slider_id={{settings.slider_id}}"
                    height="0" width="500"></iframe>
        </div>
        <?php
    }

    /**
     * Render element.
     *
     * @inheritDoc
     */
    protected function render() {
        $settings  = $this->get_settings_for_display();
        $slider_id = intval( $settings['slider_id'] );
        $action    = $_GET['action'] ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

        if ( 'elementor' === $action ) {
            $args = add_query_arg(
                    [
                            'carousel_slider_preview' => true,
                            'carousel_slider_iframe'  => true,
                            'slider_id'               => $slider_id,
                    ],
                    site_url()
            );

            $html = '<div class="carousel-slider-iframe-container">';
            $html .= '<div class="carousel-slider-iframe-overlay"></div>';
            $html .= '<iframe class="carousel-slider-iframe" src="' . $args . '" height="0" width="500"></iframe>';
            $html .= '</div>';
            echo wp_kses_post( $html );

            return;
        }

        $html = '<div class="carousel-slider-elementor-widget">';
        $html .= Frontend::init()->carousel_slide( [ 'id' => $slider_id ] );
        $html .= '</div>';

        echo wp_kses_post( $html );
    }
}
includes/Integration/DiviBuilder/Module.php000064400000004011151727276540015011 0ustar00<?php

namespace CarouselSlider\Integration\DiviBuilder;

use CarouselSlider\Frontend\Frontend;
use CarouselSlider\Helper;
use ET_Builder_Module;

defined( 'ABSPATH' ) || exit;

/**
 * Module class
 */
class Module extends ET_Builder_Module {
	/**
	 * Module slug
	 *
	 * @var string
	 */
	public $slug = 'carousel_slider_divi_module';

	/**
	 * Enable support visual builder
	 *
	 * @var string
	 */
	public $vb_support = 'on';

	/**
	 * Credits of our custom modules.
	 *
	 * @var string[]
	 */
	protected $module_credits = [
		'module_uri' => 'https://wordpress.org/plugins/carousel-slider',
		'author'     => 'Sayful Islam',
		'author_uri' => 'https://sayfulislam.com',
	];

	/**
	 * Init module
	 *
	 * @return void
	 */
	public function init() {
		$this->name = esc_html__( 'Carousel Slider', 'carousel-slider' );
	}

	/**
	 * Get the settings fields data for this element.
	 *
	 * @inheritDoc
	 */
	public function get_fields(): array {
		$posts   = Helper::get_sliders();
		$options = [];
		foreach ( $posts as $post ) {
			$options[ $post->ID ] = $post->post_title;
		}

		return [
			'slider_id' => [
				'label'           => esc_html__( 'Slider', 'carousel-slider' ),
				'description'     => esc_html__( 'Select a slider.', 'carousel-slider' ),
				'type'            => 'select',
				'option_category' => 'basic_option',
				'options'         => $options,
			],
			'site_url'  => [
				'type'  => 'hidden',
				'value' => site_url(),
			],
		];
	}

	/**
	 * Generates the module's HTML output based on {@see self::$props}. This method should be
	 * overridden in module classes.
	 *
	 * @param array  $unprocessed_props List of unprocessed attributes.
	 * @param string $content Content being processed.
	 * @param string $render_slug Slug of module that is used for rendering output.
	 *
	 * @return string The module's HTML output.
	 */
	public function render( $unprocessed_props, $content = null, $render_slug ) {
		$slider_id = intval( $this->props['slider_id'] );

		return Frontend::init()->carousel_slide( [ 'id' => $slider_id ] );
	}
}
includes/Integration/DiviBuilder/DiviBuilderModule.php000064400000003605151727276540017144 0ustar00<?php

namespace CarouselSlider\Integration\DiviBuilder;

use ET_Builder_Module;

defined( 'ABSPATH' ) || exit;

/**
 * DiviBuilderModule class
 */
class DiviBuilderModule {

	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	private static $instance = null;

	/**
	 * The instance of the class
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'carousel_slider/activation', [ self::$instance, 'activation' ] );
			add_action( 'wp_enqueue_scripts', [ self::$instance, 'load_scripts' ] );
			add_action( 'et_builder_ready', [ self::$instance, 'load_modules' ] );
		}

		return self::$instance;
	}

	/**
	 * Force the legacy backend builder to reload its template cache.
	 * This ensures that custom modules are available for use right away.
	 */
	public function activation() {
		if ( function_exists( 'et_pb_force_regenerate_templates' ) ) {
			et_pb_force_regenerate_templates();
		}
	}

	/**
	 * Load module script
	 */
	public function load_scripts() {
		if ( empty( $_GET['et_fb'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			return;
		}
		wp_enqueue_style(
			'carousel-slider-divi-modules',
			CAROUSEL_SLIDER_ASSETS . '/css/admin-divi-modules.css',
			[],
			CAROUSEL_SLIDER_VERSION
		);
		wp_enqueue_script(
			'carousel-slider-divi-modules',
			CAROUSEL_SLIDER_ASSETS . '/js/admin-divi-modules.js',
			[ 'react', 'react-dom' ],
			CAROUSEL_SLIDER_VERSION,
			true
		);
		wp_localize_script( 'carousel-slider-divi-modules', 'csDivi', [ 'site_url' => site_url() ] );
	}

	/**
	 * Load modules
	 */
	public function load_modules() {
		if ( ! self::should_load_modules() ) {
			return;
		}
		new Module();
	}

	/**
	 * Check if we should load modules
	 *
	 * @return bool
	 */
	public static function should_load_modules(): bool {
		return class_exists( ET_Builder_Module::class );
	}
}
includes/Integration/VisualComposer/Element.php000064400000003433151727276540015735 0ustar00<?php

namespace CarouselSlider\Integration\VisualComposer;

defined( 'ABSPATH' ) || exit;

/**
 * Element class
 */
class Element {
	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	private static $instance = null;

	/**
	 * Ensures only one instance of this class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			self::$instance->integrate_with_vc();
		}

		return self::$instance;
	}

	/**
	 * Integrate with visual composer
	 */
	public function integrate_with_vc() {
		// Check if Visual Composer is installed.
		if ( ! function_exists( 'vc_map' ) ) {
			return;
		}

		vc_map(
			array(
				'name'        => __( 'Carousel Slider', 'carousel-slider' ),
				'description' => __( 'Place Carousel Slider.', 'carousel-slider' ),
				'base'        => 'carousel_slide',
				'controls'    => 'full',
				'icon'        => CAROUSEL_SLIDER_ASSETS . '/static-images/logo.svg',
				'category'    => __( 'Content', 'carousel-slider' ),
				'params'      => array(
					array(
						'type'       => 'dropdown',
						'holder'     => 'div',
						'class'      => 'carousel-slider-id',
						'param_name' => 'id',
						'value'      => $this->carousels_list(),
						'heading'    => __( 'Choose Carousel Slide', 'carousel-slider' ),
					),
				),
			)
		);
	}

	/**
	 * Generate array for carousel slider
	 *
	 * @return array
	 */
	private function carousels_list(): array {
		$carousels = get_posts(
			[
				'post_type'      => 'carousels',
				'post_status'    => 'publish',
				'posts_per_page' => - 1,
			]
		);

		$result = [];

		if ( count( $carousels ) ) {
			foreach ( $carousels as $carousel ) {
				$result[ esc_html( $carousel->post_title ) ] = $carousel->ID;
			}
		}

		return $result;
	}
}
includes/Abstracts/SwiperSetting.php000064400000006550151727276540013646 0ustar00<?php

namespace CarouselSlider\Abstracts;

use CarouselSlider\Helper;
use CarouselSlider\Supports\Validate;

/**
 * SwiperSettings class
 */
class SwiperSetting {
	/**
	 * Owl settings
	 *
	 * @var array
	 */
	protected $settings = [];

	/**
	 * Get slider settings
	 *
	 * @var SliderSetting|null
	 */
	protected $slider_setting = null;

	/**
	 * Class constructor
	 *
	 * @param  SliderSetting $slider_setting  slider setting class.
	 */
	public function __construct( SliderSetting $slider_setting ) {
		$this->slider_setting = $slider_setting;
		$this->read( $slider_setting );
	}

	/**
	 * Read settings
	 *
	 * @param  SliderSetting $setting  slider setting class.
	 *
	 * @return void
	 */
	public function read( SliderSetting $setting ) {
		$show_navigation = $setting->get_nav_visibility() !== 'never';
		$show_pagination = $setting->get_pagination_visibility() !== 'never';

		$this->settings = [
			'navigation'         => $show_navigation,
			'pagination'         => $show_pagination,
			'direction'          => $setting->get_slider_direction(),
			'loop'               => $setting->get_prop( 'loop' ),
			'slidesOffsetBefore' => $setting->get_prop( 'stage_padding', 0 ),
			'slidesOffsetAfter'  => $setting->get_prop( 'stage_padding', 0 ),
			'speed'              => $setting->get_prop( 'autoplay_speed', 300 ),
			'spaceBetween'       => $setting->get_prop( 'space_between' ),
			'slidesPerView'      => 1,
		];

		if ( ! $setting->is_slider() ) {
			$this->settings['breakpoints'] = $this->get_breakpoints();
		}

		if ( $setting->is_auto_width() ) {
			if ( isset( $this->settings['breakpoints'] ) ) {
				unset( $this->settings['breakpoints'] );
			}
			$this->settings['slidesPerView'] = 'auto';
		}

		if ( 'vertical' === $setting->get_slider_direction() || $setting->is_slider() ) {
			if ( isset( $this->settings['breakpoints'] ) ) {
				unset( $this->settings['breakpoints'] );
			}
		}

		if ( $show_navigation ) {
			$this->settings['navigation'] = [
				'nextEl' => '.swiper-button-next',
				'prevEl' => '.swiper-button-prev',
			];
		}

		if ( $show_pagination ) {
			$this->settings['pagination'] = [
				'el'        => '.swiper-pagination',
				'type'      => $setting->get_pagination_type(),
				'clickable' => true,
			];
		}

		if ( Validate::checked( $setting->get_option( 'scrollbar' ) ) ) {
			$this->settings['scrollbar'] = [
				'el' => '.swiper-scrollbar',
			];
		}

		$lazy = $setting->get_prop( 'lazy_load' );
		if ( Validate::checked( $lazy ) ) {
			$this->settings['lazy']          = [
				'loadPrevNext' => true,
			];
			$this->settings['preloadImages'] = false;
		}

		$autoplay = $setting->get_prop( 'autoplay' );
		if ( Validate::checked( $autoplay ) ) {
			$this->settings['autoplay'] = [
				'delay'             => $setting->get_prop( 'autoplay_delay' ),
				'pauseOnMouseEnter' => $setting->get_prop( 'autoplay_hover_pause' ),
			];
		}
	}

	/**
	 * Get breakpoints
	 *
	 * @return array
	 */
	public function get_breakpoints(): array {
		$slider_breakpoint = [];

		foreach ( $this->slider_setting->get_slides_per_view() as $prefix => $item ) {
			$slider_breakpoint[ Helper::get_breakpoint_width( $prefix ) ] = [ 'slidesPerView' => $item ];
		}

		return $slider_breakpoint;
	}

	/**
	 * Get all settings
	 *
	 * @return array
	 */
	public function all(): array {
		return apply_filters( 'carousel_slider/settings/swiper_settings', $this->settings, $this->slider_setting );
	}
}
includes/Abstracts/AbstractTemplate.php000064400000007202151727276540014271 0ustar00<?php

namespace CarouselSlider\Abstracts;

use CarouselSlider\Helper;
use WP_Error;

defined( 'ABSPATH' ) || exit;

/**
 * AbstractTemplate class
 * The base template class for any slider type
 *
 * @package CarouselSlider/Abstracts
 */
abstract class AbstractTemplate {
	/**
	 * Get default image carousel settings
	 *
	 * @return array
	 */
	public static function get_default_settings(): array {
		return [
			// General Settings.
			'_image_size'                  => 'medium',
			'_stage_padding'               => '0',
			'_margin_right'                => (string) Helper::get_default_setting( 'margin_right' ),
			'_lazy_load_image'             => Helper::get_default_setting( 'lazy_load_image' ),
			'_infinity_loop'               => 'on',
			'_auto_width'                  => 'off',
			// Autoplay Settings.
			'_autoplay'                    => 'on',
			'_autoplay_pause'              => 'on',
			'_autoplay_timeout'            => '5000',
			'_autoplay_speed'              => '500',
			// Navigation Settings.
			'_nav_button'                  => 'always',
			'_slide_by'                    => '1',
			'_arrow_position'              => 'outside',
			'_arrow_size'                  => '48',
			'_dot_nav'                     => 'on', // Always.
			'_bullet_position'             => 'center',
			'_bullet_size'                 => '10',
			'_bullet_shape'                => 'circle',
			'_nav_color'                   => Helper::get_default_setting( 'nav_color' ),
			'_nav_active_color'            => Helper::get_default_setting( 'nav_active_color' ),
			// Responsive Settings.
			'_items_portrait_mobile'       => '1',
			'_items_small_portrait_tablet' => '2',
			'_items_portrait_tablet'       => '3',
			'_items_small_desktop'         => '3',
			'_items_desktop'               => '3',
			'_items'                       => '4',
		];
	}

	/**
	 * Get a list of images sorted by its width and height
	 *
	 * @param string $image_size The image size.
	 * @param int    $per_page Item per page.
	 *
	 * @return array
	 */
	public static function get_images( string $image_size = 'full', int $per_page = 100 ): array {
		$args        = array(
			'order'          => 'DESC',
			'post_type'      => 'attachment',
			'post_mime_type' => 'image',
			'post_status'    => 'any',
			'posts_per_page' => $per_page,
		);
		$attachments = get_posts( $args );

		$images = [];

		foreach ( $attachments as $attachment ) {
			if ( ! in_array( $attachment->post_mime_type, [ 'image/jpeg', 'image/png' ], true ) ) {
				continue;
			}

			$src        = wp_get_attachment_image_src( $attachment->ID, $image_size );
			$_link_url  = get_post_meta( $attachment->ID, '_carousel_slider_link_url', true );
			$_image_alt = get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true );

			$images[] = [
				'id'           => $attachment->ID,
				'title'        => $attachment->post_title,
				'description'  => $attachment->post_content,
				'caption'      => $attachment->post_excerpt,
				'alt_text'     => $_image_alt,
				'link_url'     => $_link_url,
				'image_src'    => $src[0],
				'image_width'  => $src[1],
				'image_height' => $src[2],
			];
		}

		$widths  = wp_list_pluck( $images, 'image_width' );
		$heights = wp_list_pluck( $images, 'image_height' );

		// Sort the $images with $widths and $heights descending.
		array_multisort( $widths, SORT_DESC, $heights, SORT_DESC, $images );

		return $images;
	}

	/**
	 * Create a new slider.
	 *
	 * @param string $slider_title The slider title.
	 *
	 * @return int|WP_Error The WP_Post ID on success. The value 0 or \WP_Error on failure.
	 */
	public static function create_slider( string $slider_title ) {
		return Helper::create_slider( $slider_title );
	}
}
includes/Abstracts/SliderSetting.php000064400000034604151727276550013621 0ustar00<?php

namespace CarouselSlider\Abstracts;

use BadMethodCallException;
use CarouselSlider\Admin\MetaBoxConfig;
use CarouselSlider\Helper;
use CarouselSlider\Interfaces\SliderSettingInterface;
use CarouselSlider\Supports\Sanitize;
use CarouselSlider\Supports\Validate;

/**
 * SliderSetting class
 * The base slider setting for any slider type
 *
 * @method string get_nav_steps()
 * @method int get_stage_padding()
 * @method int get_space_between()
 * @method bool is_loop()
 * @method bool is_lazy_load()
 * @method bool is_auto_width()
 * @method bool is_autoplay()
 * @method bool has_autoplay_hover_pause()
 * @method int get_autoplay_delay()
 * @method int get_autoplay_speed()
 * @method int get_items_on_mobile()
 * @method int get_items_on_small_tablet()
 * @method int get_items_on_tablet()
 * @method int get_items_on_desktop()
 * @method int get_items_on_widescreen()
 * @method int get_items_on_fullhd()
 *
 * @package CarouselSlider/Abstracts
 */
class SliderSetting extends Data implements SliderSettingInterface {

	const NAV_VISIBILITY        = array( 'always', 'never', 'hover' );
	const NAV_POSITION          = array( 'inside', 'outside' );
	const PAGINATION_VISIBILITY = array( 'always', 'never', 'hover' );
	const PAGINATION_TYPE       = array( 'bullets', 'fraction', 'progressbar', 'custom' );
	const SLIDE_EFFECTS         = array( 'slide', 'fade', 'cube', 'coverflow', 'flip', 'creative', 'cards' );

	/**
	 * The slider id.
	 *
	 * @var int
	 */
	protected $slider_id = 0;

	/**
	 * Get slider type
	 *
	 * @var string
	 */
	protected $slider_type = null;

	/**
	 * Is data read from the server?
	 *
	 * @var bool
	 */
	protected $data_read = false;

	/**
	 * Global settings
	 *
	 * @var array
	 */
	protected static $global_settings = array();

	/**
	 * Class constructor
	 *
	 * @param  int  $slider_id  The slider id.
	 * @param  bool $read_metadata  Should read metadata immediately.
	 */
	public function __construct( int $slider_id, bool $read_metadata = true ) {
		$this->slider_id = $slider_id;
		if ( $read_metadata ) {
			$this->read_metadata();
			if ( method_exists( $this, 'read_extra_metadata' ) ) {
				$this->read_extra_metadata();
			}
		}
	}

	/**
	 * Get global settings
	 *
	 * @return array
	 */
	public static function get_global_settings(): array {
		return Helper::get_global_settings();
	}

	/**
	 * Does this collection have a given key?
	 *
	 * @param  string $key  The data key.
	 *
	 * @return bool
	 */
	public static function has_global_option( string $key ): bool {
		return array_key_exists( $key, self::get_global_settings() );
	}

	/**
	 * Get option
	 *
	 * @param  string $key  option key.
	 * @param  mixed  $default_value  default value.
	 *
	 * @return mixed
	 */
	public function get_global_option( string $key, $default_value = '' ) {
		if ( static::has_global_option( $key ) ) {
			return static::get_global_settings()[ $key ];
		}

		return $default_value;
	}

	/**
	 * Get option for key
	 * If there is no option for a key, return it from the global option.
	 *
	 * @param  string $key  option key.
	 * @param  mixed  $default_value  default value to return if a data key does not exist.
	 *
	 * @return mixed The key's value, or the default value
	 */
	public function get_option( string $key, $default_value = '' ) {
		if ( $this->has_prop( $key ) ) {
			return $this->get_prop( $key, $default_value );
		}

		return $this->get_global_option( $key, $default_value );
	}

	/**
	 * Get slider Id
	 *
	 * @return int
	 */
	public function get_slider_id(): int {
		return $this->slider_id;
	}

	/**
	 * Get slider type
	 *
	 * @return string
	 */
	public function get_slider_type(): string {
		if ( is_null( $this->slider_type ) ) {
			$slide_type = get_post_meta( $this->get_slider_id(), '_slide_type', true );
			$this->set_slider_type( $slide_type );
		}

		return $this->slider_type;
	}

	/**
	 * Set slider type
	 *
	 * @param  mixed $type  The slider type.
	 *
	 * @return void
	 */
	public function set_slider_type( $type ) {
		if ( array_key_exists( $type, Helper::get_slide_types() ) ) {
			$this->slider_type = $type;
		} else {
			$this->slider_type = 'image-carousel';
		}
	}

	/**
	 * Get image size
	 *
	 * @return string
	 */
	public function get_image_size(): string {
		$size = $this->get_option( 'image_size', 'medium_large' );

		return array_key_exists( $size, Helper::get_available_image_sizes() ) ? $size : 'medium_large';
	}

	/**
	 * If it should lazily load image
	 *
	 * @return bool
	 */
	public function lazy_load_image(): bool {
		$default = Helper::get_default_setting( 'lazy_load_image' );

		return Validate::checked( $this->get_option( 'lazy_load', $default ) );
	}

	/**
	 * Set nav visibility
	 *
	 * @param  mixed $value  The navigation visibility.
	 */
	public function set_nav_visibility( $value ) {
		// For backup compatability.
		$value = str_replace( array( 'off', 'on' ), array( 'never', 'hover' ), $value );

		if ( in_array( $value, static::NAV_VISIBILITY, true ) ) {
			$this->data['nav_visibility'] = $value;
		}
	}


	/**
	 * Get nav visibility
	 *
	 * @return string
	 */
	public function get_nav_visibility(): string {
		$value = $this->get_prop( 'nav_visibility' );
		// For backup compatability.
		return str_replace( array( 'off', 'on' ), array( 'never', 'hover' ), $value );
	}

	/**
	 * Set nav position
	 *
	 * @param  mixed $value  The navigation position.
	 */
	public function set_nav_position( $value ) {
		if ( in_array( $value, static::NAV_POSITION, true ) ) {
			$this->data['nav_position'] = $value;
		}
	}

	/**
	 * Set nav steps
	 *
	 * @param  mixed $value  The navigation steps.
	 */
	public function set_nav_steps( $value ) {
		if ( in_array( $value, array( 'page', '-1', - 1 ), true ) ) {
			$this->data['nav_steps'] = 'page';
		} else {
			$this->data['nav_steps'] = max( 1, intval( $value ) );
		}
	}

	/**
	 * Set pagination visibility
	 *
	 * @param  mixed $value  The pagination visibility value.
	 */
	public function set_pagination_visibility( $value ) {
		// For backup compatability.
		$value = str_replace( array( 'off', 'on' ), array( 'never', 'always' ), $value );

		if ( in_array( $value, static::PAGINATION_VISIBILITY, true ) ) {
			$this->data['pagination_visibility'] = $value;
		}
	}

	/**
	 * Get pagination visibility
	 *
	 * @return string
	 */
	public function get_pagination_visibility(): string {
		$value = $this->get_prop( 'pagination_visibility' );
		// For backup compatability.
		return str_replace( array( 'off', 'on' ), array( 'never', 'always' ), $value );
	}

	/**
	 * Get pagination type. Only works with Pro.
	 *
	 * @return string
	 */
	public function get_pagination_type(): string {
		$value = $this->get_prop( 'pagination_type', 'bullets' );

		return in_array( $value, static::PAGINATION_TYPE, true ) ? $value : 'bullets';
	}

	/**
	 * Get slider direction. Only works with pro.
	 *
	 * @return string
	 */
	public function get_slider_direction(): string {
		return 'vertical' === $this->get_option( 'slider_direction' ) ? 'vertical' : 'horizontal';
	}

	/**
	 * Get slider direction. Only works with pro.
	 *
	 * @return string
	 */
	public function get_slider_effect(): string {
		if ( ! Helper::is_pro_active() ) {
			return 'slide';
		}
		$effect = $this->get_option( 'slider_effect' );

		return in_array( $effect, static::SLIDE_EFFECTS, true ) ? $effect : 'slide';
	}

	/**
	 * Get sliders per view
	 *
	 * @return array
	 */
	public function get_slides_per_view(): array {
		// For backup compatability.
		if ( ! $this->has_prop( 'slides_per_view' ) ) {
			return array(
				'xs'  => (int) $this->get_items_on_mobile(),
				'sm'  => (int) $this->get_items_on_small_tablet(),
				'md'  => (int) $this->get_items_on_tablet(),
				'lg'  => (int) $this->get_items_on_desktop(),
				'xl'  => (int) $this->get_items_on_widescreen(),
				'2xl' => (int) $this->get_items_on_fullhd(),
			);
		}
		$slides          = (array) $this->get_option( 'slides_per_view', array() );
		$slides          = wp_parse_args( $slides, array( 'xs' => 1 ) );
		$slides_per_view = array();
		foreach ( $slides as $prefix => $item ) {
			$slides_per_view[ esc_attr( $prefix ) ] = floatval( $item );
		}

		return $slides_per_view;
	}

	/**
	 * Is it a type of slider?
	 *
	 * @return bool
	 */
	public function is_slider(): bool {
		return 'slider' === $this->get_prop( 'type_of_slider' );
	}

	/**
	 * Check if we are using swiper
	 *
	 * @return bool
	 */
	public function is_using_swiper(): bool {
		return Helper::is_using_swiper();
	}

	/**
	 * Read setting from the database
	 *
	 * @param  array $values  The value to be read.
	 *
	 * @return void
	 */
	public function read_metadata( array $values = array() ) {
		if ( $this->data_read ) {
			return;
		}
		if ( empty( $values ) ) {
			$metadata = get_post_meta( $this->get_slider_id() );
			foreach ( $metadata as $meta_key => $meta_value ) {
				$values[ $meta_key ] = maybe_unserialize( $meta_value[0] );
			}
		}
		$fields_settings = self::get_fields_settings();
		foreach ( $fields_settings as $attribute => $config ) {
			$this->read_single_metadata( $attribute, $config, $values );
		}
		$this->data_read = true;
	}

	/**
	 * Read data from HTTP POST variable
	 *
	 * @param  array $values  The values from HTTP POST variables.
	 *
	 * @return void
	 */
	public function read_http_post_variables( array $values = array() ) {
		$fields_settings = self::get_fields_settings();
		foreach ( $fields_settings as $attribute => $config ) {
			$this->read_single_metadata( $attribute, $config, $values );
		}
	}

	/**
	 * Read data from HTTP POST variable
	 *
	 * @param  array $values  The values from HTTP POST variables.
	 *
	 * @return void
	 */
	public function read_extra_http_post_variables( array $values = array() ) {
		if ( method_exists( get_called_class(), 'extra_props' ) ) {
			foreach ( static::extra_props() as $attribute => $config ) {
				$this->read_single_metadata( $attribute, $config, $values );
			}
		}
	}

	/**
	 * Read single metadata
	 *
	 * @param  string $attribute  property name.
	 * @param  array  $field  The field settings.
	 * @param  array  $values  The values.
	 *
	 * @return void
	 */
	public function read_single_metadata( string $attribute, array $field, array $values ) {
		$method_name = 'set_' . $attribute;
		$value       = $values[ $field['id'] ] ?? ( $field['default'] ?? null );
		if ( method_exists( $this, $method_name ) ) {
			$this->$method_name( $value );
		} else {
			$value = $this->prepare_item_for_response( $field['type'], $value );
			$this->set_prop( $attribute, $value );
		}
	}

	/**
	 * Write metadata
	 * make sure to backward compatibility for the following props
	 * --- nav_visibility, pagination_visibility, nav_steps
	 * --- Convert boolean value to 'on' and 'off'
	 *
	 * @return void
	 */
	public function write_metadata() {
		$fields_settings = self::get_fields_settings();
		foreach ( $fields_settings as $prop_name => $field ) {
			$value = $this->get_prop( $prop_name );
			if ( 'nav_visibility' === $prop_name ) {
				$value = str_replace( array( 'never', 'hover' ), array( 'off', 'on' ), $value );
			}
			if ( 'pagination_visibility' === $prop_name ) {
				$value = str_replace( array( 'never', 'always' ), array( 'off', 'on' ), $value );
			}
			$sanitized_value = $this->prepare_item_for_database( $value, $field );
			update_post_meta( $this->slider_id, $field['id'], $sanitized_value );
		}
	}

	/**
	 * Sanitize value by data type
	 *
	 * @param  string $type  The type.
	 * @param  mixed  $value  The value.
	 *
	 * @return mixed
	 */
	protected function prepare_item_for_response( string $type, $value ) {
		if ( 'array' === $type && is_string( $value ) ) {
			$value = explode( ',', $value );
		}
		if ( 'int[]' === $type && is_string( $value ) ) {
			$value = array_filter( array_map( 'intval', explode( ',', $value ) ) );
		}
		if ( in_array( $type, array( 'int', 'number' ), true ) ) {
			$value = (int) $value;
		}
		if ( in_array( $type, array( 'bool', 'switch' ), true ) ) {
			$value = Validate::checked( $value );
		}

		return $value;
	}

	/**
	 * Prepare item for the database store
	 *
	 * @param  mixed $value  The value to be sanitized.
	 * @param  array $setting  The field setting.
	 *
	 * @return mixed
	 */
	protected function prepare_item_for_database( $value, array $setting ) {
		if ( isset( $setting['sanitize_callback'] ) && is_callable( $setting['sanitize_callback'] ) ) {
			return call_user_func( $setting['sanitize_callback'], $value );
		}
		if ( isset( $setting['choices'] ) && is_array( $setting['choices'] ) ) {
			return $this->sanitize_choices( $value, $setting );
		}
		if ( in_array( $setting['type'], array( 'bool', 'switch' ), true ) ) {
			return Validate::checked( $value ) ? 'on' : 'off';
		}

		return Sanitize::deep( $value );
	}

	/**
	 * Sanitize choices value
	 *
	 * @param  mixed $value  The value to be sanitized.
	 * @param  array $setting  The field setting.
	 *
	 * @return array|mixed|null
	 */
	public function sanitize_choices( $value, array $setting ) {
		$enum = array();
		foreach ( $setting['choices'] as $key => $choice ) {
			if ( is_array( $choice ) && isset( $choice['value'] ) ) {
				$enum[] = $choice['value'];
			} else {
				$enum[] = $key;
			}
		}

		$default = $setting['default'] ?? null;
		if ( isset( $setting['multiple'] ) ) {
			$sanitized_value = array();
			foreach ( (array) $value as $item ) {
				if ( in_array( $item, $enum, true ) ) {
					$sanitized_value[] = $item;
				}
			}

			return $sanitized_value;
		}

		return in_array( $value, $enum, true ) ? $value : $default;
	}

	/**
	 * Default properties
	 *
	 * @return array
	 */
	protected static function get_fields_settings(): array {
		return MetaBoxConfig::get_fields_settings();
	}

	/**
	 * Handle calling property via method
	 *
	 * @param  string $name  The name of the method being called.
	 * @param  array  $args  An enumerated array containing the parameters passed to the $name'ed method.
	 *
	 * @return mixed
	 * @throws BadMethodCallException Exception if not method available.
	 */
	public function __call( string $name, array $args ) {
		if ( preg_match( '/^(?P<prefix>get|is|has|should)_(?P<property>\s*.*)/', $name, $matches ) ) {
			if ( $this->has_prop( $matches['property'] ) ) {
				if ( in_array( $matches['prefix'], array( 'is', 'has', 'should' ), true ) ) {
					return Validate::checked( $this->get_prop( $matches['property'] ) );
				}

				return $this->get_prop( $matches['property'] );
			}
			if ( static::has_global_option( $matches['property'] ) ) {
				return static::get_global_option( $matches['property'] );
			}
		}
		throw new BadMethodCallException(
			'Call to undefined method ' . esc_html( sprintf( '%s::%s()', __CLASS__, $name ) )
		);
	}
}
includes/Abstracts/OwlSetting.php000064400000003737151727276550013143 0ustar00<?php

namespace CarouselSlider\Abstracts;

use CarouselSlider\Helper;

/**
 * OwlSetting class
 * The owl carousel JavaScript option generator.
 *
 * @package CarouselSlider/Abstracts
 */
class OwlSetting {

	/**
	 * Owl settings
	 *
	 * @var array
	 */
	protected $settings = [];

	/**
	 * Get slider settings
	 *
	 * @var SliderSetting|null
	 */
	protected $slider_setting = null;

	/**
	 * Class constructor
	 *
	 * @param  SliderSetting $slider_setting  slider setting class.
	 */
	public function __construct( SliderSetting $slider_setting ) {
		$this->slider_setting = $slider_setting;
		$this->read( $slider_setting );
	}

	/**
	 * Read settings
	 *
	 * @param  SliderSetting $setting  slider setting class.
	 *
	 * @return void
	 */
	public function read( SliderSetting $setting ) {
		$this->settings = [
			'nav'                => $setting->get_nav_visibility() !== 'never',
			'dots'               => $setting->get_pagination_visibility() !== 'never',
			'slideBy'            => $setting->get_nav_steps(),
			'stagePadding'       => $setting->get_stage_padding(),
			'margin'             => $setting->get_space_between(),
			'loop'               => $setting->is_loop(),
			'lazyLoad'           => $setting->lazy_load_image(),
			'autoplay'           => $setting->is_autoplay(),
			'autoplayTimeout'    => $setting->get_autoplay_delay(),
			'autoplaySpeed'      => $setting->get_autoplay_speed(),
			'autoplayHoverPause' => $setting->has_autoplay_hover_pause(),
			'autoWidth'          => $setting->is_auto_width(),
		];

		if ( $this->slider_setting->is_slider() ) {
			$this->settings['items'] = 1;
		} else {
			foreach ( $this->slider_setting->get_slides_per_view() as $prefix => $item ) {
				$this->settings['responsive'][ Helper::get_breakpoint_width( $prefix ) ] = [ 'items' => $item ];
			}
		}
	}

	/**
	 * Get all settings
	 *
	 * @return array
	 */
	public function all(): array {
		return apply_filters( 'carousel_slider/settings/owl_settings', $this->settings, $this->slider_setting );
	}
}
includes/Abstracts/Data.php000064400000006234151727276550011710 0ustar00<?php

namespace CarouselSlider\Abstracts;

use ArrayAccess;
use JsonSerializable;

defined( 'ABSPATH' ) || exit;

/**
 * Class Data
 *
 * @package CarouselSlider\Abstracts
 */
class Data implements ArrayAccess, JsonSerializable {

	/**
	 * Object data
	 *
	 * @var array
	 */
	protected $data = [];

	/**
	 * String representation of the class
	 *
	 * @return string
	 */
	public function __toString() {
		return wp_json_encode( $this->to_array() );
	}

	/**
	 * Get collection item for a key
	 *
	 * @param string $name The property name.
	 *
	 * @return mixed
	 */
	public function __get( string $name ) {
		return $this->get_prop( $name );
	}

	/**
	 * Does this collection have a given key?
	 *
	 * @param string $name The property name.
	 *
	 * @return bool
	 */
	public function __isset( string $name ) {
		return $this->has_prop( $name );
	}

	/**
	 * Array representation of the class
	 *
	 * @return array
	 */
	public function to_array(): array {
		return $this->data;
	}

	/**
	 * Does this collection have a given key?
	 *
	 * @param string $key The data key.
	 *
	 * @return bool
	 */
	public function has_prop( string $key ): bool {
		return isset( $this->data[ $key ] );
	}

	/**
	 * Set collection item
	 *
	 * @param string $key The data key.
	 * @param mixed  $value The data value.
	 */
	public function set_prop( string $key, $value ) {
		$this->data[ $key ] = $value;
	}

	/**
	 * Get collection item for a key
	 *
	 * @param string $key The data key.
	 * @param mixed  $default_value The default value to return if the data key does not exist.
	 *
	 * @return mixed The key's value, or the default value
	 */
	public function get_prop( string $key, $default_value = '' ) {
		if ( $this->has_prop( $key ) ) {
			return $this->data[ $key ];
		}

		return $default_value;
	}

	/**
	 * Remove item from the collection
	 *
	 * @param string $key The data key.
	 */
	public function remove_prop( string $key ) {
		if ( $this->has_prop( $key ) ) {
			unset( $this->data[ $key ] );
		}
	}

	/**
	 * Whether an offset exists
	 *
	 * @param mixed $offset An offset to check for.
	 *
	 * @return boolean true on success or false on failure.
	 */
	public function offsetExists( $offset ): bool {
		return $this->has_prop( $offset );
	}

	/**
	 * Offset to retrieve
	 *
	 * @param mixed $offset The offset to retrieve.
	 *
	 * @return mixed Can return all value types.
	 */
	#[\ReturnTypeWillChange]
	public function offsetGet( $offset ) {
		return $this->get_prop( $offset );
	}

	/**
	 * Offset to set
	 *
	 * @param mixed $offset The offset to assign the value to.
	 * @param mixed $value The value to set.
	 *
	 * @return void
	 */
	#[\ReturnTypeWillChange]
	public function offsetSet( $offset, $value ) {
		$this->set_prop( $offset, $value );
	}

	/**
	 * Offset to unset
	 *
	 * @param mixed $offset The offset to unset.
	 *
	 * @return void
	 */
	#[\ReturnTypeWillChange]
	public function offsetUnset( $offset ) {
		$this->remove_prop( $offset );
	}

	/**
	 * Specify data which should be serialized to JSON
	 *
	 * @return array data, which can be serialized by json_encode
	 * which is a value of any type other than a resource.
	 */
	public function jsonSerialize(): array {
		return $this->to_array();
	}
}
includes/Abstracts/AbstractView.php000064400000017067151727276550013443 0ustar00<?php

namespace CarouselSlider\Abstracts;

use CarouselSlider\Helper;
use CarouselSlider\Interfaces\SliderSettingInterface;
use CarouselSlider\Interfaces\SliderViewInterface;
use CarouselSlider\Supports\Validate;

defined( 'ABSPATH' ) || exit;

/**
 * AbstractView class
 * The base view class for any slider type
 *
 * @package CarouselSlider/Abstracts
 */
abstract class AbstractView implements SliderViewInterface {
	/**
	 * Slider id
	 *
	 * @var int
	 */
	protected $slider_id = 0;

	/**
	 * Slider type
	 *
	 * @var string
	 */
	protected $slider_type = '';

	/**
	 * The slider setting class
	 *
	 * @var SliderSetting
	 */
	protected $slider_setting;

	/**
	 * Render element.
	 * Generates the final HTML on the frontend.
	 *
	 * @return string
	 */
	abstract public function render(): string;

	/**
	 * Get slider id
	 *
	 * @return int
	 */
	public function get_slider_id(): int {
		return $this->slider_id;
	}

	/**
	 * Set slider id
	 *
	 * @param  int $slider_id  The slider id.
	 */
	public function set_slider_id( int $slider_id ) {
		$this->slider_id = $slider_id;
	}

	/**
	 * Get slider type
	 *
	 * @return string
	 */
	public function get_slider_type(): string {
		return $this->slider_type;
	}

	/**
	 * Set slider type
	 *
	 * @param  string $slider_type  The slider type.
	 */
	public function set_slider_type( string $slider_type ) {
		$this->slider_type = $slider_type;
	}

	/**
	 * Get slider setting
	 *
	 * @return SliderSetting|SliderSettingInterface|Data
	 */
	public function get_slider_setting() {
		if ( ! $this->slider_setting instanceof SliderSettingInterface ) {
			$this->slider_setting = new SliderSetting( $this->get_slider_id() );
		}

		return $this->slider_setting;
	}

	/**
	 * Set slider setting class
	 *
	 * @param  SliderSettingInterface $slider_setting  The SliderSetting class.
	 */
	public function set_slider_setting( SliderSettingInterface $slider_setting ) {
		$this->slider_setting = $slider_setting;
	}

	/**
	 * Get slider javaScript package name
	 *
	 * @return string
	 */
	protected function get_slider_js_package(): string {
		$package = Helper::get_setting( 'slider_js_package' );

		return 'owl.carousel' === $package ? 'owl.carousel' : 'swiper';
	}

	/**
	 * Check if we are using swiper
	 *
	 * @return bool
	 */
	protected function is_using_swiper(): bool {
		return Helper::is_using_swiper();
	}

	/**
	 * Get slider start wrapper html
	 *
	 * @param  array $args  The additional arguments.
	 *
	 * @return string
	 */
	public function start_wrapper_html( array $args = [] ): string {
		$setting     = $this->get_slider_setting();
		$css_classes = [
			'carousel-slider-outer',
			'carousel-slider-outer-' . $this->get_slider_type(),
			'carousel-slider-outer-' . $this->get_slider_id(),
		];
		if ( $this->is_using_swiper() ) {
			$css_classes[] = 'swiper';
			$css_classes[] = sprintf( 'navigation-visibility-%s', $setting->get_nav_visibility() );
			$css_classes[] = sprintf( 'navigation-position-%s', $setting->get_option( 'nav_position' ) );
			$css_classes[] = sprintf( 'pagination-visibility-%s', $setting->get_pagination_visibility() );
			$css_classes[] = sprintf( 'pagination-shape-%s', $setting->get_option( 'pagination_shape' ) );
			$css_classes[] = sprintf( 'pagination-align-%s', $setting->get_option( 'pagination_alignment' ) );
		}

		$outer_attributes_array = [
			'class' => implode( ' ', $css_classes ),
			'style' => Helper::array_to_style( $this->get_css_variable() ),
		];

		$attributes_array = $this->get_slider_attributes( $args );

		$html  = '<div ' . join( ' ', Helper::array_to_attribute( $outer_attributes_array ) ) . '>' . PHP_EOL;
		$html .= '<div ' . join( ' ', $attributes_array ) . '>' . PHP_EOL;

		return $html;
	}

	/**
	 * Get slider end wrapper html
	 *
	 * @return string
	 */
	public function end_wrapper_html(): string {
		$html = '</div><!-- .carousel-slider-' . $this->get_slider_id() . ' -->' . PHP_EOL;
		if ( $this->is_using_swiper() ) {
			// If we need pagination.
			if ( $this->get_slider_setting()->get_pagination_visibility() !== 'never' ) {
				$html .= '<div class="swiper-pagination"></div>';
			}

			// If we need navigation.
			if ( $this->get_slider_setting()->get_nav_visibility() !== 'never' ) {
				$html .= '<div class="swiper-button-prev"></div><div class="swiper-button-next"></div>';
			}

			// If we need scrollbar.
			if ( Validate::checked( $this->get_slider_setting()->get_option( 'scrollbar' ) ) ) {
				$html .= '<div class="swiper-scrollbar"></div>';
			}
		}
		$html .= '</div><!-- .carousel-slider-outer-' . $this->get_slider_id() . ' -->' . PHP_EOL;

		return $html;
	}

	/**
	 * Get item wrapper start html
	 *
	 * @return string
	 */
	public function start_item_wrapper_html(): string {
		if ( $this->is_using_swiper() ) {
			return '<div class="swiper-slide">';
		}

		return '';
	}

	/**
	 * Get item wrapper end html
	 *
	 * @return string
	 */
	public function end_item_wrapper_html(): string {
		if ( $this->is_using_swiper() ) {
			return '</div>';
		}

		return '';
	}

	/**
	 * Get slider default attributes
	 *
	 * @param  array $args  The additional arguments.
	 *
	 * @return array
	 */
	protected function get_slider_attributes( array $args = [] ): array {
		$default_attributes = [
			'id'              => sprintf( "'id-%s", $this->get_slider_id() ),
			'class'           => implode( ' ', $this->get_css_classes() ),
			'data-slide-type' => $this->get_slider_type(),
		];

		if ( $this->is_using_swiper() ) {
			$swiper_settings = new SwiperSetting( $this->get_slider_setting() );

			$default_attributes['data-swiper'] = wp_json_encode( $swiper_settings->all() );
		} else {
			$owl_settings = new OwlSetting( $this->get_slider_setting() );

			$default_attributes['data-owl-settings'] = wp_json_encode( $owl_settings->all() );
		}

		$attributes = array_merge( $default_attributes, $this->extra_slider_attributes(), $args );

		return Helper::array_to_attribute( $attributes );
	}

	/**
	 * Get extra slider attributes
	 *
	 * @return array
	 */
	protected function extra_slider_attributes(): array {
		return [];
	}

	/**
	 * Get slider CSS style variables
	 *
	 * @return array
	 */
	public function get_css_variable(): array {
		$setting = $this->get_slider_setting();
		$css_var = [
			'--carousel-slider-nav-color'        => $setting->get_prop( 'nav_color' ),
			'--carousel-slider-active-nav-color' => $setting->get_prop( 'nav_active_color' ),
			'--carousel-slider-arrow-size'       => $setting->get_prop( 'nav_size' ) . 'px',
			'--carousel-slider-bullet-size'      => $setting->get_prop( 'pagination_size' ) . 'px',
		];

		if ( $this->is_using_swiper() ) {
			$css_var['--swiper-theme-color']            = $setting->get_prop( 'nav_color' );
			$css_var['--swiper-navigation-size']        = $setting->get_prop( 'nav_size' ) . 'px';
			$css_var['--swiper-pagination-bullet-size'] = $setting->get_prop( 'pagination_size' ) . 'px';
		}

		return apply_filters( 'carousel_slider/css_var', $css_var, $setting );
	}

	/**
	 * Get slider css classes
	 *
	 * @return string[]
	 */
	public function get_css_classes(): array {
		$setting = $this->get_slider_setting();

		$css_classes = [
			'carousel-slider',
			'carousel-slider-' . $this->get_slider_id(),
			'arrows-visibility-' . $setting->get_nav_visibility(),
			'dots-visibility-' . $setting->get_pagination_visibility(),
			'arrows-' . $setting->get_option( 'nav_position' ),
			'dots-' . $setting->get_option( 'pagination_alignment' ),
			'dots-' . $setting->get_option( 'pagination_shape' ),
		];

		if ( $this->is_using_swiper() ) {
			$css_classes[] = 'swiper-wrapper';
		} else {
			$css_classes[] = 'owl-carousel';
		}

		return apply_filters( 'carousel_slider/css_classes', $css_classes, $setting );
	}
}
includes/Plugin.php000064400000016741151727276550010353 0ustar00<?php

namespace CarouselSlider;

use Automattic\WooCommerce\Utilities\FeaturesUtil;
use CarouselSlider\Admin\Admin;
use CarouselSlider\Admin\GutenbergBlock;
use CarouselSlider\Admin\MetaBox;
use CarouselSlider\Admin\PreviewMetaBox;
use CarouselSlider\Admin\Setting;
use CarouselSlider\Admin\Upgrader;
use CarouselSlider\CLI\Command;
use CarouselSlider\Frontend\Frontend;
use CarouselSlider\Frontend\Preview;
use CarouselSlider\Frontend\StructuredData;
use CarouselSlider\Integration\DiviBuilder\DiviBuilderModule;
use CarouselSlider\Integration\Elementor\ElementorExtension;
use CarouselSlider\Integration\VisualComposer\Element;
use CarouselSlider\Modules\HeroCarousel\Module as HeroCarouselModule;
use CarouselSlider\Modules\ImageCarousel\Module as ImageCarouselModule;
use CarouselSlider\Modules\PostCarousel\Module as PostCarouselModule;
use CarouselSlider\Modules\ProductCarousel\Module as ProductCarouselModule;
use CarouselSlider\Modules\VideoCarousel\Module as VideoCarouselModule;
use CarouselSlider\REST\CarouselController;
use CarouselSlider\Widget\CarouselSliderWidget;
use WP_CLI;
use WP_CLI_Command;

defined( 'ABSPATH' ) || exit;

/**
 * The main plugin handler class is responsible for initializing the plugin. The
 * class registers all the components required to run the plugin.
 */
class Plugin {

	/**
	 * The instance of the class
	 *
	 * @var self
	 */
	private static $instance;

	/**
	 * Holds various class instances
	 *
	 * @var array
	 */
	private $container = [];

	/**
	 * Get class from container
	 *
	 * @param  string  $key  The key used for class name.
	 *
	 * @return false|mixed
	 */
	public function get( string $key ) {
		return $this->container[ $key ] ?? false;
	}

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return self
	 */
	public static function init() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();

			add_action( 'init', [ self::$instance, 'includes' ] );
			add_action( 'init', [ self::$instance, 'register_post_type' ] );
			add_action( 'carousel_slider/activation', [ self::$instance, 'activation_includes' ] );
			add_action( 'carousel_slider/deactivation', [ self::$instance, 'deactivation_includes' ] );
			// Declare compatibility with WooCommerce plugin extensions.
			add_action( 'before_woocommerce_init', [ self::$instance, 'declaring_extension_compatibility' ] );
		}

		return self::$instance;
	}

	/**
	 * Instantiate the required classes
	 *
	 * @return void
	 */
	public function includes() {

		$this->container['assets'] = Assets::init();
		$this->container['widget'] = CarouselSliderWidget::init();

		// Load classes for admin area.
		if ( $this->is_request( 'admin' ) ) {
			$this->admin_includes();
		}

		// Load classes for the frontend area.
		if ( $this->is_request( 'frontend' ) ) {
			$this->frontend_includes();
		}

		// Load classes for ajax functionality.
		if ( $this->is_request( 'ajax' ) ) {
			$this->ajax_includes();
		}

		// WP-CLI Commands.
		if ( class_exists( WP_CLI::class ) && class_exists( WP_CLI_Command::class ) ) {
			WP_CLI::add_command( 'carousel-slider', Command::class );
		}

		$this->modules_includes();
	}

	/**
	 * Include modules main classes
	 *
	 * @return void
	 */
	public function modules_includes() {
		$this->container['module_image_carousel'] = ImageCarouselModule::init();
		$this->container['module_video_carousel'] = VideoCarouselModule::init();
		$this->container['module_post_carousel']  = PostCarouselModule::init();
		$this->container['module_hero_carousel']  = HeroCarouselModule::init();

		if ( Helper::is_woocommerce_active() ) {
			$this->container['module_product_carousel'] = ProductCarouselModule::init();
		}

		if ( Helper::is_wp_bakery_page_builder_active() ) {
			$this->container['vc_element'] = Element::init();
		}

		if ( Helper::is_divi_builder_active() ) {
			$this->container['divi_module'] = DiviBuilderModule::init();
		}

		if ( Helper::is_elementor_active() ) {
			$this->container['elementor_extension'] = ElementorExtension::init();
		}
	}

	/**
	 * Include admin classes
	 *
	 * @return void
	 */
	public function admin_includes() {
		$this->container['admin']            = Admin::init();
		$this->container['meta_box']         = MetaBox::init();
		$this->container['setting']          = Setting::init();
		$this->container['gutenberg_block']  = GutenbergBlock::init();
		$this->container['upgrader']         = Upgrader::init();
		$this->container['preview_meta_box'] = PreviewMetaBox::init();
	}

	/**
	 * Include frontend classes
	 *
	 * @return void
	 */
	public function frontend_includes() {
		$this->container['frontend']        = Frontend::init();
		$this->container['preview']         = Preview::init();
		$this->container['structured_data'] = StructuredData::init();

		add_action( 'rest_api_init', [ new CarouselController(), 'register_routes' ] );
	}

	/**
	 * Include frontend classes
	 *
	 * @return void
	 */
	public function ajax_includes() {
		$this->container['ajax'] = Ajax::init();
	}

	/**
	 * Carousel slider post-type
	 */
	public function register_post_type() {
		$labels = [
			'name'               => _x( 'Sliders', 'Post Type General Name', 'carousel-slider' ),
			'singular_name'      => _x( 'Slider', 'Post Type Singular Name', 'carousel-slider' ),
			'menu_name'          => __( 'Carousel Slider', 'carousel-slider' ),
			'parent_item_colon'  => __( 'Parent Slider:', 'carousel-slider' ),
			'all_items'          => __( 'All Sliders', 'carousel-slider' ),
			'view_item'          => __( 'View Slider', 'carousel-slider' ),
			'add_new_item'       => __( 'Add New Slider', 'carousel-slider' ),
			'add_new'            => __( 'Add New', 'carousel-slider' ),
			'edit_item'          => __( 'Edit Slider', 'carousel-slider' ),
			'update_item'        => __( 'Update Slider', 'carousel-slider' ),
			'search_items'       => __( 'Search Slider', 'carousel-slider' ),
			'not_found'          => __( 'Not found', 'carousel-slider' ),
			'not_found_in_trash' => __( 'Not found in Trash', 'carousel-slider' ),
		];
		$args   = [
			'label'               => __( 'Slider', 'carousel-slider' ),
			'description'         => __( 'The easiest way to create carousel slider', 'carousel-slider' ),
			'labels'              => $labels,
			'supports'            => [ 'title' ],
			'hierarchical'        => false,
			'public'              => false,
			'show_ui'             => true,
			'show_in_menu'        => true,
			'show_in_nav_menus'   => true,
			'show_in_admin_bar'   => false,
			'menu_position'       => 5.55525,
			'menu_icon'           => 'dashicons-slides',
			'can_export'          => true,
			'has_archive'         => false,
			'exclude_from_search' => true,
			'publicly_queryable'  => true,
			'rewrite'             => false,
			'capability_type'     => 'page',
		];

		register_post_type( CAROUSEL_SLIDER_POST_TYPE, $args );
	}

	/**
	 * Run on plugin activation
	 *
	 * @return void
	 */
	public function activation_includes() {
		flush_rewrite_rules();
	}

	/**
	 * Run on plugin deactivation
	 *
	 * @return void
	 */
	public function deactivation_includes() {
		flush_rewrite_rules();
	}

	/**
	 * What type of request is this?
	 *
	 * @param  string  $type  admin, ajax, rest, cron or frontend.
	 *
	 * @return bool
	 */
	private function is_request( string $type ): bool {
		return Helper::is_request( $type );
	}

	/**
	 * Declaring extension compatibility
	 * - High-performance order storage
	 */
	public function declaring_extension_compatibility() {
		if ( class_exists( FeaturesUtil::class ) ) {
			FeaturesUtil::declare_compatibility( 'custom_order_tables', CAROUSEL_SLIDER_FILE, true );
		}
	}
}
assets/js/admin-feedback.js000064400000002117151727276560011655 0ustar00(()=>{let e=document.querySelector("#the-list"),t=e?.querySelector('[data-slug="carousel-slider"] span.deactivate a'),a=document.querySelector("#carousel-slider-deactivate-feedback-dialog-wrapper"),r=a?.querySelector(".button--skip-feedback"),d=a?.querySelector(".button--submit-feedback"),i=a?.querySelector("form"),l=i.querySelectorAll("input[type=radio]");r.href=t?.getAttribute("href");r.addEventListener("click",(()=>{a.removeAttribute("open")})),d.addEventListener("click",(e=>{e.preventDefault(),d.classList.add("is-loading"),((e=null)=>new Promise((t=>{let a=new XMLHttpRequest;a.open("POST",window.ajaxurl),a.addEventListener("readystatechange",(()=>{a.readyState===XMLHttpRequest.DONE&&200===a.status&&t(!0)})),a.send(e)})))(new FormData(i)).then((()=>{r.click()})).finally((()=>{d.classList.add("is-loading")}))})),t.addEventListener("click",(e=>{e.preventDefault(),a&&a.setAttribute("open","")})),a.addEventListener("close",(()=>{a.removeAttribute("open")})),l.forEach((e=>{e.addEventListener("change",(e=>{e.target.value&&d.hasAttribute("disabled")&&d.removeAttribute("disabled")}))}))})();assets/js/admin.js000064400000401140151727276560010132 0ustar00/*! For license information please see admin.js.LICENSE.txt */
(()=>{var e={113:(e,t,n)=>{"use strict";n.d(t,{G:()=>i,a:()=>o});const o=(e,t={},n=[])=>{let o=document.createElement(e);return Object.keys(t).length&&Object.entries(t).forEach((([e,t])=>{o.setAttribute(e,t)})),n.length&&o.append(...n),o},i=()=>"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}))},271:()=>{!function(e,t){var n={version:302};if("wpColorPickerAlpha"in window&&"version"in window.wpColorPickerAlpha){var o=parseInt(window.wpColorPickerAlpha.version,10);if(!isNaN(o)&&o>=n.version)return}if(!Color.fn.hasOwnProperty("to_s")){Color.fn.to_s=function(e){"hex"===(e=e||"hex")&&this._alpha<1&&(e="rgba");var t="";return"hex"===e?t=this.toString():this.error||(t=this.toCSS(e).replace(/\(\s+/,"(").replace(/\s+\)/,")")),t},window.wpColorPickerAlpha=n;var i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAAHnlligAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHJJREFUeNpi+P///4EDBxiAGMgCCCAGFB5AADGCRBgYDh48CCRZIJS9vT2QBAggFBkmBiSAogxFBiCAoHogAKIKAlBUYTELAiAmEtABEECk20G6BOmuIl0CIMBQ/IEMkO0myiSSraaaBhZcbkUOs0HuBwDplz5uFJ3Z4gAAAABJRU5ErkJggg==";e.widget("a8c.iris",e.a8c.iris,{alphaOptions:{alphaEnabled:!1},_getColor:function(e){return e===t&&(e=this._color),this.alphaOptions.alphaEnabled?(e=e.to_s(this.alphaOptions.alphaColorType),this.alphaOptions.alphaColorWithSpace||(e=e.replace(/\s+/g,"")),e):e.toString()},_create:function(){try{this.alphaOptions=this.element.wpColorPicker("instance").alphaOptions}catch(e){}e.extend({},this.alphaOptions,{alphaEnabled:!1,alphaCustomWidth:130,alphaReset:!1,alphaColorType:"hex",alphaColorWithSpace:!1}),this._super()},_addInputListeners:function(e){var t=this,n=function(n){var o=e.val(),i=new Color(o),r=(o=o.replace(/^(#|(rgb|hsl)a?)/,""),t.alphaOptions.alphaColorType);e.removeClass("iris-error"),i.error?""!==o&&e.addClass("iris-error"):"hex"===r&&"keyup"===n.type&&o.match(/^[0-9a-fA-F]{3}$/)||i.toIEOctoHex()!==t._color.toIEOctoHex()&&t._setOption("color",t._getColor(i))};e.on("change",n).on("keyup",t._debounce(n,100)),t.options.hide&&e.one("focus",(function(){t.show()}))},_initControls:function(){if(this._super(),this.alphaOptions.alphaEnabled){var t=this,n=t.controls.strip.clone(!1,!1),o=n.find(".iris-slider-offset"),i={stripAlpha:n,stripAlphaSlider:o};n.addClass("iris-strip-alpha"),o.addClass("iris-slider-offset-alpha"),n.appendTo(t.picker.find(".iris-picker-inner")),e.each(i,(function(e,n){t.controls[e]=n})),t.controls.stripAlphaSlider.slider({orientation:"vertical",min:0,max:100,step:1,value:parseInt(100*t._color._alpha),slide:function(e,n){t.active="strip",t._color._alpha=parseFloat(n.value/100),t._change.apply(t,arguments)}})}},_dimensions:function(e){if(this._super(e),this.alphaOptions.alphaEnabled){var t,n,o,i,r,s=this,a=s.options,l=s.controls.square,c=s.picker.find(".iris-strip");for(t=Math.round(s.picker.outerWidth(!0)-(a.border?22:0)),n=Math.round(l.outerWidth()),o=Math.round((t-n)/2),i=Math.round(o/2),r=Math.round(n+2*o+2*i);r>t;)o=Math.round(o-2),i=Math.round(i-1),r=Math.round(n+2*o+2*i);l.css("margin","0"),c.width(o).css("margin-left",i+"px")}},_change:function(){var t=this,n=t.active;if(t._super(),t.alphaOptions.alphaEnabled){var o=t.controls,r=parseInt(100*t._color._alpha),s=t._color.toRgb(),a=["rgb("+s.r+","+s.g+","+s.b+") 0%","rgba("+s.r+","+s.g+","+s.b+", 0) 100%"];t.picker.closest(".wp-picker-container").find(".wp-color-result");t.options.color=t._getColor(),o.stripAlpha.css({background:"linear-gradient(to bottom, "+a.join(", ")+"), url("+i+")"}),n&&o.stripAlphaSlider.slider("value",r),t._color.error||t.element.removeClass("iris-error").val(t.options.color),t.picker.find(".iris-palette-container").on("click.palette",".iris-palette",(function(){var n=e(this).data("color");t.alphaOptions.alphaReset&&(t._color._alpha=1,n=t._getColor()),t._setOption("color",n)}))}},_paintDimension:function(e,t){var n=this,o=!1;n.alphaOptions.alphaEnabled&&"strip"===t&&(o=n._color,n._color=new Color(o.toString()),n.hue=n._color.h()),n._super(e,t),o&&(n._color=o)},_setOption:function(e,t){var n=this;if("color"!==e||!n.alphaOptions.alphaEnabled)return n._super(e,t);t=""+t,newColor=new Color(t).setHSpace(n.options.mode),newColor.error||n._getColor(newColor)===n._getColor()||(n._color=newColor,n.options.color=n._getColor(),n.active="external",n._change())},color:function(e){return!0===e?this._color.clone():e===t?this._getColor():void this.option("color",e)}}),e.widget("wp.wpColorPicker",e.wp.wpColorPicker,{alphaOptions:{alphaEnabled:!1},_getAlphaOptions:function(){var t=this.element,n=t.data("type")||this.options.type,o=t.data("defaultColor")||t.val(),i={alphaEnabled:t.data("alphaEnabled")||!1,alphaCustomWidth:130,alphaReset:!1,alphaColorType:"rgb",alphaColorWithSpace:!1};return i.alphaEnabled&&(i.alphaEnabled=t.is("input")&&"full"===n),i.alphaEnabled?(i.alphaColorWithSpace=o&&o.match(/\s/),e.each(i,(function(e,n){var r=t.data(e)||n;switch(e){case"alphaCustomWidth":r=r?parseInt(r,10):0,r=isNaN(r)?n:r;break;case"alphaColorType":r.match(/^(hex|(rgb|hsl)a?)$/)||(r=o&&o.match(/^#/)?"hex":o&&o.match(/^hsla?/)?"hsl":n);break;default:r=!!r}i[e]=r})),i):i},_create:function(){e.support.iris&&(this.alphaOptions=this._getAlphaOptions(),this._super())},_addListeners:function(){if(!this.alphaOptions.alphaEnabled)return this._super();var t=this,n=t.element,o=t.toggler.is("a");this.alphaOptions.defaultWidth=n.width(),this.alphaOptions.alphaCustomWidth&&n.width(parseInt(this.alphaOptions.defaultWidth+this.alphaOptions.alphaCustomWidth,10)),t.toggler.css({position:"relative","background-image":"url("+i+")"}),o?t.toggler.html('<span class="color-alpha" />'):t.toggler.append('<span class="color-alpha" />'),t.colorAlpha=t.toggler.find("span.color-alpha").css({width:"30px",height:"100%",position:"absolute",top:0,"background-color":n.val()}),"ltr"===t.colorAlpha.css("direction")?t.colorAlpha.css({"border-bottom-left-radius":"2px","border-top-left-radius":"2px",left:0}):t.colorAlpha.css({"border-bottom-right-radius":"2px","border-top-right-radius":"2px",right:0}),n.iris({change:function(e,n){t.colorAlpha.css({"background-color":n.color.to_s(t.alphaOptions.alphaColorType)}),"function"==typeof t.options.change&&t.options.change.call(this,e,n)}}),t.wrap.on("click.wpcolorpicker",(function(e){e.stopPropagation()})),t.toggler.on("click",(function(){t.toggler.hasClass("wp-picker-open")?t.close():t.open()})),n.on("change",(function(i){var r=e(this).val();(n.hasClass("iris-error")||""===r||r.match(/^(#|(rgb|hsl)a?)$/))&&(o&&t.toggler.removeAttr("style"),t.colorAlpha.css("background-color",""),"function"==typeof t.options.clear&&t.options.clear.call(this,i))})),t.button.on("click",(function(i){e(this).hasClass("wp-picker-default")?n.val(t.options.defaultColor).change():e(this).hasClass("wp-picker-clear")&&(n.val(""),o&&t.toggler.removeAttr("style"),t.colorAlpha.css("background-color",""),"function"==typeof t.options.clear&&t.options.clear.call(this,i),n.trigger("change"))}))}})}}(jQuery)},294:(e,t,n)=>{"use strict";n(926);var o=n(113);class i extends HTMLElement{el(e,t={},n=[]){return(0,o.a)(e,t,n)}triggerCustomEvent(e){this.dispatchEvent(new CustomEvent(e))}}const r=i;class s extends r{constructor(){super(),this.attachShadow({mode:"open"});const e=document.createElement("style");e.textContent=s.getStyle(),this.shadowRoot.append(e,...this.getWrapperTemplate())}attributeChangedCallback(e,t,n){const o=this.shadowRoot.querySelector(".shapla-modal");if("open"===e&&this.hasAttribute("open")?o.classList.add("is-active"):o.classList.remove("is-active"),"type"===e){const e=this.shadowRoot.querySelector(".shapla-modal-content");"box"===n&&(e.classList.contains("shapla-modal-box")||e.classList.add("shapla-modal-box"))}}static get observedAttributes(){return["open","type"]}connectedCallback(){const e=this.getAttribute("type");if("card"===e){this.renderCardTemplate();const e=this.shadowRoot.querySelector(".shapla-modal-card__footer");e.querySelector("slot").assignedNodes().length<1&&e.classList.add("no-content")}"confirm"===e&&this.updateConfirmDom();const t=this.shadowRoot.querySelector(".shapla-modal-close.is-fixed"),n=this.shadowRoot.querySelector(".shapla-modal-content");"confirm"===e?(t.remove(),n.classList.add("shapla-modal-confirm"),n.innerHTML="",n.append(...this.getConfirmTemplate())):"box"===e&&n.classList.add("shapla-modal-box");const o=this.shadowRoot.querySelector(".shapla-modal-background"),i=this.getAttribute("backdrop-theme");-1!==["dark","light"].indexOf(i)&&o.classList.add(`is-${i}`),this.updateContentSize(),this.closeOnEscape(),this.closeOnBackdropClick(),this.closeOnCrossClick()}renderCardTemplate(){const e=this.shadowRoot.querySelector(".shapla-modal-close.is-fixed"),t=this.shadowRoot.querySelector(".shapla-modal-content");e.remove(),t.classList.add("shapla-modal-card"),t.innerHTML="",t.append(...this.getCartTemplate());const n=this.getAttribute("heading");n&&(this.shadowRoot.querySelector(".shapla-modal-card__title").innerHTML=n)}updateContentSize(){const e=this.getAttribute("content-size");-1!==["small","medium","large","full","custom"].indexOf(e)&&this.shadowRoot.querySelector(".shapla-modal-content").classList.add(`is-${e}`)}updateConfirmDom(){const e=this.getAttribute("icon")??"primary",t=this.getAttribute("heading"),n=this.getAttribute("message")??"Are you sure?",o=this.getAttribute("confirm-button")??"Ok",i=this.getAttribute("cancel-button")??"Cancel",r=this.shadowRoot.querySelector(".button--confirm"),s=this.shadowRoot.querySelector(".button--cancel");o&&(r.innerHTML=o),i&&(s.innerHTML=i);const a=this.shadowRoot.querySelector(".shapla-modal-confirm");-1!==["primary","success","error"].indexOf(e)&&a.querySelector(".shapla-modal-confirm__icon")?.classList.add(`is-${e}`),this.hasAttribute("content-size")||(this.setAttribute("content-size","small"),this.updateContentSize()),this.hasAttribute("disabled-backdrop-click")||this.setAttribute("disabled-backdrop-click",""),t.length&&(a.querySelector(".shapla-modal-confirm__title").innerHTML=t),n.length&&(a.querySelector(".shapla-modal-confirm__message").innerHTML=n),this.closeOnCrossClick()}closeOnCrossClick(){(this.shadowRoot.querySelectorAll(".shapla-modal-close, .button--cancel")||[]).forEach((e=>{e.addEventListener("click",(()=>this.triggerCloseEvent()))}))}closeOnBackdropClick(){const e=this.shadowRoot.querySelector(".shapla-modal-background");this.hasAttribute("disabled-backdrop-click")||"confirm"!==this.getAttribute("type")&&e.addEventListener("click",(()=>this.triggerCloseEvent()))}closeOnEscape(){document.addEventListener("keydown",(e=>{27===(e||window.event).keyCode&&this.hasAttribute("open")&&this.triggerCloseEvent()}))}triggerCloseEvent(){this.triggerCustomEvent("close")}getWrapperTemplate(){return[this.el("div",{class:"shapla-modal"},[this.el("div",{class:"shapla-modal-background"}),this.el("shapla-cross",{class:"shapla-modal-close is-fixed",size:"large"}),this.el("div",{class:"shapla-modal-content"},[this.el("slot")])])]}getCartTemplate(){return[this.el("header",{class:"shapla-modal-card__header"},[this.el("div",{class:"shapla-modal-card__title"},[this.el("slot",{name:"heading"})]),this.el("shapla-cross",{class:"shapla-modal-close",size:"medium"})]),this.el("section",{class:"shapla-modal-card__body"},[this.el("slot")]),this.el("footer",{class:"shapla-modal-card__footer is-pulled-right"},[this.el("slot",{name:"footer"})])]}getConfirmTemplate(){return[this.el("div",{class:"shapla-modal-confirm__content"},[this.el("div",{class:"shapla-modal-confirm__icon"},[this.el("div",{class:"shapla-modal-confirm__icon-content"},["!"])]),this.el("h3",{class:"shapla-modal-confirm__title"}),this.el("div",{class:"shapla-modal-confirm__message"})]),this.el("div",{class:"shapla-modal-confirm__actions"},[this.el("slot",{name:"actions"},[this.el("button",{class:"shapla-button button--cancel"}),this.el("button",{class:"shapla-button is-primary button--confirm"})])])]}static getStyle(){return".shapla-modal,.shapla-modal-background{bottom:0;left:0;position:absolute;right:0;top:0}\n    .shapla-modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;\n    position:fixed;z-index:var(--modal-z-index,100000)}\n    .shapla-modal.is-active{display:flex}\n    .shapla-modal-background{background-color:var(--modal-backdrop-color,rgba(0,0,0,.5))}\n    .shapla-modal-background.is-light{--modal-backdrop-color:var(--modal-backdrop-color-light,hsla(0,0%,100%,.5))}\n    .shapla-modal .shapla-delete-icon.is-fixed,.shapla-modal .shapla-modal-close.is-fixed{\n    position:fixed;right:var(--modal-close-right,1.25rem);top:var(--modal-close-top,1.25rem)}\n    .shapla-modal-content{margin:0 var(--modal-content-margin,20px);\n    max-height:calc(100vh - var(--modal-content-spacing, 160px));overflow:auto;position:relative;\n    width:var(--modal-content-width,calc(100% - var(--modal-content-margin, 20px)*2))}\n    .shapla-modal-content.is-small{--modal-content-width:var(--modal-content-width-small,320px)}\n    .shapla-modal-content.is-full{height:calc(100vh - var(--modal-content-margin, 20px)*2);\n    width:calc(100vw - var(--modal-content-margin, 20px)*2)}\n    @media print,screen and (min-width:768px){\n    .shapla-modal-content{--modal-content-spacing:40px;margin:0 auto}\n    .shapla-modal-content:not(.is-small):not(.is-full):not(.is-large){\n    --modal-content-width:var(--modal-content-width-medium,640px)}}\n    @media screen and (min-width:1024px){\n    .shapla-modal-content.is-large{--modal-content-width:var(--modal-content-width-large,960px)}}\n    .shapla-modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden}\n    .shapla-modal-card__footer,.shapla-modal-card__header{align-items:center;background-color:#fff;display:flex;\n    flex-shrink:0;justify-content:flex-start;padding:1rem;position:relative}\n    .shapla-modal-card__footer>*+*,.shapla-modal-card__header>*+*{margin-left:.5rem}\n    .shapla-modal-card__header{border-bottom:1px solid rgba(0,0,0,.12);border-top-left-radius:4px;\n    border-top-right-radius:4px}\n    .shapla-modal-card__title{flex-grow:1;flex-shrink:0;font-size:1.5rem;font-weight:400;line-height:1;margin:0}\n    .shapla-modal-card__footer{border-bottom-left-radius:4px;border-bottom-right-radius:4px;\n    border-top:1px solid rgba(0,0,0,.12)}\n    .shapla-modal-card__footer.is-pulled-right{justify-content:flex-end}\n    .shapla-modal-card__footer.no-content{border-top:none;padding:2px}\n    .shapla-modal-card__body{background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:1rem}\n    .shapla-modal-box,.shapla-modal-confirm{background-color:#fff;border-radius:4px;\n    box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2);padding:1rem}\n    .shapla-modal-confirm__content{padding:1rem;text-align:center}\n    .shapla-modal-confirm__icon{border:.25em solid var(--shapla-primary,#0d6efd);border-radius:50%;\n    color:var(--shapla-primary,#0d6efd);cursor:default;display:flex;height:5em;justify-content:center;\n    margin:1.25em auto 1.875em;-webkit-user-select:none;user-select:none;width:5em}\n    .shapla-modal-confirm__icon.is-success{border-color:var(--shapla-success,#198754);color:var(--shapla-success,#198754)}\n    .shapla-modal-confirm__icon.is-error{border-color:var(--shapla-error,#dc3545);color:var(--shapla-error,#dc3545)}\n    .shapla-modal-confirm__icon-content{align-items:center;display:flex;font-size:3.75em}\n    .shapla-modal-confirm__title{font-size:1.875em;margin:0 0 .4em;text-align:center}\n    .shapla-modal-confirm__actions{display:flex;justify-content:center;padding:1rem}\n    .shapla-modal-confirm__actions>*+*{margin-left:.5rem}"}}customElements.define("shapla-dialog",s);const a=(e,t,n)=>{t.length>2&&n.length&&e.removeAttribute("disabled")},l=document.querySelectorAll("[href*='post-new.php?post_type=carousels']");if(l){const e={title:"",type:""},t=(0,o.a)("button",{class:"shapla-button is-primary",disabled:""},["Next"]),n=(0,o.a)("button",{class:"shapla-button"},["Cancel"]),i=(0,o.a)("shapla-dialog",{type:"card","content-size":"large",heading:"Add New Carousel"},[(0,o.a)("div",{slot:"footer",class:"cs-flex cs-space-x-1"},[n,t])]);i.addEventListener("close",(()=>{i.removeAttribute("open")})),n.addEventListener("click",(()=>{i.removeAttribute("open")})),document.querySelector("body")?.append(i);const r=(0,o.a)("div",{class:"shapla-columns"},[(0,o.a)("div",{class:"shapla-column is-12-tablet"},[(0,o.a)("input",{type:"text",name:"slider_title",size:"30",value:"",id:"title",spellcheck:"true",autocomplete:"Off",placeholder:"Add Title",class:"widefat cs-py-2"})])]);i.append(r);const s=(0,o.a)("div",{class:"shapla-columns is-multiline"});i.append(s);let c=[];window.CarouselSliderL10n.sliderTypes.forEach((e=>{c.push((e=>{let t=(0,o.a)("span",{class:"option-slider-type__icon"});t.innerHTML=e.icon;let n={type:"radio",name:"slider_type",id:`_slide_type__${e.slug}`,class:"screen-reader-text",value:e.slug};return e.enabled||(n.disabled=""),(0,o.a)("div",{class:"shapla-column is-6-tablet is-4-desktop is-3-fullhd"},[(0,o.a)("input",n),(0,o.a)("label",{class:"option-slider-type",for:`_slide_type__${e.slug}`},[(0,o.a)("span",{class:"option-slider-type__content"},[t,(0,o.a)("span",{class:"option-slider-type__label"},[e.label]),e.pro?(0,o.a)("span",{class:"option-slider-type__pro"},["Pro"]):""])])])})(e))})),s.append(...c),l.forEach((e=>{e.addEventListener("click",(e=>{e.preventDefault(),i.setAttribute("open","")}))})),i.querySelectorAll('input[name="slider_title"]').forEach((n=>{n.addEventListener("input",(n=>{e.title=n.target.value,a(t,e.title,e.type)}))})),i.querySelectorAll('input[name="slider_type"]').forEach((n=>{n.addEventListener("change",(n=>{e.type=n.target.value,a(t,e.title,e.type)}))})),t.addEventListener("click",(n=>{t.hasAttribute("disabled")||(t.classList.add("is-loading"),fetch(window.CarouselSliderL10n.restRoot+"/carousels",{method:"POST",headers:{"Content-Type":"application/json","X-WP-Nonce":window.CarouselSliderL10n.restNonce},body:JSON.stringify(e)}).then((e=>e.json())).then((e=>{if(e.data.edit_link){let t=document.createElement("a");t.href=e.data.edit_link,t.click()}})).catch((e=>{console.error("Error:",e)})).finally((()=>{t.classList.remove("is-loading")})))}))}},639:()=>{function e(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var o=n.call(e,t||"default");if("object"!=typeof o)return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}new class{constructor(){e(this,"_previewContainer",void 0),e(this,"_formPost",void 0),e(this,"_previewMetaBox",void 0),e(this,"_iframeContainer",void 0),e(this,"_btnUpdatePreview",void 0),e(this,"_btnHidePreview",void 0),e(this,"_btnShowPreview",void 0),e(this,"_previewStatus","hidden"),e(this,"_postId",0),this._iframeContainer=document.querySelector("#carousel_slider_preview_iframe_container"),this._previewMetaBox=document.querySelector("#carousel-slider-live-preview"),this._btnUpdatePreview=document.querySelector("#carousel-slider-update-preview"),this._btnShowPreview=document.querySelector("#carousel-slider-show-preview"),this._btnHidePreview=document.querySelector("#carousel-slider-hide-preview"),this._previewContainer=document.querySelector("#carousel_slider_preview_meta_box"),this._formPost=document.body.querySelector("form#post"),this._iframeContainer&&this._btnUpdatePreview&&this._btnHidePreview&&this._formPost&&(this._postId=parseInt(this._btnShowPreview.dataset.id),this._btnShowPreview.addEventListener("click",(()=>this.onClickShowPreviewButton())),this._btnHidePreview.addEventListener("click",(()=>this.onClickHidePreviewButton())),this._btnUpdatePreview.addEventListener("click",(()=>this.onClickUpdatePreviewButton())),this._formPost.addEventListener("change",(()=>this.dispatchRefreshPreviewEvent())),document.body.addEventListener("CarouselSlider.refresh.preview",(()=>this.onRefreshPreview())))}getIframeUrl(){const e=new URL(window.CarouselSliderL10n.homeUrl);return e.searchParams.set("carousel_slider_preview","1"),e.searchParams.set("carousel_slider_iframe","1"),e.searchParams.set("slider_id",this._postId.toString()),e.toString()}getPreviewIframe(){const e=document.createElement("iframe");return e.setAttribute("id","carousel_slider_preview_iframe"),e.setAttribute("frameborder","0"),e.setAttribute("src",this.getIframeUrl()),e}refreshIframe(){const e=this._iframeContainer.offsetHeight;this._iframeContainer.style.height=e+"px",this._iframeContainer.innerHTML="",this._iframeContainer.appendChild(this.getPreviewIframe()),this._iframeContainer.style.height=""}onRefreshPreview(){this._previewStatus="updatable",this._btnHidePreview.classList.add("hidden"),this._btnShowPreview.classList.add("hidden"),this._btnUpdatePreview.classList.remove("hidden"),this._previewMetaBox.style.display="block"}onClickShowPreviewButton(){this._btnShowPreview.classList.add("hidden"),this._btnUpdatePreview.classList.add("hidden"),this._btnHidePreview.classList.remove("hidden"),this._previewMetaBox.style.display="block",this.getPreviewHtml().then((()=>{this._previewStatus="showing"}))}onClickHidePreviewButton(){this._previewStatus="hidden",this._btnHidePreview.classList.add("hidden"),this._btnUpdatePreview.classList.add("hidden"),this._btnShowPreview.classList.remove("hidden"),this._previewMetaBox.style.display="none"}onClickUpdatePreviewButton(){"hidden"!==this._previewStatus&&this.getPreviewHtml().then((()=>{this._previewStatus="showing",this._btnShowPreview.classList.add("hidden"),this._btnUpdatePreview.classList.add("hidden"),this._btnHidePreview.classList.remove("hidden"),this._previewMetaBox.style.display="block"}))}dispatchRefreshPreviewEvent(){document.body.dispatchEvent(new CustomEvent("CarouselSlider.refresh.preview"))}getPreviewHtml(){return new Promise(((e,t)=>{const n=document.body.querySelector("form#post");if(n){const o=new FormData(n);o.set("action","carousel_slider_preview_meta_box");const i=new URL(window.CarouselSliderL10n.ajaxUrl);i.searchParams.set("action","carousel_slider_preview_meta_box"),i.searchParams.set("cs_nonce",window.CarouselSliderL10n.nonce),fetch(i.toString(),{method:"POST",headers:{"X-WP-Nonce":window.CarouselSliderL10n.restNonce},body:o}).then((e=>e.json())).then((t=>{e(t.data),this.refreshIframe()})).catch((e=>{console.error("Error:",e),t(!1)}))}}))}}},669:e=>{"use strict";e.exports=jQuery},776:(e,t,n)=>{var o,i,r;i=[n(669)],void 0===(r="function"==typeof(o=function(e){var t=function(){if(e&&e.fn&&e.fn.select2&&e.fn.select2.amd)var t=e.fn.select2.amd;var n,o,i;return t&&t.requirejs||(t?o=t:t={},function(e){var t,r,s,a,l={},c={},d={},u={},p=Object.prototype.hasOwnProperty,h=[].slice,f=/\.js$/;function m(e,t){return p.call(e,t)}function g(e,t){var n,o,i,r,s,a,l,c,u,p,h,m=t&&t.split("/"),g=d.map,v=g&&g["*"]||{};if(e){for(s=(e=e.split("/")).length-1,d.nodeIdCompat&&f.test(e[s])&&(e[s]=e[s].replace(f,"")),"."===e[0].charAt(0)&&m&&(e=m.slice(0,m.length-1).concat(e)),u=0;u<e.length;u++)if("."===(h=e[u]))e.splice(u,1),u-=1;else if(".."===h){if(0===u||1===u&&".."===e[2]||".."===e[u-1])continue;u>0&&(e.splice(u-1,2),u-=2)}e=e.join("/")}if((m||v)&&g){for(u=(n=e.split("/")).length;u>0;u-=1){if(o=n.slice(0,u).join("/"),m)for(p=m.length;p>0;p-=1)if((i=g[m.slice(0,p).join("/")])&&(i=i[o])){r=i,a=u;break}if(r)break;!l&&v&&v[o]&&(l=v[o],c=u)}!r&&l&&(r=l,a=c),r&&(n.splice(0,a,r),e=n.join("/"))}return e}function v(t,n){return function(){var o=h.call(arguments,0);return"string"!=typeof o[0]&&1===o.length&&o.push(null),r.apply(e,o.concat([t,n]))}}function _(e){return function(t){return g(t,e)}}function y(e){return function(t){l[e]=t}}function b(n){if(m(c,n)){var o=c[n];delete c[n],u[n]=!0,t.apply(e,o)}if(!m(l,n)&&!m(u,n))throw new Error("No "+n);return l[n]}function w(e){var t,n=e?e.indexOf("!"):-1;return n>-1&&(t=e.substring(0,n),e=e.substring(n+1,e.length)),[t,e]}function x(e){return e?w(e):[]}function A(e){return function(){return d&&d.config&&d.config[e]||{}}}s=function(e,t){var n,o=w(e),i=o[0],r=t[1];return e=o[1],i&&(n=b(i=g(i,r))),i?e=n&&n.normalize?n.normalize(e,_(r)):g(e,r):(i=(o=w(e=g(e,r)))[0],e=o[1],i&&(n=b(i))),{f:i?i+"!"+e:e,n:e,pr:i,p:n}},a={require:function(e){return v(e)},exports:function(e){var t=l[e];return void 0!==t?t:l[e]={}},module:function(e){return{id:e,uri:"",exports:l[e],config:A(e)}}},t=function(t,n,o,i){var r,d,p,h,f,g,_,w=[],A=typeof o;if(g=x(i=i||t),"undefined"===A||"function"===A){for(n=!n.length&&o.length?["require","exports","module"]:n,f=0;f<n.length;f+=1)if("require"===(d=(h=s(n[f],g)).f))w[f]=a.require(t);else if("exports"===d)w[f]=a.exports(t),_=!0;else if("module"===d)r=w[f]=a.module(t);else if(m(l,d)||m(c,d)||m(u,d))w[f]=b(d);else{if(!h.p)throw new Error(t+" missing "+d);h.p.load(h.n,v(i,!0),y(d),{}),w[f]=l[d]}p=o?o.apply(l[t],w):void 0,t&&(r&&r.exports!==e&&r.exports!==l[t]?l[t]=r.exports:p===e&&_||(l[t]=p))}else t&&(l[t]=o)},n=o=r=function(n,o,i,l,c){if("string"==typeof n)return a[n]?a[n](o):b(s(n,x(o)).f);if(!n.splice){if((d=n).deps&&r(d.deps,d.callback),!o)return;o.splice?(n=o,o=i,i=null):n=e}return o=o||function(){},"function"==typeof i&&(i=l,l=c),l?t(e,n,o,i):setTimeout((function(){t(e,n,o,i)}),4),r},r.config=function(e){return r(e)},n._defined=l,(i=function(e,t,n){if("string"!=typeof e)throw new Error("See almond README: incorrect module build, no module name");t.splice||(n=t,t=[]),m(l,e)||m(c,e)||(c[e]=[e,t,n])}).amd={jQuery:!0}}(),t.requirejs=n,t.require=o,t.define=i),t.define("almond",(function(){})),t.define("jquery",[],(function(){var t=e||$;return null==t&&console&&console.error&&console.error("Select2: An instance of jQuery or a jQuery-compatible library was not found. Make sure that you are including jQuery before Select2 on your web page."),t})),t.define("select2/utils",["jquery"],(function(e){var t={};function n(e){var t=e.prototype,n=[];for(var o in t)"function"==typeof t[o]&&"constructor"!==o&&n.push(o);return n}t.Extend=function(e,t){var n={}.hasOwnProperty;function o(){this.constructor=e}for(var i in t)n.call(t,i)&&(e[i]=t[i]);return o.prototype=t.prototype,e.prototype=new o,e.__super__=t.prototype,e},t.Decorate=function(e,t){var o=n(t),i=n(e);function r(){var n=Array.prototype.unshift,o=t.prototype.constructor.length,i=e.prototype.constructor;o>0&&(n.call(arguments,e.prototype.constructor),i=t.prototype.constructor),i.apply(this,arguments)}function s(){this.constructor=r}t.displayName=e.displayName,r.prototype=new s;for(var a=0;a<i.length;a++){var l=i[a];r.prototype[l]=e.prototype[l]}for(var c=function(e){var n=function(){};e in r.prototype&&(n=r.prototype[e]);var o=t.prototype[e];return function(){return Array.prototype.unshift.call(arguments,n),o.apply(this,arguments)}},d=0;d<o.length;d++){var u=o[d];r.prototype[u]=c(u)}return r};var o=function(){this.listeners={}};o.prototype.on=function(e,t){this.listeners=this.listeners||{},e in this.listeners?this.listeners[e].push(t):this.listeners[e]=[t]},o.prototype.trigger=function(e){var t=Array.prototype.slice,n=t.call(arguments,1);this.listeners=this.listeners||{},null==n&&(n=[]),0===n.length&&n.push({}),n[0]._type=e,e in this.listeners&&this.invoke(this.listeners[e],t.call(arguments,1)),"*"in this.listeners&&this.invoke(this.listeners["*"],arguments)},o.prototype.invoke=function(e,t){for(var n=0,o=e.length;n<o;n++)e[n].apply(this,t)},t.Observable=o,t.generateChars=function(e){for(var t="",n=0;n<e;n++)t+=Math.floor(36*Math.random()).toString(36);return t},t.bind=function(e,t){return function(){e.apply(t,arguments)}},t._convertData=function(e){for(var t in e){var n=t.split("-"),o=e;if(1!==n.length){for(var i=0;i<n.length;i++){var r=n[i];(r=r.substring(0,1).toLowerCase()+r.substring(1))in o||(o[r]={}),i==n.length-1&&(o[r]=e[t]),o=o[r]}delete e[t]}}return e},t.hasScroll=function(t,n){var o=e(n),i=n.style.overflowX,r=n.style.overflowY;return(i!==r||"hidden"!==r&&"visible"!==r)&&("scroll"===i||"scroll"===r||o.innerHeight()<n.scrollHeight||o.innerWidth()<n.scrollWidth)},t.escapeMarkup=function(e){var t={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,(function(e){return t[e]}))},t.appendMany=function(t,n){if("1.7"===e.fn.jquery.substr(0,3)){var o=e();e.map(n,(function(e){o=o.add(e)})),n=o}t.append(n)},t.__cache={};var i=0;return t.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null==t&&(e.id?(t=e.id,e.setAttribute("data-select2-id",t)):(e.setAttribute("data-select2-id",++i),t=i.toString())),t},t.StoreData=function(e,n,o){var i=t.GetUniqueElementId(e);t.__cache[i]||(t.__cache[i]={}),t.__cache[i][n]=o},t.GetData=function(n,o){var i=t.GetUniqueElementId(n);return o?t.__cache[i]&&null!=t.__cache[i][o]?t.__cache[i][o]:e(n).data(o):t.__cache[i]},t.RemoveData=function(e){var n=t.GetUniqueElementId(e);null!=t.__cache[n]&&delete t.__cache[n],e.removeAttribute("data-select2-id")},t})),t.define("select2/results",["jquery","./utils"],(function(e,t){function n(e,t,o){this.$element=e,this.data=o,this.options=t,n.__super__.constructor.call(this)}return t.Extend(n,t.Observable),n.prototype.render=function(){var t=e('<ul class="select2-results__options" role="listbox"></ul>');return this.options.get("multiple")&&t.attr("aria-multiselectable","true"),this.$results=t,t},n.prototype.clear=function(){this.$results.empty()},n.prototype.displayMessage=function(t){var n=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var o=e('<li role="alert" aria-live="assertive" class="select2-results__option"></li>'),i=this.options.get("translations").get(t.message);o.append(n(i(t.args))),o[0].className+=" select2-results__message",this.$results.append(o)},n.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},n.prototype.append=function(e){this.hideLoading();var t=[];if(null!=e.results&&0!==e.results.length){e.results=this.sort(e.results);for(var n=0;n<e.results.length;n++){var o=e.results[n],i=this.option(o);t.push(i)}this.$results.append(t)}else 0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"})},n.prototype.position=function(e,t){t.find(".select2-results").append(e)},n.prototype.sort=function(e){return this.options.get("sorter")(e)},n.prototype.highlightFirstItem=function(){var e=this.$results.find(".select2-results__option[aria-selected]"),t=e.filter("[aria-selected=true]");t.length>0?t.first().trigger("mouseenter"):e.first().trigger("mouseenter"),this.ensureHighlightVisible()},n.prototype.setClasses=function(){var n=this;this.data.current((function(o){var i=e.map(o,(function(e){return e.id.toString()}));n.$results.find(".select2-results__option[aria-selected]").each((function(){var n=e(this),o=t.GetData(this,"data"),r=""+o.id;null!=o.element&&o.element.selected||null==o.element&&e.inArray(r,i)>-1?n.attr("aria-selected","true"):n.attr("aria-selected","false")}))}))},n.prototype.showLoading=function(e){this.hideLoading();var t={disabled:!0,loading:!0,text:this.options.get("translations").get("searching")(e)},n=this.option(t);n.className+=" loading-results",this.$results.prepend(n)},n.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},n.prototype.option=function(n){var o=document.createElement("li");o.className="select2-results__option";var i={role:"option","aria-selected":"false"},r=window.Element.prototype.matches||window.Element.prototype.msMatchesSelector||window.Element.prototype.webkitMatchesSelector;for(var s in(null!=n.element&&r.call(n.element,":disabled")||null==n.element&&n.disabled)&&(delete i["aria-selected"],i["aria-disabled"]="true"),null==n.id&&delete i["aria-selected"],null!=n._resultId&&(o.id=n._resultId),n.title&&(o.title=n.title),n.children&&(i.role="group",i["aria-label"]=n.text,delete i["aria-selected"]),i){var a=i[s];o.setAttribute(s,a)}if(n.children){var l=e(o),c=document.createElement("strong");c.className="select2-results__group",e(c),this.template(n,c);for(var d=[],u=0;u<n.children.length;u++){var p=n.children[u],h=this.option(p);d.push(h)}var f=e("<ul></ul>",{class:"select2-results__options select2-results__options--nested"});f.append(d),l.append(c),l.append(f)}else this.template(n,o);return t.StoreData(o,"data",n),o},n.prototype.bind=function(n,o){var i=this,r=n.id+"-results";this.$results.attr("id",r),n.on("results:all",(function(e){i.clear(),i.append(e.data),n.isOpen()&&(i.setClasses(),i.highlightFirstItem())})),n.on("results:append",(function(e){i.append(e.data),n.isOpen()&&i.setClasses()})),n.on("query",(function(e){i.hideMessages(),i.showLoading(e)})),n.on("select",(function(){n.isOpen()&&(i.setClasses(),i.options.get("scrollAfterSelect")&&i.highlightFirstItem())})),n.on("unselect",(function(){n.isOpen()&&(i.setClasses(),i.options.get("scrollAfterSelect")&&i.highlightFirstItem())})),n.on("open",(function(){i.$results.attr("aria-expanded","true"),i.$results.attr("aria-hidden","false"),i.setClasses(),i.ensureHighlightVisible()})),n.on("close",(function(){i.$results.attr("aria-expanded","false"),i.$results.attr("aria-hidden","true"),i.$results.removeAttr("aria-activedescendant")})),n.on("results:toggle",(function(){var e=i.getHighlightedResults();0!==e.length&&e.trigger("mouseup")})),n.on("results:select",(function(){var e=i.getHighlightedResults();if(0!==e.length){var n=t.GetData(e[0],"data");"true"==e.attr("aria-selected")?i.trigger("close",{}):i.trigger("select",{data:n})}})),n.on("results:previous",(function(){var e=i.getHighlightedResults(),t=i.$results.find("[aria-selected]"),n=t.index(e);if(!(n<=0)){var o=n-1;0===e.length&&(o=0);var r=t.eq(o);r.trigger("mouseenter");var s=i.$results.offset().top,a=r.offset().top,l=i.$results.scrollTop()+(a-s);0===o?i.$results.scrollTop(0):a-s<0&&i.$results.scrollTop(l)}})),n.on("results:next",(function(){var e=i.getHighlightedResults(),t=i.$results.find("[aria-selected]"),n=t.index(e)+1;if(!(n>=t.length)){var o=t.eq(n);o.trigger("mouseenter");var r=i.$results.offset().top+i.$results.outerHeight(!1),s=o.offset().top+o.outerHeight(!1),a=i.$results.scrollTop()+s-r;0===n?i.$results.scrollTop(0):s>r&&i.$results.scrollTop(a)}})),n.on("results:focus",(function(e){e.element.addClass("select2-results__option--highlighted")})),n.on("results:message",(function(e){i.displayMessage(e)})),e.fn.mousewheel&&this.$results.on("mousewheel",(function(e){var t=i.$results.scrollTop(),n=i.$results.get(0).scrollHeight-t+e.deltaY,o=e.deltaY>0&&t-e.deltaY<=0,r=e.deltaY<0&&n<=i.$results.height();o?(i.$results.scrollTop(0),e.preventDefault(),e.stopPropagation()):r&&(i.$results.scrollTop(i.$results.get(0).scrollHeight-i.$results.height()),e.preventDefault(),e.stopPropagation())})),this.$results.on("mouseup",".select2-results__option[aria-selected]",(function(n){var o=e(this),r=t.GetData(this,"data");"true"!==o.attr("aria-selected")?i.trigger("select",{originalEvent:n,data:r}):i.options.get("multiple")?i.trigger("unselect",{originalEvent:n,data:r}):i.trigger("close",{})})),this.$results.on("mouseenter",".select2-results__option[aria-selected]",(function(n){var o=t.GetData(this,"data");i.getHighlightedResults().removeClass("select2-results__option--highlighted"),i.trigger("results:focus",{data:o,element:e(this)})}))},n.prototype.getHighlightedResults=function(){return this.$results.find(".select2-results__option--highlighted")},n.prototype.destroy=function(){this.$results.remove()},n.prototype.ensureHighlightVisible=function(){var e=this.getHighlightedResults();if(0!==e.length){var t=this.$results.find("[aria-selected]").index(e),n=this.$results.offset().top,o=e.offset().top,i=this.$results.scrollTop()+(o-n),r=o-n;i-=2*e.outerHeight(!1),t<=2?this.$results.scrollTop(0):(r>this.$results.outerHeight()||r<0)&&this.$results.scrollTop(i)}},n.prototype.template=function(t,n){var o=this.options.get("templateResult"),i=this.options.get("escapeMarkup"),r=o(t,n);null==r?n.style.display="none":"string"==typeof r?n.innerHTML=i(r):e(n).append(r)},n})),t.define("select2/keys",[],(function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}})),t.define("select2/selection/base",["jquery","../utils","../keys"],(function(e,t,n){function o(e,t){this.$element=e,this.options=t,o.__super__.constructor.call(this)}return t.Extend(o,t.Observable),o.prototype.render=function(){var n=e('<span class="select2-selection" role="combobox"  aria-haspopup="true" aria-expanded="false"></span>');return this._tabindex=0,null!=t.GetData(this.$element[0],"old-tabindex")?this._tabindex=t.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),n.attr("title",this.$element.attr("title")),n.attr("tabindex",this._tabindex),n.attr("aria-disabled","false"),this.$selection=n,n},o.prototype.bind=function(e,t){var o=this,i=e.id+"-results";this.container=e,this.$selection.on("focus",(function(e){o.trigger("focus",e)})),this.$selection.on("blur",(function(e){o._handleBlur(e)})),this.$selection.on("keydown",(function(e){o.trigger("keypress",e),e.which===n.SPACE&&e.preventDefault()})),e.on("results:focus",(function(e){o.$selection.attr("aria-activedescendant",e.data._resultId)})),e.on("selection:update",(function(e){o.update(e.data)})),e.on("open",(function(){o.$selection.attr("aria-expanded","true"),o.$selection.attr("aria-owns",i),o._attachCloseHandler(e)})),e.on("close",(function(){o.$selection.attr("aria-expanded","false"),o.$selection.removeAttr("aria-activedescendant"),o.$selection.removeAttr("aria-owns"),o.$selection.trigger("focus"),o._detachCloseHandler(e)})),e.on("enable",(function(){o.$selection.attr("tabindex",o._tabindex),o.$selection.attr("aria-disabled","false")})),e.on("disable",(function(){o.$selection.attr("tabindex","-1"),o.$selection.attr("aria-disabled","true")}))},o.prototype._handleBlur=function(t){var n=this;window.setTimeout((function(){document.activeElement==n.$selection[0]||e.contains(n.$selection[0],document.activeElement)||n.trigger("blur",t)}),1)},o.prototype._attachCloseHandler=function(n){e(document.body).on("mousedown.select2."+n.id,(function(n){var o=e(n.target).closest(".select2");e(".select2.select2-container--open").each((function(){this!=o[0]&&t.GetData(this,"element").select2("close")}))}))},o.prototype._detachCloseHandler=function(t){e(document.body).off("mousedown.select2."+t.id)},o.prototype.position=function(e,t){t.find(".selection").append(e)},o.prototype.destroy=function(){this._detachCloseHandler(this.container)},o.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},o.prototype.isEnabled=function(){return!this.isDisabled()},o.prototype.isDisabled=function(){return this.options.get("disabled")},o})),t.define("select2/selection/single",["jquery","./base","../utils","../keys"],(function(e,t,n,o){function i(){i.__super__.constructor.apply(this,arguments)}return n.Extend(i,t),i.prototype.render=function(){var e=i.__super__.render.call(this);return e.addClass("select2-selection--single"),e.html('<span class="select2-selection__rendered"></span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span>'),e},i.prototype.bind=function(e,t){var n=this;i.__super__.bind.apply(this,arguments);var o=e.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",o).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",o),this.$selection.on("mousedown",(function(e){1===e.which&&n.trigger("toggle",{originalEvent:e})})),this.$selection.on("focus",(function(e){})),this.$selection.on("blur",(function(e){})),e.on("focus",(function(t){e.isOpen()||n.$selection.trigger("focus")}))},i.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},i.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},i.prototype.selectionContainer=function(){return e("<span></span>")},i.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(".select2-selection__rendered"),o=this.display(t,n);n.empty().append(o);var i=t.title||t.text;i?n.attr("title",i):n.removeAttr("title")}else this.clear()},i})),t.define("select2/selection/multiple",["jquery","./base","../utils"],(function(e,t,n){function o(e,t){o.__super__.constructor.apply(this,arguments)}return n.Extend(o,t),o.prototype.render=function(){var e=o.__super__.render.call(this);return e.addClass("select2-selection--multiple"),e.html('<ul class="select2-selection__rendered"></ul>'),e},o.prototype.bind=function(t,i){var r=this;o.__super__.bind.apply(this,arguments),this.$selection.on("click",(function(e){r.trigger("toggle",{originalEvent:e})})),this.$selection.on("click",".select2-selection__choice__remove",(function(t){if(!r.isDisabled()){var o=e(this).parent(),i=n.GetData(o[0],"data");r.trigger("unselect",{originalEvent:t,data:i})}}))},o.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},o.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},o.prototype.selectionContainer=function(){return e('<li class="select2-selection__choice"><span class="select2-selection__choice__remove" role="presentation">&times;</span></li>')},o.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],o=0;o<e.length;o++){var i=e[o],r=this.selectionContainer(),s=this.display(i,r);r.append(s);var a=i.title||i.text;a&&r.attr("title",a),n.StoreData(r[0],"data",i),t.push(r)}var l=this.$selection.find(".select2-selection__rendered");n.appendMany(l,t)}},o})),t.define("select2/selection/placeholder",["../utils"],(function(e){function t(e,t,n){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n)}return t.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},t.prototype.createPlaceholder=function(e,t){var n=this.selectionContainer();return n.html(this.display(t)),n.addClass("select2-selection__placeholder").removeClass("select2-selection__choice"),n},t.prototype.update=function(e,t){var n=1==t.length&&t[0].id!=this.placeholder.id;if(t.length>1||n)return e.call(this,t);this.clear();var o=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(o)},t})),t.define("select2/selection/allowClear",["jquery","../keys","../utils"],(function(e,t,n){function o(){}return o.prototype.bind=function(e,t,n){var o=this;e.call(this,t,n),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",(function(e){o._handleClear(e)})),t.on("keypress",(function(e){o._handleKeyboardClear(e,t)}))},o.prototype._handleClear=function(e,t){if(!this.isDisabled()){var o=this.$selection.find(".select2-selection__clear");if(0!==o.length){t.stopPropagation();var i=n.GetData(o[0],"data"),r=this.$element.val();this.$element.val(this.placeholder.id);var s={data:i};if(this.trigger("clear",s),s.prevented)this.$element.val(r);else{for(var a=0;a<i.length;a++)if(s={data:i[a]},this.trigger("unselect",s),s.prevented)return void this.$element.val(r);this.$element.trigger("input").trigger("change"),this.trigger("toggle",{})}}}},o.prototype._handleKeyboardClear=function(e,n,o){o.isOpen()||n.which!=t.DELETE&&n.which!=t.BACKSPACE||this._handleClear(n)},o.prototype.update=function(t,o){if(t.call(this,o),!(this.$selection.find(".select2-selection__placeholder").length>0||0===o.length)){var i=this.options.get("translations").get("removeAllItems"),r=e('<span class="select2-selection__clear" title="'+i()+'">&times;</span>');n.StoreData(r[0],"data",o),this.$selection.find(".select2-selection__rendered").prepend(r)}},o})),t.define("select2/selection/search",["jquery","../utils","../keys"],(function(e,t,n){function o(e,t,n){e.call(this,t,n)}return o.prototype.render=function(t){var n=e('<li class="select2-search select2-search--inline"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="searchbox" aria-autocomplete="list" /></li>');this.$searchContainer=n,this.$search=n.find("input");var o=t.call(this);return this._transferTabIndex(),o},o.prototype.bind=function(e,o,i){var r=this,s=o.id+"-results";e.call(this,o,i),o.on("open",(function(){r.$search.attr("aria-controls",s),r.$search.trigger("focus")})),o.on("close",(function(){r.$search.val(""),r.$search.removeAttr("aria-controls"),r.$search.removeAttr("aria-activedescendant"),r.$search.trigger("focus")})),o.on("enable",(function(){r.$search.prop("disabled",!1),r._transferTabIndex()})),o.on("disable",(function(){r.$search.prop("disabled",!0)})),o.on("focus",(function(e){r.$search.trigger("focus")})),o.on("results:focus",(function(e){e.data._resultId?r.$search.attr("aria-activedescendant",e.data._resultId):r.$search.removeAttr("aria-activedescendant")})),this.$selection.on("focusin",".select2-search--inline",(function(e){r.trigger("focus",e)})),this.$selection.on("focusout",".select2-search--inline",(function(e){r._handleBlur(e)})),this.$selection.on("keydown",".select2-search--inline",(function(e){if(e.stopPropagation(),r.trigger("keypress",e),r._keyUpPrevented=e.isDefaultPrevented(),e.which===n.BACKSPACE&&""===r.$search.val()){var o=r.$searchContainer.prev(".select2-selection__choice");if(o.length>0){var i=t.GetData(o[0],"data");r.searchRemoveChoice(i),e.preventDefault()}}})),this.$selection.on("click",".select2-search--inline",(function(e){r.$search.val()&&e.stopPropagation()}));var a=document.documentMode,l=a&&a<=11;this.$selection.on("input.searchcheck",".select2-search--inline",(function(e){l?r.$selection.off("input.search input.searchcheck"):r.$selection.off("keyup.search")})),this.$selection.on("keyup.search input.search",".select2-search--inline",(function(e){if(l&&"input"===e.type)r.$selection.off("input.search input.searchcheck");else{var t=e.which;t!=n.SHIFT&&t!=n.CTRL&&t!=n.ALT&&t!=n.TAB&&r.handleSearch(e)}}))},o.prototype._transferTabIndex=function(e){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},o.prototype.createPlaceholder=function(e,t){this.$search.attr("placeholder",t.text)},o.prototype.update=function(e,t){var n=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),e.call(this,t),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),n&&this.$search.trigger("focus")},o.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var e=this.$search.val();this.trigger("query",{term:e})}this._keyUpPrevented=!1},o.prototype.searchRemoveChoice=function(e,t){this.trigger("unselect",{data:t}),this.$search.val(t.text),this.handleSearch()},o.prototype.resizeSearch=function(){this.$search.css("width","25px");var e="";e=""!==this.$search.attr("placeholder")?this.$selection.find(".select2-selection__rendered").width():.75*(this.$search.val().length+1)+"em",this.$search.css("width",e)},o})),t.define("select2/selection/eventRelay",["jquery"],(function(e){function t(){}return t.prototype.bind=function(t,n,o){var i=this,r=["open","opening","close","closing","select","selecting","unselect","unselecting","clear","clearing"],s=["opening","closing","selecting","unselecting","clearing"];t.call(this,n,o),n.on("*",(function(t,n){if(-1!==e.inArray(t,r)){n=n||{};var o=e.Event("select2:"+t,{params:n});i.$element.trigger(o),-1!==e.inArray(t,s)&&(n.prevented=o.isDefaultPrevented())}}))},t})),t.define("select2/translation",["jquery","require"],(function(e,t){function n(e){this.dict=e||{}}return n.prototype.all=function(){return this.dict},n.prototype.get=function(e){return this.dict[e]},n.prototype.extend=function(t){this.dict=e.extend({},t.all(),this.dict)},n._cache={},n.loadPath=function(e){if(!(e in n._cache)){var o=t(e);n._cache[e]=o}return new n(n._cache[e])},n})),t.define("select2/diacritics",[],(function(){return{"Ⓐ":"A",A:"A",À:"A",Á:"A",Â:"A",Ầ:"A",Ấ:"A",Ẫ:"A",Ẩ:"A",Ã:"A",Ā:"A",Ă:"A",Ằ:"A",Ắ:"A",Ẵ:"A",Ẳ:"A",Ȧ:"A",Ǡ:"A",Ä:"A",Ǟ:"A",Ả:"A",Å:"A",Ǻ:"A",Ǎ:"A",Ȁ:"A",Ȃ:"A",Ạ:"A",Ậ:"A",Ặ:"A",Ḁ:"A",Ą:"A",Ⱥ:"A",Ɐ:"A",Ꜳ:"AA",Æ:"AE",Ǽ:"AE",Ǣ:"AE",Ꜵ:"AO",Ꜷ:"AU",Ꜹ:"AV",Ꜻ:"AV",Ꜽ:"AY","Ⓑ":"B",B:"B",Ḃ:"B",Ḅ:"B",Ḇ:"B",Ƀ:"B",Ƃ:"B",Ɓ:"B","Ⓒ":"C",C:"C",Ć:"C",Ĉ:"C",Ċ:"C",Č:"C",Ç:"C",Ḉ:"C",Ƈ:"C",Ȼ:"C",Ꜿ:"C","Ⓓ":"D",D:"D",Ḋ:"D",Ď:"D",Ḍ:"D",Ḑ:"D",Ḓ:"D",Ḏ:"D",Đ:"D",Ƌ:"D",Ɗ:"D",Ɖ:"D",Ꝺ:"D",DZ:"DZ",DŽ:"DZ",Dz:"Dz",Dž:"Dz","Ⓔ":"E",E:"E",È:"E",É:"E",Ê:"E",Ề:"E",Ế:"E",Ễ:"E",Ể:"E",Ẽ:"E",Ē:"E",Ḕ:"E",Ḗ:"E",Ĕ:"E",Ė:"E",Ë:"E",Ẻ:"E",Ě:"E",Ȅ:"E",Ȇ:"E",Ẹ:"E",Ệ:"E",Ȩ:"E",Ḝ:"E",Ę:"E",Ḙ:"E",Ḛ:"E",Ɛ:"E",Ǝ:"E","Ⓕ":"F",F:"F",Ḟ:"F",Ƒ:"F",Ꝼ:"F","Ⓖ":"G",G:"G",Ǵ:"G",Ĝ:"G",Ḡ:"G",Ğ:"G",Ġ:"G",Ǧ:"G",Ģ:"G",Ǥ:"G",Ɠ:"G",Ꞡ:"G",Ᵹ:"G",Ꝿ:"G","Ⓗ":"H",H:"H",Ĥ:"H",Ḣ:"H",Ḧ:"H",Ȟ:"H",Ḥ:"H",Ḩ:"H",Ḫ:"H",Ħ:"H",Ⱨ:"H",Ⱶ:"H",Ɥ:"H","Ⓘ":"I",I:"I",Ì:"I",Í:"I",Î:"I",Ĩ:"I",Ī:"I",Ĭ:"I",İ:"I",Ï:"I",Ḯ:"I",Ỉ:"I",Ǐ:"I",Ȉ:"I",Ȋ:"I",Ị:"I",Į:"I",Ḭ:"I",Ɨ:"I","Ⓙ":"J",J:"J",Ĵ:"J",Ɉ:"J","Ⓚ":"K",K:"K",Ḱ:"K",Ǩ:"K",Ḳ:"K",Ķ:"K",Ḵ:"K",Ƙ:"K",Ⱪ:"K",Ꝁ:"K",Ꝃ:"K",Ꝅ:"K",Ꞣ:"K","Ⓛ":"L",L:"L",Ŀ:"L",Ĺ:"L",Ľ:"L",Ḷ:"L",Ḹ:"L",Ļ:"L",Ḽ:"L",Ḻ:"L",Ł:"L",Ƚ:"L",Ɫ:"L",Ⱡ:"L",Ꝉ:"L",Ꝇ:"L",Ꞁ:"L",LJ:"LJ",Lj:"Lj","Ⓜ":"M",M:"M",Ḿ:"M",Ṁ:"M",Ṃ:"M",Ɱ:"M",Ɯ:"M","Ⓝ":"N",N:"N",Ǹ:"N",Ń:"N",Ñ:"N",Ṅ:"N",Ň:"N",Ṇ:"N",Ņ:"N",Ṋ:"N",Ṉ:"N",Ƞ:"N",Ɲ:"N",Ꞑ:"N",Ꞥ:"N",NJ:"NJ",Nj:"Nj","Ⓞ":"O",O:"O",Ò:"O",Ó:"O",Ô:"O",Ồ:"O",Ố:"O",Ỗ:"O",Ổ:"O",Õ:"O",Ṍ:"O",Ȭ:"O",Ṏ:"O",Ō:"O",Ṑ:"O",Ṓ:"O",Ŏ:"O",Ȯ:"O",Ȱ:"O",Ö:"O",Ȫ:"O",Ỏ:"O",Ő:"O",Ǒ:"O",Ȍ:"O",Ȏ:"O",Ơ:"O",Ờ:"O",Ớ:"O",Ỡ:"O",Ở:"O",Ợ:"O",Ọ:"O",Ộ:"O",Ǫ:"O",Ǭ:"O",Ø:"O",Ǿ:"O",Ɔ:"O",Ɵ:"O",Ꝋ:"O",Ꝍ:"O",Œ:"OE",Ƣ:"OI",Ꝏ:"OO",Ȣ:"OU","Ⓟ":"P",P:"P",Ṕ:"P",Ṗ:"P",Ƥ:"P",Ᵽ:"P",Ꝑ:"P",Ꝓ:"P",Ꝕ:"P","Ⓠ":"Q",Q:"Q",Ꝗ:"Q",Ꝙ:"Q",Ɋ:"Q","Ⓡ":"R",R:"R",Ŕ:"R",Ṙ:"R",Ř:"R",Ȑ:"R",Ȓ:"R",Ṛ:"R",Ṝ:"R",Ŗ:"R",Ṟ:"R",Ɍ:"R",Ɽ:"R",Ꝛ:"R",Ꞧ:"R",Ꞃ:"R","Ⓢ":"S",S:"S",ẞ:"S",Ś:"S",Ṥ:"S",Ŝ:"S",Ṡ:"S",Š:"S",Ṧ:"S",Ṣ:"S",Ṩ:"S",Ș:"S",Ş:"S",Ȿ:"S",Ꞩ:"S",Ꞅ:"S","Ⓣ":"T",T:"T",Ṫ:"T",Ť:"T",Ṭ:"T",Ț:"T",Ţ:"T",Ṱ:"T",Ṯ:"T",Ŧ:"T",Ƭ:"T",Ʈ:"T",Ⱦ:"T",Ꞇ:"T",Ꜩ:"TZ","Ⓤ":"U",U:"U",Ù:"U",Ú:"U",Û:"U",Ũ:"U",Ṹ:"U",Ū:"U",Ṻ:"U",Ŭ:"U",Ü:"U",Ǜ:"U",Ǘ:"U",Ǖ:"U",Ǚ:"U",Ủ:"U",Ů:"U",Ű:"U",Ǔ:"U",Ȕ:"U",Ȗ:"U",Ư:"U",Ừ:"U",Ứ:"U",Ữ:"U",Ử:"U",Ự:"U",Ụ:"U",Ṳ:"U",Ų:"U",Ṷ:"U",Ṵ:"U",Ʉ:"U","Ⓥ":"V",V:"V",Ṽ:"V",Ṿ:"V",Ʋ:"V",Ꝟ:"V",Ʌ:"V",Ꝡ:"VY","Ⓦ":"W",W:"W",Ẁ:"W",Ẃ:"W",Ŵ:"W",Ẇ:"W",Ẅ:"W",Ẉ:"W",Ⱳ:"W","Ⓧ":"X",X:"X",Ẋ:"X",Ẍ:"X","Ⓨ":"Y",Y:"Y",Ỳ:"Y",Ý:"Y",Ŷ:"Y",Ỹ:"Y",Ȳ:"Y",Ẏ:"Y",Ÿ:"Y",Ỷ:"Y",Ỵ:"Y",Ƴ:"Y",Ɏ:"Y",Ỿ:"Y","Ⓩ":"Z",Z:"Z",Ź:"Z",Ẑ:"Z",Ż:"Z",Ž:"Z",Ẓ:"Z",Ẕ:"Z",Ƶ:"Z",Ȥ:"Z",Ɀ:"Z",Ⱬ:"Z",Ꝣ:"Z","ⓐ":"a",a:"a",ẚ:"a",à:"a",á:"a",â:"a",ầ:"a",ấ:"a",ẫ:"a",ẩ:"a",ã:"a",ā:"a",ă:"a",ằ:"a",ắ:"a",ẵ:"a",ẳ:"a",ȧ:"a",ǡ:"a",ä:"a",ǟ:"a",ả:"a",å:"a",ǻ:"a",ǎ:"a",ȁ:"a",ȃ:"a",ạ:"a",ậ:"a",ặ:"a",ḁ:"a",ą:"a",ⱥ:"a",ɐ:"a",ꜳ:"aa",æ:"ae",ǽ:"ae",ǣ:"ae",ꜵ:"ao",ꜷ:"au",ꜹ:"av",ꜻ:"av",ꜽ:"ay","ⓑ":"b",b:"b",ḃ:"b",ḅ:"b",ḇ:"b",ƀ:"b",ƃ:"b",ɓ:"b","ⓒ":"c",c:"c",ć:"c",ĉ:"c",ċ:"c",č:"c",ç:"c",ḉ:"c",ƈ:"c",ȼ:"c",ꜿ:"c",ↄ:"c","ⓓ":"d",d:"d",ḋ:"d",ď:"d",ḍ:"d",ḑ:"d",ḓ:"d",ḏ:"d",đ:"d",ƌ:"d",ɖ:"d",ɗ:"d",ꝺ:"d",dz:"dz",dž:"dz","ⓔ":"e",e:"e",è:"e",é:"e",ê:"e",ề:"e",ế:"e",ễ:"e",ể:"e",ẽ:"e",ē:"e",ḕ:"e",ḗ:"e",ĕ:"e",ė:"e",ë:"e",ẻ:"e",ě:"e",ȅ:"e",ȇ:"e",ẹ:"e",ệ:"e",ȩ:"e",ḝ:"e",ę:"e",ḙ:"e",ḛ:"e",ɇ:"e",ɛ:"e",ǝ:"e","ⓕ":"f",f:"f",ḟ:"f",ƒ:"f",ꝼ:"f","ⓖ":"g",g:"g",ǵ:"g",ĝ:"g",ḡ:"g",ğ:"g",ġ:"g",ǧ:"g",ģ:"g",ǥ:"g",ɠ:"g",ꞡ:"g",ᵹ:"g",ꝿ:"g","ⓗ":"h",h:"h",ĥ:"h",ḣ:"h",ḧ:"h",ȟ:"h",ḥ:"h",ḩ:"h",ḫ:"h",ẖ:"h",ħ:"h",ⱨ:"h",ⱶ:"h",ɥ:"h",ƕ:"hv","ⓘ":"i",i:"i",ì:"i",í:"i",î:"i",ĩ:"i",ī:"i",ĭ:"i",ï:"i",ḯ:"i",ỉ:"i",ǐ:"i",ȉ:"i",ȋ:"i",ị:"i",į:"i",ḭ:"i",ɨ:"i",ı:"i","ⓙ":"j",j:"j",ĵ:"j",ǰ:"j",ɉ:"j","ⓚ":"k",k:"k",ḱ:"k",ǩ:"k",ḳ:"k",ķ:"k",ḵ:"k",ƙ:"k",ⱪ:"k",ꝁ:"k",ꝃ:"k",ꝅ:"k",ꞣ:"k","ⓛ":"l",l:"l",ŀ:"l",ĺ:"l",ľ:"l",ḷ:"l",ḹ:"l",ļ:"l",ḽ:"l",ḻ:"l",ſ:"l",ł:"l",ƚ:"l",ɫ:"l",ⱡ:"l",ꝉ:"l",ꞁ:"l",ꝇ:"l",lj:"lj","ⓜ":"m",m:"m",ḿ:"m",ṁ:"m",ṃ:"m",ɱ:"m",ɯ:"m","ⓝ":"n",n:"n",ǹ:"n",ń:"n",ñ:"n",ṅ:"n",ň:"n",ṇ:"n",ņ:"n",ṋ:"n",ṉ:"n",ƞ:"n",ɲ:"n",ʼn:"n",ꞑ:"n",ꞥ:"n",nj:"nj","ⓞ":"o",o:"o",ò:"o",ó:"o",ô:"o",ồ:"o",ố:"o",ỗ:"o",ổ:"o",õ:"o",ṍ:"o",ȭ:"o",ṏ:"o",ō:"o",ṑ:"o",ṓ:"o",ŏ:"o",ȯ:"o",ȱ:"o",ö:"o",ȫ:"o",ỏ:"o",ő:"o",ǒ:"o",ȍ:"o",ȏ:"o",ơ:"o",ờ:"o",ớ:"o",ỡ:"o",ở:"o",ợ:"o",ọ:"o",ộ:"o",ǫ:"o",ǭ:"o",ø:"o",ǿ:"o",ɔ:"o",ꝋ:"o",ꝍ:"o",ɵ:"o",œ:"oe",ƣ:"oi",ȣ:"ou",ꝏ:"oo","ⓟ":"p",p:"p",ṕ:"p",ṗ:"p",ƥ:"p",ᵽ:"p",ꝑ:"p",ꝓ:"p",ꝕ:"p","ⓠ":"q",q:"q",ɋ:"q",ꝗ:"q",ꝙ:"q","ⓡ":"r",r:"r",ŕ:"r",ṙ:"r",ř:"r",ȑ:"r",ȓ:"r",ṛ:"r",ṝ:"r",ŗ:"r",ṟ:"r",ɍ:"r",ɽ:"r",ꝛ:"r",ꞧ:"r",ꞃ:"r","ⓢ":"s",s:"s",ß:"s",ś:"s",ṥ:"s",ŝ:"s",ṡ:"s",š:"s",ṧ:"s",ṣ:"s",ṩ:"s",ș:"s",ş:"s",ȿ:"s",ꞩ:"s",ꞅ:"s",ẛ:"s","ⓣ":"t",t:"t",ṫ:"t",ẗ:"t",ť:"t",ṭ:"t",ț:"t",ţ:"t",ṱ:"t",ṯ:"t",ŧ:"t",ƭ:"t",ʈ:"t",ⱦ:"t",ꞇ:"t",ꜩ:"tz","ⓤ":"u",u:"u",ù:"u",ú:"u",û:"u",ũ:"u",ṹ:"u",ū:"u",ṻ:"u",ŭ:"u",ü:"u",ǜ:"u",ǘ:"u",ǖ:"u",ǚ:"u",ủ:"u",ů:"u",ű:"u",ǔ:"u",ȕ:"u",ȗ:"u",ư:"u",ừ:"u",ứ:"u",ữ:"u",ử:"u",ự:"u",ụ:"u",ṳ:"u",ų:"u",ṷ:"u",ṵ:"u",ʉ:"u","ⓥ":"v",v:"v",ṽ:"v",ṿ:"v",ʋ:"v",ꝟ:"v",ʌ:"v",ꝡ:"vy","ⓦ":"w",w:"w",ẁ:"w",ẃ:"w",ŵ:"w",ẇ:"w",ẅ:"w",ẘ:"w",ẉ:"w",ⱳ:"w","ⓧ":"x",x:"x",ẋ:"x",ẍ:"x","ⓨ":"y",y:"y",ỳ:"y",ý:"y",ŷ:"y",ỹ:"y",ȳ:"y",ẏ:"y",ÿ:"y",ỷ:"y",ẙ:"y",ỵ:"y",ƴ:"y",ɏ:"y",ỿ:"y","ⓩ":"z",z:"z",ź:"z",ẑ:"z",ż:"z",ž:"z",ẓ:"z",ẕ:"z",ƶ:"z",ȥ:"z",ɀ:"z",ⱬ:"z",ꝣ:"z",Ά:"Α",Έ:"Ε",Ή:"Η",Ί:"Ι",Ϊ:"Ι",Ό:"Ο",Ύ:"Υ",Ϋ:"Υ",Ώ:"Ω",ά:"α",έ:"ε",ή:"η",ί:"ι",ϊ:"ι",ΐ:"ι",ό:"ο",ύ:"υ",ϋ:"υ",ΰ:"υ",ώ:"ω",ς:"σ","’":"'"}})),t.define("select2/data/base",["../utils"],(function(e){function t(e,n){t.__super__.constructor.call(this)}return e.Extend(t,e.Observable),t.prototype.current=function(e){throw new Error("The `current` method must be defined in child classes.")},t.prototype.query=function(e,t){throw new Error("The `query` method must be defined in child classes.")},t.prototype.bind=function(e,t){},t.prototype.destroy=function(){},t.prototype.generateResultId=function(t,n){var o=t.id+"-result-";return o+=e.generateChars(4),null!=n.id?o+="-"+n.id.toString():o+="-"+e.generateChars(4),o},t})),t.define("select2/data/select",["./base","../utils","jquery"],(function(e,t,n){function o(e,t){this.$element=e,this.options=t,o.__super__.constructor.call(this)}return t.Extend(o,e),o.prototype.current=function(e){var t=[],o=this;this.$element.find(":selected").each((function(){var e=n(this),i=o.item(e);t.push(i)})),e(t)},o.prototype.select=function(e){var t=this;if(e.selected=!0,n(e.element).is("option"))return e.element.selected=!0,void this.$element.trigger("input").trigger("change");if(this.$element.prop("multiple"))this.current((function(o){var i=[];(e=[e]).push.apply(e,o);for(var r=0;r<e.length;r++){var s=e[r].id;-1===n.inArray(s,i)&&i.push(s)}t.$element.val(i),t.$element.trigger("input").trigger("change")}));else{var o=e.id;this.$element.val(o),this.$element.trigger("input").trigger("change")}},o.prototype.unselect=function(e){var t=this;if(this.$element.prop("multiple")){if(e.selected=!1,n(e.element).is("option"))return e.element.selected=!1,void this.$element.trigger("input").trigger("change");this.current((function(o){for(var i=[],r=0;r<o.length;r++){var s=o[r].id;s!==e.id&&-1===n.inArray(s,i)&&i.push(s)}t.$element.val(i),t.$element.trigger("input").trigger("change")}))}},o.prototype.bind=function(e,t){var n=this;this.container=e,e.on("select",(function(e){n.select(e.data)})),e.on("unselect",(function(e){n.unselect(e.data)}))},o.prototype.destroy=function(){this.$element.find("*").each((function(){t.RemoveData(this)}))},o.prototype.query=function(e,t){var o=[],i=this;this.$element.children().each((function(){var t=n(this);if(t.is("option")||t.is("optgroup")){var r=i.item(t),s=i.matches(e,r);null!==s&&o.push(s)}})),t({results:o})},o.prototype.addOptions=function(e){t.appendMany(this.$element,e)},o.prototype.option=function(e){var o;e.children?(o=document.createElement("optgroup")).label=e.text:void 0!==(o=document.createElement("option")).textContent?o.textContent=e.text:o.innerText=e.text,void 0!==e.id&&(o.value=e.id),e.disabled&&(o.disabled=!0),e.selected&&(o.selected=!0),e.title&&(o.title=e.title);var i=n(o),r=this._normalizeItem(e);return r.element=o,t.StoreData(o,"data",r),i},o.prototype.item=function(e){var o={};if(null!=(o=t.GetData(e[0],"data")))return o;if(e.is("option"))o={id:e.val(),text:e.text(),disabled:e.prop("disabled"),selected:e.prop("selected"),title:e.prop("title")};else if(e.is("optgroup")){o={text:e.prop("label"),children:[],title:e.prop("title")};for(var i=e.children("option"),r=[],s=0;s<i.length;s++){var a=n(i[s]),l=this.item(a);r.push(l)}o.children=r}return(o=this._normalizeItem(o)).element=e[0],t.StoreData(e[0],"data",o),o},o.prototype._normalizeItem=function(e){e!==Object(e)&&(e={id:e,text:e});var t={selected:!1,disabled:!1};return null!=(e=n.extend({},{text:""},e)).id&&(e.id=e.id.toString()),null!=e.text&&(e.text=e.text.toString()),null==e._resultId&&e.id&&null!=this.container&&(e._resultId=this.generateResultId(this.container,e)),n.extend({},t,e)},o.prototype.matches=function(e,t){return this.options.get("matcher")(e,t)},o})),t.define("select2/data/array",["./select","../utils","jquery"],(function(e,t,n){function o(e,t){this._dataToConvert=t.get("data")||[],o.__super__.constructor.call(this,e,t)}return t.Extend(o,e),o.prototype.bind=function(e,t){o.__super__.bind.call(this,e,t),this.addOptions(this.convertToOptions(this._dataToConvert))},o.prototype.select=function(e){var t=this.$element.find("option").filter((function(t,n){return n.value==e.id.toString()}));0===t.length&&(t=this.option(e),this.addOptions(t)),o.__super__.select.call(this,e)},o.prototype.convertToOptions=function(e){var o=this,i=this.$element.find("option"),r=i.map((function(){return o.item(n(this)).id})).get(),s=[];function a(e){return function(){return n(this).val()==e.id}}for(var l=0;l<e.length;l++){var c=this._normalizeItem(e[l]);if(n.inArray(c.id,r)>=0){var d=i.filter(a(c)),u=this.item(d),p=n.extend(!0,{},c,u),h=this.option(p);d.replaceWith(h)}else{var f=this.option(c);if(c.children){var m=this.convertToOptions(c.children);t.appendMany(f,m)}s.push(f)}}return s},o})),t.define("select2/data/ajax",["./array","../utils","jquery"],(function(e,t,n){function o(e,t){this.ajaxOptions=this._applyDefaults(t.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),o.__super__.constructor.call(this,e,t)}return t.Extend(o,e),o.prototype._applyDefaults=function(e){var t={data:function(e){return n.extend({},e,{q:e.term})},transport:function(e,t,o){var i=n.ajax(e);return i.then(t),i.fail(o),i}};return n.extend({},t,e,!0)},o.prototype.processResults=function(e){return e},o.prototype.query=function(e,t){var o=this;null!=this._request&&(n.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var i=n.extend({type:"GET"},this.ajaxOptions);function r(){var r=i.transport(i,(function(i){var r=o.processResults(i,e);o.options.get("debug")&&window.console&&console.error&&(r&&r.results&&n.isArray(r.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),t(r)}),(function(){(!("status"in r)||0!==r.status&&"0"!==r.status)&&o.trigger("results:message",{message:"errorLoading"})}));o._request=r}"function"==typeof i.url&&(i.url=i.url.call(this.$element,e)),"function"==typeof i.data&&(i.data=i.data.call(this.$element,e)),this.ajaxOptions.delay&&null!=e.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(r,this.ajaxOptions.delay)):r()},o})),t.define("select2/data/tags",["jquery"],(function(e){function t(t,n,o){var i=o.get("tags"),r=o.get("createTag");void 0!==r&&(this.createTag=r);var s=o.get("insertTag");if(void 0!==s&&(this.insertTag=s),t.call(this,n,o),e.isArray(i))for(var a=0;a<i.length;a++){var l=i[a],c=this._normalizeItem(l),d=this.option(c);this.$element.append(d)}}return t.prototype.query=function(e,t,n){var o=this;function i(e,r){for(var s=e.results,a=0;a<s.length;a++){var l=s[a],c=null!=l.children&&!i({results:l.children},!0);if((l.text||"").toUpperCase()===(t.term||"").toUpperCase()||c)return!r&&(e.data=s,void n(e))}if(r)return!0;var d=o.createTag(t);if(null!=d){var u=o.option(d);u.attr("data-select2-tag",!0),o.addOptions([u]),o.insertTag(s,d)}e.results=s,n(e)}this._removeOldTags(),null!=t.term&&null==t.page?e.call(this,t,i):e.call(this,t,n)},t.prototype.createTag=function(t,n){var o=e.trim(n.term);return""===o?null:{id:o,text:o}},t.prototype.insertTag=function(e,t,n){t.unshift(n)},t.prototype._removeOldTags=function(t){this.$element.find("option[data-select2-tag]").each((function(){this.selected||e(this).remove()}))},t})),t.define("select2/data/tokenizer",["jquery"],(function(e){function t(e,t,n){var o=n.get("tokenizer");void 0!==o&&(this.tokenizer=o),e.call(this,t,n)}return t.prototype.bind=function(e,t,n){e.call(this,t,n),this.$search=t.dropdown.$search||t.selection.$search||n.find(".select2-search__field")},t.prototype.query=function(t,n,o){var i=this;function r(t){var n=i._normalizeItem(t);if(!i.$element.find("option").filter((function(){return e(this).val()===n.id})).length){var o=i.option(n);o.attr("data-select2-tag",!0),i._removeOldTags(),i.addOptions([o])}s(n)}function s(e){i.trigger("select",{data:e})}n.term=n.term||"";var a=this.tokenizer(n,this.options,r);a.term!==n.term&&(this.$search.length&&(this.$search.val(a.term),this.$search.trigger("focus")),n.term=a.term),t.call(this,n,o)},t.prototype.tokenizer=function(t,n,o,i){for(var r=o.get("tokenSeparators")||[],s=n.term,a=0,l=this.createTag||function(e){return{id:e.term,text:e.term}};a<s.length;){var c=s[a];if(-1!==e.inArray(c,r)){var d=s.substr(0,a),u=l(e.extend({},n,{term:d}));null!=u?(i(u),s=s.substr(a+1)||"",a=0):a++}else a++}return{term:s}},t})),t.define("select2/data/minimumInputLength",[],(function(){function e(e,t,n){this.minimumInputLength=n.get("minimumInputLength"),e.call(this,t,n)}return e.prototype.query=function(e,t,n){t.term=t.term||"",t.term.length<this.minimumInputLength?this.trigger("results:message",{message:"inputTooShort",args:{minimum:this.minimumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e})),t.define("select2/data/maximumInputLength",[],(function(){function e(e,t,n){this.maximumInputLength=n.get("maximumInputLength"),e.call(this,t,n)}return e.prototype.query=function(e,t,n){t.term=t.term||"",this.maximumInputLength>0&&t.term.length>this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e})),t.define("select2/data/maximumSelectionLength",[],(function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var o=this;e.call(this,t,n),t.on("select",(function(){o._checkIfMaximumSelected()}))},e.prototype.query=function(e,t,n){var o=this;this._checkIfMaximumSelected((function(){e.call(o,t,n)}))},e.prototype._checkIfMaximumSelected=function(e,t){var n=this;this.current((function(e){var o=null!=e?e.length:0;n.maximumSelectionLength>0&&o>=n.maximumSelectionLength?n.trigger("results:message",{message:"maximumSelected",args:{maximum:n.maximumSelectionLength}}):t&&t()}))},e})),t.define("select2/dropdown",["jquery","./utils"],(function(e,t){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return t.Extend(n,t.Observable),n.prototype.render=function(){var t=e('<span class="select2-dropdown"><span class="select2-results"></span></span>');return t.attr("dir",this.options.get("dir")),this.$dropdown=t,t},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n})),t.define("select2/dropdown/search",["jquery","../utils"],(function(e,t){function n(){}return n.prototype.render=function(t){var n=t.call(this),o=e('<span class="select2-search select2-search--dropdown"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="searchbox" aria-autocomplete="list" /></span>');return this.$searchContainer=o,this.$search=o.find("input"),n.prepend(o),n},n.prototype.bind=function(t,n,o){var i=this,r=n.id+"-results";t.call(this,n,o),this.$search.on("keydown",(function(e){i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented()})),this.$search.on("input",(function(t){e(this).off("keyup")})),this.$search.on("keyup input",(function(e){i.handleSearch(e)})),n.on("open",(function(){i.$search.attr("tabindex",0),i.$search.attr("aria-controls",r),i.$search.trigger("focus"),window.setTimeout((function(){i.$search.trigger("focus")}),0)})),n.on("close",(function(){i.$search.attr("tabindex",-1),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.val(""),i.$search.trigger("blur")})),n.on("focus",(function(){n.isOpen()||i.$search.trigger("focus")})),n.on("results:all",(function(e){null!=e.query.term&&""!==e.query.term||(i.showSearch(e)?i.$searchContainer.removeClass("select2-search--hide"):i.$searchContainer.addClass("select2-search--hide"))})),n.on("results:focus",(function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")}))},n.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},n.prototype.showSearch=function(e,t){return!0},n})),t.define("select2/dropdown/hidePlaceholder",[],(function(){function e(e,t,n,o){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,o)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),o=t.length-1;o>=0;o--){var i=t[o];this.placeholder.id===i.id&&n.splice(o,1)}return n},e})),t.define("select2/dropdown/infiniteScroll",["jquery"],(function(e){function t(e,t,n,o){this.lastParams={},e.call(this,t,n,o),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return t.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&(this.$results.append(this.$loadingMore),this.loadMoreIfNeeded())},t.prototype.bind=function(e,t,n){var o=this;e.call(this,t,n),t.on("query",(function(e){o.lastParams=e,o.loading=!0})),t.on("query:append",(function(e){o.lastParams=e,o.loading=!0})),this.$results.on("scroll",this.loadMoreIfNeeded.bind(this))},t.prototype.loadMoreIfNeeded=function(){var t=e.contains(document.documentElement,this.$loadingMore[0]);!this.loading&&t&&this.$results.offset().top+this.$results.outerHeight(!1)+50>=this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)&&this.loadMore()},t.prototype.loadMore=function(){this.loading=!0;var t=e.extend({},{page:1},this.lastParams);t.page++,this.trigger("query:append",t)},t.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},t.prototype.createLoadingMore=function(){var t=e('<li class="select2-results__option select2-results__option--load-more"role="option" aria-disabled="true"></li>'),n=this.options.get("translations").get("loadingMore");return t.html(n(this.lastParams)),t},t})),t.define("select2/dropdown/attachBody",["jquery","../utils"],(function(e,t){function n(t,n,o){this.$dropdownParent=e(o.get("dropdownParent")||document.body),t.call(this,n,o)}return n.prototype.bind=function(e,t,n){var o=this;e.call(this,t,n),t.on("open",(function(){o._showDropdown(),o._attachPositioningHandler(t),o._bindContainerResultHandlers(t)})),t.on("close",(function(){o._hideDropdown(),o._detachPositioningHandler(t)})),this.$dropdownContainer.on("mousedown",(function(e){e.stopPropagation()}))},n.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},n.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},n.prototype.render=function(t){var n=e("<span></span>"),o=t.call(this);return n.append(o),this.$dropdownContainer=n,n},n.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},n.prototype._bindContainerResultHandlers=function(e,t){if(!this._containerResultsHandlersBound){var n=this;t.on("results:all",(function(){n._positionDropdown(),n._resizeDropdown()})),t.on("results:append",(function(){n._positionDropdown(),n._resizeDropdown()})),t.on("results:message",(function(){n._positionDropdown(),n._resizeDropdown()})),t.on("select",(function(){n._positionDropdown(),n._resizeDropdown()})),t.on("unselect",(function(){n._positionDropdown(),n._resizeDropdown()})),this._containerResultsHandlersBound=!0}},n.prototype._attachPositioningHandler=function(n,o){var i=this,r="scroll.select2."+o.id,s="resize.select2."+o.id,a="orientationchange.select2."+o.id,l=this.$container.parents().filter(t.hasScroll);l.each((function(){t.StoreData(this,"select2-scroll-position",{x:e(this).scrollLeft(),y:e(this).scrollTop()})})),l.on(r,(function(n){var o=t.GetData(this,"select2-scroll-position");e(this).scrollTop(o.y)})),e(window).on(r+" "+s+" "+a,(function(e){i._positionDropdown(),i._resizeDropdown()}))},n.prototype._detachPositioningHandler=function(n,o){var i="scroll.select2."+o.id,r="resize.select2."+o.id,s="orientationchange.select2."+o.id;this.$container.parents().filter(t.hasScroll).off(i),e(window).off(i+" "+r+" "+s)},n.prototype._positionDropdown=function(){var t=e(window),n=this.$dropdown.hasClass("select2-dropdown--above"),o=this.$dropdown.hasClass("select2-dropdown--below"),i=null,r=this.$container.offset();r.bottom=r.top+this.$container.outerHeight(!1);var s={height:this.$container.outerHeight(!1)};s.top=r.top,s.bottom=r.top+s.height;var a={height:this.$dropdown.outerHeight(!1)},l={top:t.scrollTop(),bottom:t.scrollTop()+t.height()},c=l.top<r.top-a.height,d=l.bottom>r.bottom+a.height,u={left:r.left,top:s.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h={top:0,left:0};(e.contains(document.body,p[0])||p[0].isConnected)&&(h=p.offset()),u.top-=h.top,u.left-=h.left,n||o||(i="below"),d||!c||n?!c&&d&&n&&(i="below"):i="above",("above"==i||n&&"below"!==i)&&(u.top=s.top-h.top-a.height),null!=i&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+i),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+i)),this.$dropdownContainer.css(u)},n.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},n.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},n})),t.define("select2/dropdown/minimumResultsForSearch",[],(function(){function e(t){for(var n=0,o=0;o<t.length;o++){var i=t[o];i.children?n+=e(i.children):n++}return n}function t(e,t,n,o){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,o)}return t.prototype.showSearch=function(t,n){return!(e(n.data.results)<this.minimumResultsForSearch)&&t.call(this,n)},t})),t.define("select2/dropdown/selectOnClose",["../utils"],(function(e){function t(){}return t.prototype.bind=function(e,t,n){var o=this;e.call(this,t,n),t.on("close",(function(e){o._handleSelectOnClose(e)}))},t.prototype._handleSelectOnClose=function(t,n){if(n&&null!=n.originalSelect2Event){var o=n.originalSelect2Event;if("select"===o._type||"unselect"===o._type)return}var i=this.getHighlightedResults();if(!(i.length<1)){var r=e.GetData(i[0],"data");null!=r.element&&r.element.selected||null==r.element&&r.selected||this.trigger("select",{data:r})}},t})),t.define("select2/dropdown/closeOnSelect",[],(function(){function e(){}return e.prototype.bind=function(e,t,n){var o=this;e.call(this,t,n),t.on("select",(function(e){o._selectTriggered(e)})),t.on("unselect",(function(e){o._selectTriggered(e)}))},e.prototype._selectTriggered=function(e,t){var n=t.originalEvent;n&&(n.ctrlKey||n.metaKey)||this.trigger("close",{originalEvent:n,originalSelect2Event:t})},e})),t.define("select2/i18n/en",[],(function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Please delete "+t+" character";return 1!=t&&(n+="s"),n},inputTooShort:function(e){return"Please enter "+(e.minimum-e.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var t="You can only select "+e.maximum+" item";return 1!=e.maximum&&(t+="s"),t},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}})),t.define("select2/defaults",["jquery","require","./results","./selection/single","./selection/multiple","./selection/placeholder","./selection/allowClear","./selection/search","./selection/eventRelay","./utils","./translation","./diacritics","./data/select","./data/array","./data/ajax","./data/tags","./data/tokenizer","./data/minimumInputLength","./data/maximumInputLength","./data/maximumSelectionLength","./dropdown","./dropdown/search","./dropdown/hidePlaceholder","./dropdown/infiniteScroll","./dropdown/attachBody","./dropdown/minimumResultsForSearch","./dropdown/selectOnClose","./dropdown/closeOnSelect","./i18n/en"],(function(e,t,n,o,i,r,s,a,l,c,d,u,p,h,f,m,g,v,_,y,b,w,x,A,C,$,O,S,E){function k(){this.reset()}return k.prototype.apply=function(d){if(null==(d=e.extend(!0,{},this.defaults,d)).dataAdapter){if(null!=d.ajax?d.dataAdapter=f:null!=d.data?d.dataAdapter=h:d.dataAdapter=p,d.minimumInputLength>0&&(d.dataAdapter=c.Decorate(d.dataAdapter,v)),d.maximumInputLength>0&&(d.dataAdapter=c.Decorate(d.dataAdapter,_)),d.maximumSelectionLength>0&&(d.dataAdapter=c.Decorate(d.dataAdapter,y)),d.tags&&(d.dataAdapter=c.Decorate(d.dataAdapter,m)),null==d.tokenSeparators&&null==d.tokenizer||(d.dataAdapter=c.Decorate(d.dataAdapter,g)),null!=d.query){var u=t(d.amdBase+"compat/query");d.dataAdapter=c.Decorate(d.dataAdapter,u)}if(null!=d.initSelection){var E=t(d.amdBase+"compat/initSelection");d.dataAdapter=c.Decorate(d.dataAdapter,E)}}if(null==d.resultsAdapter&&(d.resultsAdapter=n,null!=d.ajax&&(d.resultsAdapter=c.Decorate(d.resultsAdapter,A)),null!=d.placeholder&&(d.resultsAdapter=c.Decorate(d.resultsAdapter,x)),d.selectOnClose&&(d.resultsAdapter=c.Decorate(d.resultsAdapter,O))),null==d.dropdownAdapter){if(d.multiple)d.dropdownAdapter=b;else{var k=c.Decorate(b,w);d.dropdownAdapter=k}if(0!==d.minimumResultsForSearch&&(d.dropdownAdapter=c.Decorate(d.dropdownAdapter,$)),d.closeOnSelect&&(d.dropdownAdapter=c.Decorate(d.dropdownAdapter,S)),null!=d.dropdownCssClass||null!=d.dropdownCss||null!=d.adaptDropdownCssClass){var D=t(d.amdBase+"compat/dropdownCss");d.dropdownAdapter=c.Decorate(d.dropdownAdapter,D)}d.dropdownAdapter=c.Decorate(d.dropdownAdapter,C)}if(null==d.selectionAdapter){if(d.multiple?d.selectionAdapter=i:d.selectionAdapter=o,null!=d.placeholder&&(d.selectionAdapter=c.Decorate(d.selectionAdapter,r)),d.allowClear&&(d.selectionAdapter=c.Decorate(d.selectionAdapter,s)),d.multiple&&(d.selectionAdapter=c.Decorate(d.selectionAdapter,a)),null!=d.containerCssClass||null!=d.containerCss||null!=d.adaptContainerCssClass){var L=t(d.amdBase+"compat/containerCss");d.selectionAdapter=c.Decorate(d.selectionAdapter,L)}d.selectionAdapter=c.Decorate(d.selectionAdapter,l)}d.language=this._resolveLanguage(d.language),d.language.push("en");for(var P=[],T=0;T<d.language.length;T++){var j=d.language[T];-1===P.indexOf(j)&&P.push(j)}return d.language=P,d.translations=this._processTranslations(d.language,d.debug),d},k.prototype.reset=function(){function t(e){function t(e){return u[e]||e}return e.replace(/[^\u0000-\u007E]/g,t)}function n(o,i){if(""===e.trim(o.term))return i;if(i.children&&i.children.length>0){for(var r=e.extend(!0,{},i),s=i.children.length-1;s>=0;s--)null==n(o,i.children[s])&&r.children.splice(s,1);return r.children.length>0?r:n(o,r)}var a=t(i.text).toUpperCase(),l=t(o.term).toUpperCase();return a.indexOf(l)>-1?i:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:c.escapeMarkup,language:{},matcher:n,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,scrollAfterSelect:!1,sorter:function(e){return e},templateResult:function(e){return e.text},templateSelection:function(e){return e.text},theme:"default",width:"resolve"}},k.prototype.applyFromElement=function(e,t){var n=e.language,o=this.defaults.language,i=t.prop("lang"),r=t.closest("[lang]").prop("lang"),s=Array.prototype.concat.call(this._resolveLanguage(i),this._resolveLanguage(n),this._resolveLanguage(o),this._resolveLanguage(r));return e.language=s,e},k.prototype._resolveLanguage=function(t){if(!t)return[];if(e.isEmptyObject(t))return[];if(e.isPlainObject(t))return[t];var n;n=e.isArray(t)?t:[t];for(var o=[],i=0;i<n.length;i++)if(o.push(n[i]),"string"==typeof n[i]&&n[i].indexOf("-")>0){var r=n[i].split("-")[0];o.push(r)}return o},k.prototype._processTranslations=function(t,n){for(var o=new d,i=0;i<t.length;i++){var r=new d,s=t[i];if("string"==typeof s)try{r=d.loadPath(s)}catch(e){try{s=this.defaults.amdLanguageBase+s,r=d.loadPath(s)}catch(e){n&&window.console&&console.warn&&console.warn('Select2: The language file for "'+s+'" could not be automatically loaded. A fallback will be used instead.')}}else r=e.isPlainObject(s)?new d(s):s;o.extend(r)}return o},k.prototype.set=function(t,n){var o={};o[e.camelCase(t)]=n;var i=c._convertData(o);e.extend(!0,this.defaults,i)},new k})),t.define("select2/options",["require","jquery","./defaults","./utils"],(function(e,t,n,o){function i(t,i){if(this.options=t,null!=i&&this.fromElement(i),null!=i&&(this.options=n.applyFromElement(this.options,i)),this.options=n.apply(this.options),i&&i.is("input")){var r=e(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=o.Decorate(this.options.dataAdapter,r)}}return i.prototype.fromElement=function(e){var n=["select2"];null==this.options.multiple&&(this.options.multiple=e.prop("multiple")),null==this.options.disabled&&(this.options.disabled=e.prop("disabled")),null==this.options.dir&&(e.prop("dir")?this.options.dir=e.prop("dir"):e.closest("[dir]").prop("dir")?this.options.dir=e.closest("[dir]").prop("dir"):this.options.dir="ltr"),e.prop("disabled",this.options.disabled),e.prop("multiple",this.options.multiple),o.GetData(e[0],"select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),o.StoreData(e[0],"data",o.GetData(e[0],"select2Tags")),o.StoreData(e[0],"tags",!0)),o.GetData(e[0],"ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),e.attr("ajax--url",o.GetData(e[0],"ajaxUrl")),o.StoreData(e[0],"ajax-Url",o.GetData(e[0],"ajaxUrl")));var i={};function r(e,t){return t.toUpperCase()}for(var s=0;s<e[0].attributes.length;s++){var a=e[0].attributes[s].name,l="data-";if(a.substr(0,l.length)==l){var c=a.substring(l.length),d=o.GetData(e[0],c);i[c.replace(/-([a-z])/g,r)]=d}}t.fn.jquery&&"1."==t.fn.jquery.substr(0,2)&&e[0].dataset&&(i=t.extend(!0,{},e[0].dataset,i));var u=t.extend(!0,{},o.GetData(e[0]),i);for(var p in u=o._convertData(u))t.inArray(p,n)>-1||(t.isPlainObject(this.options[p])?t.extend(this.options[p],u[p]):this.options[p]=u[p]);return this},i.prototype.get=function(e){return this.options[e]},i.prototype.set=function(e,t){this.options[e]=t},i})),t.define("select2/core",["jquery","./options","./utils","./keys"],(function(e,t,n,o){var i=function(e,o){null!=n.GetData(e[0],"select2")&&n.GetData(e[0],"select2").destroy(),this.$element=e,this.id=this._generateId(e),o=o||{},this.options=new t(o,e),i.__super__.constructor.call(this);var r=e.attr("tabindex")||0;n.StoreData(e[0],"old-tabindex",r),e.attr("tabindex","-1");var s=this.options.get("dataAdapter");this.dataAdapter=new s(e,this.options);var a=this.render();this._placeContainer(a);var l=this.options.get("selectionAdapter");this.selection=new l(e,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,a);var c=this.options.get("dropdownAdapter");this.dropdown=new c(e,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,a);var d=this.options.get("resultsAdapter");this.results=new d(e,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var u=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current((function(e){u.trigger("selection:update",{data:e})})),e.addClass("select2-hidden-accessible"),e.attr("aria-hidden","true"),this._syncAttributes(),n.StoreData(e[0],"select2",this),e.data("select2",this)};return n.Extend(i,n.Observable),i.prototype._generateId=function(e){return"select2-"+(null!=e.attr("id")?e.attr("id"):null!=e.attr("name")?e.attr("name")+"-"+n.generateChars(2):n.generateChars(4)).replace(/(:|\.|\[|\]|,)/g,"")},i.prototype._placeContainer=function(e){e.insertAfter(this.$element);var t=this._resolveWidth(this.$element,this.options.get("width"));null!=t&&e.css("width",t)},i.prototype._resolveWidth=function(e,t){var n=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==t){var o=this._resolveWidth(e,"style");return null!=o?o:this._resolveWidth(e,"element")}if("element"==t){var i=e.outerWidth(!1);return i<=0?"auto":i+"px"}if("style"==t){var r=e.attr("style");if("string"!=typeof r)return null;for(var s=r.split(";"),a=0,l=s.length;a<l;a+=1){var c=s[a].replace(/\s/g,"").match(n);if(null!==c&&c.length>=1)return c[1]}return null}return"computedstyle"==t?window.getComputedStyle(e[0]).width:t},i.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},i.prototype._registerDomEvents=function(){var e=this;this.$element.on("change.select2",(function(){e.dataAdapter.current((function(t){e.trigger("selection:update",{data:t})}))})),this.$element.on("focus.select2",(function(t){e.trigger("focus",t)})),this._syncA=n.bind(this._syncAttributes,this),this._syncS=n.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var t=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=t?(this._observer=new t((function(t){e._syncA(),e._syncS(null,t)})),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",e._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",e._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",e._syncS,!1))},i.prototype._registerDataEvents=function(){var e=this;this.dataAdapter.on("*",(function(t,n){e.trigger(t,n)}))},i.prototype._registerSelectionEvents=function(){var t=this,n=["toggle","focus"];this.selection.on("toggle",(function(){t.toggleDropdown()})),this.selection.on("focus",(function(e){t.focus(e)})),this.selection.on("*",(function(o,i){-1===e.inArray(o,n)&&t.trigger(o,i)}))},i.prototype._registerDropdownEvents=function(){var e=this;this.dropdown.on("*",(function(t,n){e.trigger(t,n)}))},i.prototype._registerResultsEvents=function(){var e=this;this.results.on("*",(function(t,n){e.trigger(t,n)}))},i.prototype._registerEvents=function(){var e=this;this.on("open",(function(){e.$container.addClass("select2-container--open")})),this.on("close",(function(){e.$container.removeClass("select2-container--open")})),this.on("enable",(function(){e.$container.removeClass("select2-container--disabled")})),this.on("disable",(function(){e.$container.addClass("select2-container--disabled")})),this.on("blur",(function(){e.$container.removeClass("select2-container--focus")})),this.on("query",(function(t){e.isOpen()||e.trigger("open",{}),this.dataAdapter.query(t,(function(n){e.trigger("results:all",{data:n,query:t})}))})),this.on("query:append",(function(t){this.dataAdapter.query(t,(function(n){e.trigger("results:append",{data:n,query:t})}))})),this.on("keypress",(function(t){var n=t.which;e.isOpen()?n===o.ESC||n===o.TAB||n===o.UP&&t.altKey?(e.close(t),t.preventDefault()):n===o.ENTER?(e.trigger("results:select",{}),t.preventDefault()):n===o.SPACE&&t.ctrlKey?(e.trigger("results:toggle",{}),t.preventDefault()):n===o.UP?(e.trigger("results:previous",{}),t.preventDefault()):n===o.DOWN&&(e.trigger("results:next",{}),t.preventDefault()):(n===o.ENTER||n===o.SPACE||n===o.DOWN&&t.altKey)&&(e.open(),t.preventDefault())}))},i.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.isDisabled()?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},i.prototype._isChangeMutation=function(t,n){var o=!1,i=this;if(!t||!t.target||"OPTION"===t.target.nodeName||"OPTGROUP"===t.target.nodeName){if(n)if(n.addedNodes&&n.addedNodes.length>0)for(var r=0;r<n.addedNodes.length;r++)n.addedNodes[r].selected&&(o=!0);else n.removedNodes&&n.removedNodes.length>0?o=!0:e.isArray(n)&&e.each(n,(function(e,t){if(i._isChangeMutation(e,t))return o=!0,!1}));else o=!0;return o}},i.prototype._syncSubtree=function(e,t){var n=this._isChangeMutation(e,t),o=this;n&&this.dataAdapter.current((function(e){o.trigger("selection:update",{data:e})}))},i.prototype.trigger=function(e,t){var n=i.__super__.trigger,o={open:"opening",close:"closing",select:"selecting",unselect:"unselecting",clear:"clearing"};if(void 0===t&&(t={}),e in o){var r=o[e],s={prevented:!1,name:e,args:t};if(n.call(this,r,s),s.prevented)return void(t.prevented=!0)}n.call(this,e,t)},i.prototype.toggleDropdown=function(){this.isDisabled()||(this.isOpen()?this.close():this.open())},i.prototype.open=function(){this.isOpen()||this.isDisabled()||this.trigger("query",{})},i.prototype.close=function(e){this.isOpen()&&this.trigger("close",{originalEvent:e})},i.prototype.isEnabled=function(){return!this.isDisabled()},i.prototype.isDisabled=function(){return this.options.get("disabled")},i.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},i.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},i.prototype.focus=function(e){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},i.prototype.enable=function(e){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=e&&0!==e.length||(e=[!0]);var t=!e[0];this.$element.prop("disabled",t)},i.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var e=[];return this.dataAdapter.current((function(t){e=t})),e},i.prototype.val=function(t){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==t||0===t.length)return this.$element.val();var n=t[0];e.isArray(n)&&(n=e.map(n,(function(e){return e.toString()}))),this.$element.val(n).trigger("input").trigger("change")},i.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",n.GetData(this.$element[0],"old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),n.RemoveData(this.$element[0]),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},i.prototype.render=function(){var t=e('<span class="select2 select2-container"><span class="selection"></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>');return t.attr("dir",this.options.get("dir")),this.$container=t,this.$container.addClass("select2-container--"+this.options.get("theme")),n.StoreData(t[0],"element",this.$element),t},i})),t.define("jquery-mousewheel",["jquery"],(function(e){return e})),t.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],(function(e,t,n,o,i){if(null==e.fn.select2){var r=["open","close","destroy"];e.fn.select2=function(t){if("object"==typeof(t=t||{}))return this.each((function(){var o=e.extend(!0,{},t);new n(e(this),o)})),this;if("string"==typeof t){var o,s=Array.prototype.slice.call(arguments,1);return this.each((function(){var e=i.GetData(this,"select2");null==e&&window.console&&console.error&&console.error("The select2('"+t+"') method was called on an element that is not using Select2."),o=e[t].apply(e,s)})),e.inArray(t,r)>-1?this:o}throw new Error("Invalid arguments for Select2: "+t)}}return null==e.fn.select2.defaults&&(e.fn.select2.defaults=o),n})),{define:t.define,require:t.require}}(),n=t.require("jquery.select2");return e.fn.select2.amd=t,n})?o.apply(t,i):o)||(e.exports=r)},913:()=>{const e=document.querySelector('input[type="checkbox"][name="carousel_slider_allow_tracking"]');e&&(window.console.log(window.ajaxurl),e.addEventListener("change",(t=>{const n=new URL(window.CarouselSliderL10n.ajaxUrl);n.searchParams.set("action","carousel_slider_tracker_consent"),n.searchParams.set("_token",e.dataset.token),t.target.checked?n.searchParams.set("carousel_slider_tracker_optin","true"):n.searchParams.set("carousel_slider_tracker_optout","true"),window.console.log(n.toString()),(e=>new Promise((t=>{let n=new XMLHttpRequest;n.addEventListener("load",(()=>{n.readyState===XMLHttpRequest.DONE&&200===n.status&&t(n.responseText)})),n.open("GET",e),n.setRequestHeader("Accept","application/json"),n.send()})))(n.toString()).then((()=>{}))})))},926:()=>{class e extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"});const t=document.createElement("style");t.textContent=e.getStyle(),this.shadowRoot.append(t,this.getElement())}getElement(){const e=document.createElement("button");return e.classList.add("shapla-cross"),this.hasAttribute("size")&&e.classList.add(`is-${this.getAttribute("size")}`),e}attributeChangedCallback(e,t,n){const o=this.shadowRoot.querySelector("button");"size"===e&&this.hasAttribute("size")&&o.classList.add(`is-${this.getAttribute("size")}`)}static get observedAttributes(){return["size"]}static getStyle(){return'.shapla-cross {\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  background-color: var(--delete-icon-background, hsla(0, 0%, 4%, .2));\n  border: none;\n  border-radius: 290486px;\n  cursor: pointer;\n  display: inline-block;\n  flex-grow: 0;\n  flex-shrink: 0;\n  font-size: 0;\n  height: var(--delete-icon-size, 20px);\n  outline: none;\n  pointer-events: auto;\n  position: relative;\n  -webkit-user-select: none;\n  user-select: none;\n  vertical-align: top;\n  width: var(--delete-icon-size, 20px)\n}\n\n.shapla-cross:after, .shapla-cross:before {\n  background-color: var(--delete-icon-color, #fff);\n  content: "";\n  display: block;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translateX(-50%) translateY(-50%) rotate(45deg);\n  transform-origin: center center\n}\n\n.shapla-cross:before {\n  height: 2px;\n  width: 50%\n}\n\n.shapla-cross:after {\n  height: 50%;\n  width: 2px\n}\n\n.shapla-cross:focus, .shapla-cross:hover {\n  background-color: var(--delete-icon-background-dark, hsla(0, 0%, 4%, .3))\n}\n\n.shapla-cross:active {\n  box-shadow: 0 3px 4px 0 rgba(0, 0, 0, .14), 0 3px 3px -2px rgba(0, 0, 0, .2), 0 1px 8px 0 rgba(0, 0, 0, .12)\n}\n\n.shapla-cross.is-small {\n  --delete-icon-size: 16px\n}\n\n.shapla-cross.is-medium {\n  --delete-icon-size: 24px\n}\n\n.shapla-cross.is-large {\n  --delete-icon-size: 32px\n}\n\n.shapla-cross.is-error {\n  --delete-icon-background: var(--shapla-error, #dc3545);\n  --delete-icon-background-dark: var(--shapla-error-variant, #d32535);\n  --delete-icon-color: var(--shapla-on-error, #fff)\n}'}}customElements.define("shapla-cross",e)}},t={};function n(o){var i=t[o];if(void 0!==i)return i.exports;var r=t[o]={exports:{}};return e[o](r,r.exports,n),r.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var o in t)n.o(t,o)&&!n.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";var e=n(669),t=n.n(e);function o(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function i(e){return e instanceof o(e).Element||e instanceof Element}function r(e){return e instanceof o(e).HTMLElement||e instanceof HTMLElement}function s(e){return"undefined"!=typeof ShadowRoot&&(e instanceof o(e).ShadowRoot||e instanceof ShadowRoot)}var a=Math.max,l=Math.min,c=Math.round;function d(){var e=navigator.userAgentData;return null!=e&&e.brands&&Array.isArray(e.brands)?e.brands.map((function(e){return e.brand+"/"+e.version})).join(" "):navigator.userAgent}function u(){return!/^((?!chrome|android).)*safari/i.test(d())}function p(e,t,n){void 0===t&&(t=!1),void 0===n&&(n=!1);var s=e.getBoundingClientRect(),a=1,l=1;t&&r(e)&&(a=e.offsetWidth>0&&c(s.width)/e.offsetWidth||1,l=e.offsetHeight>0&&c(s.height)/e.offsetHeight||1);var d=(i(e)?o(e):window).visualViewport,p=!u()&&n,h=(s.left+(p&&d?d.offsetLeft:0))/a,f=(s.top+(p&&d?d.offsetTop:0))/l,m=s.width/a,g=s.height/l;return{width:m,height:g,top:f,right:h+m,bottom:f+g,left:h,x:h,y:f}}function h(e){var t=o(e);return{scrollLeft:t.pageXOffset,scrollTop:t.pageYOffset}}function f(e){return e?(e.nodeName||"").toLowerCase():null}function m(e){return((i(e)?e.ownerDocument:e.document)||window.document).documentElement}function g(e){return p(m(e)).left+h(e).scrollLeft}function v(e){return o(e).getComputedStyle(e)}function _(e){var t=v(e),n=t.overflow,o=t.overflowX,i=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+i+o)}function y(e,t,n){void 0===n&&(n=!1);var i,s,a=r(t),l=r(t)&&function(e){var t=e.getBoundingClientRect(),n=c(t.width)/e.offsetWidth||1,o=c(t.height)/e.offsetHeight||1;return 1!==n||1!==o}(t),d=m(t),u=p(e,l,n),v={scrollLeft:0,scrollTop:0},y={x:0,y:0};return(a||!a&&!n)&&(("body"!==f(t)||_(d))&&(v=(i=t)!==o(i)&&r(i)?{scrollLeft:(s=i).scrollLeft,scrollTop:s.scrollTop}:h(i)),r(t)?((y=p(t,!0)).x+=t.clientLeft,y.y+=t.clientTop):d&&(y.x=g(d))),{x:u.left+v.scrollLeft-y.x,y:u.top+v.scrollTop-y.y,width:u.width,height:u.height}}function b(e){var t=p(e),n=e.offsetWidth,o=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-o)<=1&&(o=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:o}}function w(e){return"html"===f(e)?e:e.assignedSlot||e.parentNode||(s(e)?e.host:null)||m(e)}function x(e){return["html","body","#document"].indexOf(f(e))>=0?e.ownerDocument.body:r(e)&&_(e)?e:x(w(e))}function A(e,t){var n;void 0===t&&(t=[]);var i=x(e),r=i===(null==(n=e.ownerDocument)?void 0:n.body),s=o(i),a=r?[s].concat(s.visualViewport||[],_(i)?i:[]):i,l=t.concat(a);return r?l:l.concat(A(w(a)))}function C(e){return["table","td","th"].indexOf(f(e))>=0}function $(e){return r(e)&&"fixed"!==v(e).position?e.offsetParent:null}function O(e){for(var t=o(e),n=$(e);n&&C(n)&&"static"===v(n).position;)n=$(n);return n&&("html"===f(n)||"body"===f(n)&&"static"===v(n).position)?t:n||function(e){var t=/firefox/i.test(d());if(/Trident/i.test(d())&&r(e)&&"fixed"===v(e).position)return null;var n=w(e);for(s(n)&&(n=n.host);r(n)&&["html","body"].indexOf(f(n))<0;){var o=v(n);if("none"!==o.transform||"none"!==o.perspective||"paint"===o.contain||-1!==["transform","perspective"].indexOf(o.willChange)||t&&"filter"===o.willChange||t&&o.filter&&"none"!==o.filter)return n;n=n.parentNode}return null}(e)||t}var S="top",E="bottom",k="right",D="left",L="auto",P=[S,E,k,D],T="start",j="end",q="viewport",R="popper",M=P.reduce((function(e,t){return e.concat([t+"-"+T,t+"-"+j])}),[]),I=[].concat(P,[L]).reduce((function(e,t){return e.concat([t,t+"-"+T,t+"-"+j])}),[]),H=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function z(e){var t=new Map,n=new Set,o=[];function i(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var o=t.get(e);o&&i(o)}})),o.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||i(e)})),o}var U={placement:"bottom",modifiers:[],strategy:"absolute"};function B(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return!t.some((function(e){return!(e&&"function"==typeof e.getBoundingClientRect)}))}function N(e){void 0===e&&(e={});var t=e,n=t.defaultModifiers,o=void 0===n?[]:n,r=t.defaultOptions,s=void 0===r?U:r;return function(e,t,n){void 0===n&&(n=s);var r,a,l={placement:"bottom",orderedModifiers:[],options:Object.assign({},U,s),modifiersData:{},elements:{reference:e,popper:t},attributes:{},styles:{}},c=[],d=!1,u={state:l,setOptions:function(n){var r="function"==typeof n?n(l.options):n;p(),l.options=Object.assign({},s,l.options,r),l.scrollParents={reference:i(e)?A(e):e.contextElement?A(e.contextElement):[],popper:A(t)};var a,d,h=function(e){var t=z(e);return H.reduce((function(e,n){return e.concat(t.filter((function(e){return e.phase===n})))}),[])}((a=[].concat(o,l.options.modifiers),d=a.reduce((function(e,t){var n=e[t.name];return e[t.name]=n?Object.assign({},n,t,{options:Object.assign({},n.options,t.options),data:Object.assign({},n.data,t.data)}):t,e}),{}),Object.keys(d).map((function(e){return d[e]}))));return l.orderedModifiers=h.filter((function(e){return e.enabled})),l.orderedModifiers.forEach((function(e){var t=e.name,n=e.options,o=void 0===n?{}:n,i=e.effect;if("function"==typeof i){var r=i({state:l,name:t,instance:u,options:o}),s=function(){};c.push(r||s)}})),u.update()},forceUpdate:function(){if(!d){var e=l.elements,t=e.reference,n=e.popper;if(B(t,n)){l.rects={reference:y(t,O(n),"fixed"===l.options.strategy),popper:b(n)},l.reset=!1,l.placement=l.options.placement,l.orderedModifiers.forEach((function(e){return l.modifiersData[e.name]=Object.assign({},e.data)}));for(var o=0;o<l.orderedModifiers.length;o++)if(!0!==l.reset){var i=l.orderedModifiers[o],r=i.fn,s=i.options,a=void 0===s?{}:s,c=i.name;"function"==typeof r&&(l=r({state:l,options:a,name:c,instance:u})||l)}else l.reset=!1,o=-1}}},update:(r=function(){return new Promise((function(e){u.forceUpdate(),e(l)}))},function(){return a||(a=new Promise((function(e){Promise.resolve().then((function(){a=void 0,e(r())}))}))),a}),destroy:function(){p(),d=!0}};if(!B(e,t))return u;function p(){c.forEach((function(e){return e()})),c=[]}return u.setOptions(n).then((function(e){!d&&n.onFirstUpdate&&n.onFirstUpdate(e)})),u}}var W={passive:!0};function G(e){return e.split("-")[0]}function F(e){return e.split("-")[1]}function Y(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function K(e){var t,n=e.reference,o=e.element,i=e.placement,r=i?G(i):null,s=i?F(i):null,a=n.x+n.width/2-o.width/2,l=n.y+n.height/2-o.height/2;switch(r){case S:t={x:a,y:n.y-o.height};break;case E:t={x:a,y:n.y+n.height};break;case k:t={x:n.x+n.width,y:l};break;case D:t={x:n.x-o.width,y:l};break;default:t={x:n.x,y:n.y}}var c=r?Y(r):null;if(null!=c){var d="y"===c?"height":"width";switch(s){case T:t[c]=t[c]-(n[d]/2-o[d]/2);break;case j:t[c]=t[c]+(n[d]/2-o[d]/2)}}return t}var V={top:"auto",right:"auto",bottom:"auto",left:"auto"};function Z(e){var t,n=e.popper,i=e.popperRect,r=e.placement,s=e.variation,a=e.offsets,l=e.position,d=e.gpuAcceleration,u=e.adaptive,p=e.roundOffsets,h=e.isFixed,f=a.x,g=void 0===f?0:f,_=a.y,y=void 0===_?0:_,b="function"==typeof p?p({x:g,y}):{x:g,y};g=b.x,y=b.y;var w=a.hasOwnProperty("x"),x=a.hasOwnProperty("y"),A=D,C=S,$=window;if(u){var L=O(n),P="clientHeight",T="clientWidth";if(L===o(n)&&"static"!==v(L=m(n)).position&&"absolute"===l&&(P="scrollHeight",T="scrollWidth"),r===S||(r===D||r===k)&&s===j)C=E,y-=(h&&L===$&&$.visualViewport?$.visualViewport.height:L[P])-i.height,y*=d?1:-1;if(r===D||(r===S||r===E)&&s===j)A=k,g-=(h&&L===$&&$.visualViewport?$.visualViewport.width:L[T])-i.width,g*=d?1:-1}var q,R=Object.assign({position:l},u&&V),M=!0===p?function(e,t){var n=e.x,o=e.y,i=t.devicePixelRatio||1;return{x:c(n*i)/i||0,y:c(o*i)/i||0}}({x:g,y},o(n)):{x:g,y};return g=M.x,y=M.y,d?Object.assign({},R,((q={})[C]=x?"0":"",q[A]=w?"0":"",q.transform=($.devicePixelRatio||1)<=1?"translate("+g+"px, "+y+"px)":"translate3d("+g+"px, "+y+"px, 0)",q)):Object.assign({},R,((t={})[C]=x?y+"px":"",t[A]=w?g+"px":"",t.transform="",t))}const J={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.options,o=e.name,i=n.offset,r=void 0===i?[0,0]:i,s=I.reduce((function(e,n){return e[n]=function(e,t,n){var o=G(e),i=[D,S].indexOf(o)>=0?-1:1,r="function"==typeof n?n(Object.assign({},t,{placement:e})):n,s=r[0],a=r[1];return s=s||0,a=(a||0)*i,[D,k].indexOf(o)>=0?{x:a,y:s}:{x:s,y:a}}(n,t.rects,r),e}),{}),a=s[t.placement],l=a.x,c=a.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=l,t.modifiersData.popperOffsets.y+=c),t.modifiersData[o]=s}};var Q={left:"right",right:"left",bottom:"top",top:"bottom"};function X(e){return e.replace(/left|right|bottom|top/g,(function(e){return Q[e]}))}var ee={start:"end",end:"start"};function te(e){return e.replace(/start|end/g,(function(e){return ee[e]}))}function ne(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&s(n)){var o=t;do{if(o&&e.isSameNode(o))return!0;o=o.parentNode||o.host}while(o)}return!1}function oe(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function ie(e,t,n){return t===q?oe(function(e,t){var n=o(e),i=m(e),r=n.visualViewport,s=i.clientWidth,a=i.clientHeight,l=0,c=0;if(r){s=r.width,a=r.height;var d=u();(d||!d&&"fixed"===t)&&(l=r.offsetLeft,c=r.offsetTop)}return{width:s,height:a,x:l+g(e),y:c}}(e,n)):i(t)?function(e,t){var n=p(e,!1,"fixed"===t);return n.top=n.top+e.clientTop,n.left=n.left+e.clientLeft,n.bottom=n.top+e.clientHeight,n.right=n.left+e.clientWidth,n.width=e.clientWidth,n.height=e.clientHeight,n.x=n.left,n.y=n.top,n}(t,n):oe(function(e){var t,n=m(e),o=h(e),i=null==(t=e.ownerDocument)?void 0:t.body,r=a(n.scrollWidth,n.clientWidth,i?i.scrollWidth:0,i?i.clientWidth:0),s=a(n.scrollHeight,n.clientHeight,i?i.scrollHeight:0,i?i.clientHeight:0),l=-o.scrollLeft+g(e),c=-o.scrollTop;return"rtl"===v(i||n).direction&&(l+=a(n.clientWidth,i?i.clientWidth:0)-r),{width:r,height:s,x:l,y:c}}(m(e)))}function re(e,t,n,o){var s="clippingParents"===t?function(e){var t=A(w(e)),n=["absolute","fixed"].indexOf(v(e).position)>=0&&r(e)?O(e):e;return i(n)?t.filter((function(e){return i(e)&&ne(e,n)&&"body"!==f(e)})):[]}(e):[].concat(t),c=[].concat(s,[n]),d=c[0],u=c.reduce((function(t,n){var i=ie(e,n,o);return t.top=a(i.top,t.top),t.right=l(i.right,t.right),t.bottom=l(i.bottom,t.bottom),t.left=a(i.left,t.left),t}),ie(e,d,o));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function se(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function ae(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function le(e,t){void 0===t&&(t={});var n=t,o=n.placement,r=void 0===o?e.placement:o,s=n.strategy,a=void 0===s?e.strategy:s,l=n.boundary,c=void 0===l?"clippingParents":l,d=n.rootBoundary,u=void 0===d?q:d,h=n.elementContext,f=void 0===h?R:h,g=n.altBoundary,v=void 0!==g&&g,_=n.padding,y=void 0===_?0:_,b=se("number"!=typeof y?y:ae(y,P)),w=f===R?"reference":R,x=e.rects.popper,A=e.elements[v?w:f],C=re(i(A)?A:A.contextElement||m(e.elements.popper),c,u,a),$=p(e.elements.reference),O=K({reference:$,element:x,strategy:"absolute",placement:r}),D=oe(Object.assign({},x,O)),L=f===R?D:$,T={top:C.top-L.top+b.top,bottom:L.bottom-C.bottom+b.bottom,left:C.left-L.left+b.left,right:L.right-C.right+b.right},j=e.modifiersData.offset;if(f===R&&j){var M=j[r];Object.keys(T).forEach((function(e){var t=[k,E].indexOf(e)>=0?1:-1,n=[S,E].indexOf(e)>=0?"y":"x";T[e]+=M[n]*t}))}return T}function ce(e,t,n){return a(e,l(t,n))}const de={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,o=e.name,i=n.mainAxis,r=void 0===i||i,s=n.altAxis,c=void 0!==s&&s,d=n.boundary,u=n.rootBoundary,p=n.altBoundary,h=n.padding,f=n.tether,m=void 0===f||f,g=n.tetherOffset,v=void 0===g?0:g,_=le(t,{boundary:d,rootBoundary:u,padding:h,altBoundary:p}),y=G(t.placement),w=F(t.placement),x=!w,A=Y(y),C="x"===A?"y":"x",$=t.modifiersData.popperOffsets,L=t.rects.reference,P=t.rects.popper,j="function"==typeof v?v(Object.assign({},t.rects,{placement:t.placement})):v,q="number"==typeof j?{mainAxis:j,altAxis:j}:Object.assign({mainAxis:0,altAxis:0},j),R=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,M={x:0,y:0};if($){if(r){var I,H="y"===A?S:D,z="y"===A?E:k,U="y"===A?"height":"width",B=$[A],N=B+_[H],W=B-_[z],K=m?-P[U]/2:0,V=w===T?L[U]:P[U],Z=w===T?-P[U]:-L[U],J=t.elements.arrow,Q=m&&J?b(J):{width:0,height:0},X=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},ee=X[H],te=X[z],ne=ce(0,L[U],Q[U]),oe=x?L[U]/2-K-ne-ee-q.mainAxis:V-ne-ee-q.mainAxis,ie=x?-L[U]/2+K+ne+te+q.mainAxis:Z+ne+te+q.mainAxis,re=t.elements.arrow&&O(t.elements.arrow),se=re?"y"===A?re.clientTop||0:re.clientLeft||0:0,ae=null!=(I=null==R?void 0:R[A])?I:0,de=B+ie-ae,ue=ce(m?l(N,B+oe-ae-se):N,B,m?a(W,de):W);$[A]=ue,M[A]=ue-B}if(c){var pe,he="x"===A?S:D,fe="x"===A?E:k,me=$[C],ge="y"===C?"height":"width",ve=me+_[he],_e=me-_[fe],ye=-1!==[S,D].indexOf(y),be=null!=(pe=null==R?void 0:R[C])?pe:0,we=ye?ve:me-L[ge]-P[ge]-be+q.altAxis,xe=ye?me+L[ge]+P[ge]-be-q.altAxis:_e,Ae=m&&ye?function(e,t,n){var o=ce(e,t,n);return o>n?n:o}(we,me,xe):ce(m?we:ve,me,m?xe:_e);$[C]=Ae,M[C]=Ae-me}t.modifiersData[o]=M}},requiresIfExists:["offset"]};const ue={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,o=e.name,i=e.options,r=n.elements.arrow,s=n.modifiersData.popperOffsets,a=G(n.placement),l=Y(a),c=[D,k].indexOf(a)>=0?"height":"width";if(r&&s){var d=function(e,t){return se("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:ae(e,P))}(i.padding,n),u=b(r),p="y"===l?S:D,h="y"===l?E:k,f=n.rects.reference[c]+n.rects.reference[l]-s[l]-n.rects.popper[c],m=s[l]-n.rects.reference[l],g=O(r),v=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,_=f/2-m/2,y=d[p],w=v-u[c]-d[h],x=v/2-u[c]/2+_,A=ce(y,x,w),C=l;n.modifiersData[o]=((t={})[C]=A,t.centerOffset=A-x,t)}},effect:function(e){var t=e.state,n=e.options.element,o=void 0===n?"[data-popper-arrow]":n;null!=o&&("string"!=typeof o||(o=t.elements.popper.querySelector(o)))&&ne(t.elements.popper,o)&&(t.elements.arrow=o)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function pe(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function he(e){return[S,k,E,D].some((function(t){return e[t]>=0}))}var fe=N({defaultModifiers:[{name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var t=e.state,n=e.instance,i=e.options,r=i.scroll,s=void 0===r||r,a=i.resize,l=void 0===a||a,c=o(t.elements.popper),d=[].concat(t.scrollParents.reference,t.scrollParents.popper);return s&&d.forEach((function(e){e.addEventListener("scroll",n.update,W)})),l&&c.addEventListener("resize",n.update,W),function(){s&&d.forEach((function(e){e.removeEventListener("scroll",n.update,W)})),l&&c.removeEventListener("resize",n.update,W)}},data:{}},{name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,n=e.name;t.modifiersData[n]=K({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}},{name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options,o=n.gpuAcceleration,i=void 0===o||o,r=n.adaptive,s=void 0===r||r,a=n.roundOffsets,l=void 0===a||a,c={placement:G(t.placement),variation:F(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:i,isFixed:"fixed"===t.options.strategy};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,Z(Object.assign({},c,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:s,roundOffsets:l})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,Z(Object.assign({},c,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}},{name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},o=t.attributes[e]||{},i=t.elements[e];r(i)&&f(i)&&(Object.assign(i.style,n),Object.keys(o).forEach((function(e){var t=o[e];!1===t?i.removeAttribute(e):i.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var o=t.elements[e],i=t.attributes[e]||{},s=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{});r(o)&&f(o)&&(Object.assign(o.style,s),Object.keys(i).forEach((function(e){o.removeAttribute(e)})))}))}},requires:["computeStyles"]},J,{name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,o=e.name;if(!t.modifiersData[o]._skip){for(var i=n.mainAxis,r=void 0===i||i,s=n.altAxis,a=void 0===s||s,l=n.fallbackPlacements,c=n.padding,d=n.boundary,u=n.rootBoundary,p=n.altBoundary,h=n.flipVariations,f=void 0===h||h,m=n.allowedAutoPlacements,g=t.options.placement,v=G(g),_=l||(v===g||!f?[X(g)]:function(e){if(G(e)===L)return[];var t=X(e);return[te(e),t,te(t)]}(g)),y=[g].concat(_).reduce((function(e,n){return e.concat(G(n)===L?function(e,t){void 0===t&&(t={});var n=t,o=n.placement,i=n.boundary,r=n.rootBoundary,s=n.padding,a=n.flipVariations,l=n.allowedAutoPlacements,c=void 0===l?I:l,d=F(o),u=d?a?M:M.filter((function(e){return F(e)===d})):P,p=u.filter((function(e){return c.indexOf(e)>=0}));0===p.length&&(p=u);var h=p.reduce((function(t,n){return t[n]=le(e,{placement:n,boundary:i,rootBoundary:r,padding:s})[G(n)],t}),{});return Object.keys(h).sort((function(e,t){return h[e]-h[t]}))}(t,{placement:n,boundary:d,rootBoundary:u,padding:c,flipVariations:f,allowedAutoPlacements:m}):n)}),[]),b=t.rects.reference,w=t.rects.popper,x=new Map,A=!0,C=y[0],$=0;$<y.length;$++){var O=y[$],j=G(O),q=F(O)===T,R=[S,E].indexOf(j)>=0,H=R?"width":"height",z=le(t,{placement:O,boundary:d,rootBoundary:u,altBoundary:p,padding:c}),U=R?q?k:D:q?E:S;b[H]>w[H]&&(U=X(U));var B=X(U),N=[];if(r&&N.push(z[j]<=0),a&&N.push(z[U]<=0,z[B]<=0),N.every((function(e){return e}))){C=O,A=!1;break}x.set(O,N)}if(A)for(var W=function(e){var t=y.find((function(t){var n=x.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return C=t,"break"},Y=f?3:1;Y>0;Y--){if("break"===W(Y))break}t.placement!==C&&(t.modifiersData[o]._skip=!0,t.placement=C,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}},de,ue,{name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,o=t.rects.reference,i=t.rects.popper,r=t.modifiersData.preventOverflow,s=le(t,{elementContext:"reference"}),a=le(t,{altBoundary:!0}),l=pe(s,o),c=pe(a,i,r),d=he(l),u=he(c);t.modifiersData[n]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:d,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":d,"data-popper-escaped":u})}}]}),me=n(113);function ge(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function ve(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ge(Object(n),!0).forEach((function(t){_e(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ge(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function _e(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var o=n.call(e,t||"default");if("object"!=typeof o)return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class ye{static register(){let e=document.querySelectorAll(".cs-tooltip, [data-tooltip-target], [data-tooltip]");e.length&&e.forEach((e=>{new ye(e)}))}constructor(e,t={}){_e(this,"uuid",void 0),_e(this,"forElement",void 0),_e(this,"popperInstance",void 0),_e(this,"element",void 0),_e(this,"options",void 0),this.uuid=(0,me.G)(),this.forElement=this.updateTooltipTargetElement(e),this.options=Object.assign({theme:"dark",html:!0,container:"body",mainClass:"shapla-tooltip",activeClass:"is-active",removeOnClose:!0},t),this.popperInstance=null,this.init()}init(){["mouseenter","focus"].forEach((e=>{this.forElement.addEventListener(e,(()=>this.show()))})),["mouseleave","blur"].forEach((e=>{this.forElement.addEventListener(e,(()=>this.hide()))}))}show(){this.createTooltipElementIfNotExists(),this.element?.classList.add(this.options.activeClass),this.popperInstance=fe(this.forElement,this.element,{modifiers:[{name:"offset",options:{offset:[0,8]}}]}),this.popperInstance.setOptions((e=>ve(ve({},e),{},{modifiers:[...e.modifiers,{name:"eventListeners",enabled:!0}]}))),this.popperInstance.update()}hide(){this.element?.classList.remove(this.options.activeClass),this.popperInstance&&this.popperInstance.setOptions((e=>ve(ve({},e),{},{modifiers:[...e.modifiers,{name:"eventListeners",enabled:!1}]}))),this.options.removeOnClose&&setTimeout((()=>this.element?.remove()),10)}createTooltipElementIfNotExists(){if(this.element=document.querySelector(`[data-tooltip-for="${this.uuid}"]`),!this.element){let e=this.forElement.getAttribute("data-tooltip")||this.forElement.getAttribute("title");this.element=this.createTooltipElement(e)}}createTooltipElement(e){let t=(0,me.a)("div",{"data-popper-arrow":"",class:this.options.mainClass+"__arrow"}),n=(0,me.a)("div",{class:this.options.mainClass+"__inner"});this.options.html?n.innerHTML=e:n.innerText=e;let o=(0,me.a)("div",{"data-tooltip-for":this.uuid,"data-remove-on-close":"",role:"tooltip",class:`${this.options.mainClass} is-theme-${this.options.theme}`},[t,n]);return document.querySelector(this.options.container).appendChild(o),o}updateTooltipTargetElement(e){let t=e.getAttribute("data-tooltip")||e.getAttribute("title");return e.setAttribute("aria-describedby","tooltip"),e.setAttribute("data-tooltip-target",this.uuid),e.setAttribute("data-tooltip",t),e.hasAttribute("title")&&e.removeAttribute("title"),e}}const be=ye;n(271),n(776);let we,xe,Ae,Ce,$e,Oe,Se=t()("body"),Ee=t()("#contentButtonModal");const ke=window.CarouselSliderL10n.nonce??"",De=window.CarouselSliderL10n.l10n;Se.on("click",".carousel-slider__add-slide",(function(e){e.preventDefault(),t().ajax({url:ajaxurl,method:"POST",data:{action:"add_content_slide",task:"add-slide",nonce:ke,post_id:t()(this).data("post-id")},success:function(){window.location.reload(!0)}})})),Se.on("click",".carousel_slider__delete_slide",(function(e){e.preventDefault(),confirm(De.confirmDelete)&&t().ajax({url:ajaxurl,method:"POST",data:{action:"add_content_slide",task:"delete-slide",nonce:ke,post_id:t()(this).data("post-id"),slide_pos:t()(this).data("slide-pos")},success:function(){window.location.reload(!0)}})})),Se.on("click",".carousel_slider__move_top",(function(e){e.preventDefault(),t().ajax({url:ajaxurl,method:"POST",data:{action:"add_content_slide",task:"move-slide-top",nonce:ke,post_id:t()(this).data("post-id"),slide_pos:t()(this).data("slide-pos")},success:function(){window.location.reload(!0)}})})),Se.on("click",".carousel_slider__move_up",(function(e){e.preventDefault(),t().ajax({url:ajaxurl,method:"POST",data:{action:"add_content_slide",task:"move-slide-up",nonce:ke,post_id:t()(this).data("post-id"),slide_pos:t()(this).data("slide-pos")},success:function(){window.location.reload(!0)}})})),Se.on("click",".carousel_slider__move_down",(function(e){e.preventDefault(),t().ajax({url:ajaxurl,method:"POST",data:{action:"add_content_slide",task:"move-slide-down",nonce:ke,post_id:t()(this).data("post-id"),slide_pos:t()(this).data("slide-pos")},success:function(){window.location.reload(!0)}})})),Se.on("click",".carousel_slider__move_bottom",(function(e){e.preventDefault(),t().ajax({url:ajaxurl,method:"POST",data:{action:"add_content_slide",task:"move-slide-bottom",nonce:ke,post_id:t()(this).data("post-id"),slide_pos:t()(this).data("slide-pos")},success:function(){window.location.reload(!0)}})})),Se.on("click",".slide_image_add",(function(e){e.preventDefault();var n=t()(this);xe=n.closest(".slide_bg_wrapper"),Ce=xe.find(".content_slide_canvas"),Ae=xe.find(".background_image_id"),$e=xe.find(".delete-bg-img"),we||(we=wp.media({title:n.data("title"),button:{text:n.data("button-text")},multiple:!1}),we.on("select",(function(){var e=we.state().get("selection").first().toJSON();Ce.css("background-image","url("+e.url+")"),Ae.val(e.id),$e.removeClass("hidden")}))),we.open()})),Se.on("click",".delete-bg-img",(function(e){e.preventDefault(),xe=t()(this).closest(".slide_bg_wrapper"),Ce=xe.find(".content_slide_canvas"),Ae=xe.find(".background_image_id"),$e=xe.find(".delete-bg-img"),Ce.css("background-image",""),Ae.val("0"),$e.addClass("hidden")})),Se.on("change",".background_image_position",(function(){var e=t()(this).val();xe=t()(this).closest(".slide_bg_wrapper"),Ce=xe.find(".content_slide_canvas"),Ce.css("background-position",e)})),Se.on("change",".background_image_size",(function(){var e=t()(this).val();xe=t()(this).closest(".slide_bg_wrapper"),Ce=xe.find(".content_slide_canvas"),Ce.css("background-size",e)})),t()(".addContentButton").on("click",(function(e){e.preventDefault(),Oe=t()(this).closest(".button_config");var n=Oe.find(".button_text").val(),o=Oe.find(".button_url").val(),i=Oe.find(".button_target").val(),r=Oe.find(".button_type").val(),s=Oe.find(".button_size").val(),a=Oe.find(".button_color").val();Ee.find("#_button_text").val(n),Ee.find("#_button_url").val(o),Ee.find("#_button_target").val(i),Ee.find("#_button_type").val(r),Ee.find("#_button_size").val(s),Ee.find("#_button_color").val(a),Ee.addClass("is-active")})),t()("#saveContentButton").on("click",(function(e){if(e.preventDefault(),!Oe)return Ee.removeClass("is-active"),!1;var t=Ee.find("#_button_text").val(),n=Ee.find("#_button_url").val(),o=Ee.find("#_button_target").val(),i=Ee.find("#_button_type").val(),r=Ee.find("#_button_size").val(),s=Ee.find("#_button_color").val();Oe.find(".button_text").val(t),Oe.find(".button_url").val(n),Oe.find(".button_target").val(o),Oe.find(".button_type").val(i),Oe.find(".button_size").val(r),Oe.find(".button_color").val(s),Ee.removeClass("is-active")})),t()(".slide-color-picker").each((function(){xe=t()(this).closest(".slide_bg_wrapper"),Ce=xe.find(".content_slide_canvas"),t()(this).wpColorPicker({change:function(e,t){Ce.css("background-color",t.color.toString())}})})),t()(document).on("change",".link_type",(function(e){var n=t()(this),o=n.val(),i=n.closest(".tab-content-link"),r=i.find(".ContentCarouselLinkFull"),s=i.find(".ContentCarouselLinkButtons");"full"===o?(s.hide(),r.show()):"button"===o?(r.hide(),s.show()):(r.hide(),s.hide())}));let Le,Pe=t()("#carousel_slider_gallery_btn"),Te=Me(Pe.data("ids"));const je=(e,n)=>{t()("#_carousel_slider_images_ids").val(e),t()(".carousel_slider_gallery_list").html(n),document.body.dispatchEvent(new CustomEvent("CarouselSlider.refresh.preview"))};Pe.on("click",(function(e){e.preventDefault();let t={title:Pe.data("create"),state:"gallery-edit",frame:"post",selection:Te};(Le||Te)&&(t.title=Pe.data("edit")),Le=wp.media(t).open(),Le.menu.get("view").unset("cancel"),Le.menu.get("view").unset("separateCancel"),Le.menu.get("view").get("gallery-edit").el.innerHTML=Pe.data("edit"),Le.content.get("view").sidebar.unset("gallery"),Re(),Le.on("toolbar:render:gallery-edit",(function(){Re()})),Le.on("content:render:browse",(function(e){e&&(e.sidebar.on("ready",(function(){e.sidebar.unset("gallery")})),e.toolbar.on("ready",(function(){"gallery-library"===e.toolbar.controller._state&&e.toolbar.$el.hide()})))})),Le.state().get("library").on("remove",(function(){0===Le.state().get("library").length&&(Te=!1,je("",""))}))}));const qe=()=>{let e=Le.state().get("library"),t=[],n="";e.each((function(e){t.push(e.id);let o=e.attributes.sizes.thumbnail||e.attributes.sizes.full;n+=`<li><img src="${o.url}" width="50" height="50" class="attachment-50x50 size-50x50" loading="lazy"></li>`})),Te=Me(t.toString()),Le.close(),je(t.toString(),n)};function Re(){Le.toolbar.get("view").set({insert:{style:"primary",text:Pe.data("save"),click:()=>qe()}})}function Me(e){if(!e)return!1;"string"!=typeof e&&(e=e.toString());let t=new wp.shortcode({tag:"gallery",attrs:{ids:e},type:"single"}),n=wp.media.gallery.attachments(t),o=new wp.media.model.Selection(n.models,{props:n.props.toJSON(),multiple:!0});return o.gallery=n.gallery,o.more().done((function(){o.props.set({query:!1}),o.unmirror(),o.props.unset("orderby")})),o}const Ie=window.CarouselSliderAdminL10n,He=document.querySelector("#CarouselSliderModal");let ze=`<div class="media-url--column shapla-column is-12">\n<div class="carousel_slider-fields media-url-form-field">\n\t<div class="media-url-form-field__content">\n\t\t<label class="setting media-url-form-field__item">\n\t\t\t<span class="name">${Ie.url}</span>\n\t\t\t<input type="url" name="_images_urls[url][]" value="" autocomplete="off">\n\t\t</label>\n\t\t<label class="setting media-url-form-field__item">\n\t\t\t<span class="name">${Ie.title}</span>\n\t\t\t<input type="text" name="_images_urls[title][]" value="" autocomplete="off">\n\t\t</label>\n\t\t<label class="setting media-url-form-field__item">\n\t\t\t<span class="name">${Ie.caption}</span>\n\t\t\t<textarea name="_images_urls[caption][]"></textarea>\n\t\t</label>\n\t\t<label class="setting media-url-form-field__item">\n\t\t\t<span class="name">${Ie.altText}</span>\n\t\t\t<input type="text" name="_images_urls[alt][]" value="" autocomplete="off">\n\t\t</label>\n\t\t<label class="setting media-url-form-field__item">\n\t\t\t<span class="name">${Ie.linkToUrl}</span>\n\t\t\t<input type="text" name="_images_urls[link_url][]" value="" autocomplete="off">\n\t\t</label>\n\t</div>\n\t<div class="media-url-form-field__actions">\n\t\t<span class="move_row"><span class="dashicons dashicons-move"></span></span>\n\t\t<span class="add_row"><span class="dashicons dashicons-plus-alt"></span></span>\n\t\t<span class="delete_row"><span class="dashicons dashicons-trash"></span></span>\n\t</div>\n</div>\n</div>`;t()(document).on("click","#_images_urls_btn",(e=>{e.preventDefault(),t()("body").addClass("overflowHidden"),He&&He.setAttribute("open","")})),He&&He.addEventListener("close",(()=>{t()("body").removeClass("overflowHidden"),He.removeAttribute("open")})),t()(document).on("click",".add_row",(function(e){e.preventDefault();let n=t()("#CarouselSliderModal"),o=t()(this).closest(".media-url--column");if(o.length)o.after(ze);else{let e=n.find(".media-url--column");e.length?e.last().after(ze):n.find("#carousel_slider_form").prepend(ze)}})),t()(document).on("click",".delete_row",(function(){confirm("Are you sure to delete?")&&t()(this).closest(".media-url--column").remove()})),t()("#carousel_slider_form").sortable();const Ue=()=>{let e=t()("#_post_query_type").val(),n=t()("#field-_post_date_after"),o=t()("#field-_post_date_before"),i=t()("#field-_post_categories"),r=t()("#field-_post_tags"),s=t()("#field-_post_in"),a=t()("#field-_posts_per_page");n.hide("fast"),o.hide("fast"),i.hide("fast"),r.hide("fast"),s.hide("fast"),a.show("fast"),"date_range"===e&&(n.slideDown(),o.slideDown()),"post_categories"===e&&i.slideDown(),"post_tags"===e&&r.slideDown(),"specific_posts"===e&&(s.slideDown(),a.hide("fast"))};t()("#_post_query_type").on("change",(()=>Ue())),t()(document).ready((()=>Ue()));const Be=()=>{let e=t()("#_product_query_type").val(),n=t()("#field-_product_query"),o=t()("#field-_product_categories"),i=t()("#field-_product_tags"),r=t()("#field-_product_in"),s=t()("#field-_products_per_page");n.hide("fast"),o.hide("fast"),i.hide("fast"),r.hide("fast"),s.show("fast"),"query_product"===e&&n.slideDown(),"product_categories"===e&&o.slideDown(),"product_tags"===e&&i.slideDown(),"specific_products"===e&&(r.slideDown(),s.hide("fast"))};t()("#_product_query_type").on("change",(()=>Be())),t()(document).ready((()=>Be()));const Ne=window.CarouselSliderAdminL10n.videoCarousel,We="carousel_slider-fields--video-urls",Ge=`<div class="carousel_slider-fields--video-urls shapla-column is-12 is-6-fullhd">\n    <div class="carousel_slider-fields media-url-form-field">\n      <div class="media-url-form-field__content">\n          <label class="setting media-url-form-field__item">\n              <span class="name">${Ne.YoutubeOrVimeoURL}</span>\n              <input type="url" name="_video_urls[]" value="" autocomplete="off" \n              placeholder="https://www.youtube.com/watch?v=UOYK79yVrJ4">\n          </label>\n      </div>\n      <div class="media-url-form-field__actions flex-direction-row">\n          <span class="sort_video_url_row"><span class="dashicons dashicons-move"></span></span>\n          <span class="add_video_url_row"><span class="dashicons dashicons-plus-alt"></span></span>\n          <span class="delete_video_url_row"><span class="dashicons dashicons-trash"></span></span>\n      </div>\n    </div>\n</div>`;t()(document).on("click",".add_video_url_row",(function(e){e.preventDefault();let n=t()("#carousel-slider-video-carousel-urls"),o=t()(this).closest(`.${We}`);if(o.length)o.after(Ge);else{let e=n.find(`.${We}`);e.length?e.last().after(Ge):n.prepend(Ge)}})),t()(document).on("click",".delete_video_url_row",(function(){confirm(`${Ne.AreYouSureToDelete}`)&&t()(this).closest(`.${We}`).remove()})),t().fn.sortable&&t()("#carousel-slider-video-carousel-urls").sortable({handle:".sort_video_url_row",placeholder:"cs-sortable-state-highlight shapla-column is-12 is-6-fullhd"});n(294),n(913),n(639);let Fe=document.querySelectorAll(".cs-tooltip");Fe.length&&Fe.forEach((e=>new be(e,{theme:"light"}))),t()(".color-picker").each((function(){t()(this).wpColorPicker()})),t()("select.select2").each((function(){t()(this).select2()})),t()(".shapla-toggle").each((function(){"closed"===t()(this).attr("data-id")?t()(this).accordion({collapsible:!0,heightStyle:"content",active:!1}):t()(this).accordion({collapsible:!0,heightStyle:"content"})})),t()(".shapla-tabs").tabs({hide:{effect:"fadeOut",duration:200},show:{effect:"fadeIn",duration:200}}),document.querySelectorAll(".input-copy-to-clipboard").forEach((e=>{e.addEventListener("click",(()=>{navigator.permissions.query({name:"clipboard-write"}).then((t=>{"granted"===t.state||"prompt"===t.state?navigator.clipboard.writeText(e.innerHTML).then((()=>{window.console.log("Copied successfully")})).catch((e=>{window.console.log("Fail to copy",e)})):window.console.log("ClipBoard API status: "+t.state)}))}))}));const Ye=e=>{let t=document.querySelector("#field-_slides_per_view");t.style.display="slider"===e?"none":"block"},Ke=e=>{let t=document.querySelector("#field-_auto_width");t.style.display="slider"===e?"none":"block"};document.querySelectorAll('[name="carousel_slider[_type_of_slider]"]').forEach((e=>{e.addEventListener("change",(e=>{Ye(e.target.value),Ke(e.target.value)}))})),document.addEventListener("DOMContentLoaded",(()=>{let e=document.querySelector('[name="carousel_slider[_type_of_slider]"]:checked');e&&(Ye(e.value),Ke(e.value));let t=document.querySelector('[type="checkbox"][name="carousel_slider[_auto_width]"]:checked');t&&Ye(t?"slider":"carousel")})),document.querySelectorAll('[type="checkbox"][name="carousel_slider[_auto_width]"]').forEach((e=>{e.addEventListener("change",(e=>{Ye(e.target.checked?"slider":"carousel")}))}))})()})();assets/js/frontend-v2.js000064400000367507151727276560011230 0ustar00(()=>{var e={926:()=>{class e extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"});const t=document.createElement("style");t.textContent=e.getStyle(),this.shadowRoot.append(t,this.getElement())}getElement(){const e=document.createElement("button");return e.classList.add("shapla-cross"),this.hasAttribute("size")&&e.classList.add(`is-${this.getAttribute("size")}`),e}attributeChangedCallback(e,t,s){const a=this.shadowRoot.querySelector("button");"size"===e&&this.hasAttribute("size")&&a.classList.add(`is-${this.getAttribute("size")}`)}static get observedAttributes(){return["size"]}static getStyle(){return'.shapla-cross {\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  background-color: var(--delete-icon-background, hsla(0, 0%, 4%, .2));\n  border: none;\n  border-radius: 290486px;\n  cursor: pointer;\n  display: inline-block;\n  flex-grow: 0;\n  flex-shrink: 0;\n  font-size: 0;\n  height: var(--delete-icon-size, 20px);\n  outline: none;\n  pointer-events: auto;\n  position: relative;\n  -webkit-user-select: none;\n  user-select: none;\n  vertical-align: top;\n  width: var(--delete-icon-size, 20px)\n}\n\n.shapla-cross:after, .shapla-cross:before {\n  background-color: var(--delete-icon-color, #fff);\n  content: "";\n  display: block;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translateX(-50%) translateY(-50%) rotate(45deg);\n  transform-origin: center center\n}\n\n.shapla-cross:before {\n  height: 2px;\n  width: 50%\n}\n\n.shapla-cross:after {\n  height: 50%;\n  width: 2px\n}\n\n.shapla-cross:focus, .shapla-cross:hover {\n  background-color: var(--delete-icon-background-dark, hsla(0, 0%, 4%, .3))\n}\n\n.shapla-cross:active {\n  box-shadow: 0 3px 4px 0 rgba(0, 0, 0, .14), 0 3px 3px -2px rgba(0, 0, 0, .2), 0 1px 8px 0 rgba(0, 0, 0, .12)\n}\n\n.shapla-cross.is-small {\n  --delete-icon-size: 16px\n}\n\n.shapla-cross.is-medium {\n  --delete-icon-size: 24px\n}\n\n.shapla-cross.is-large {\n  --delete-icon-size: 32px\n}\n\n.shapla-cross.is-error {\n  --delete-icon-background: var(--shapla-error, #dc3545);\n  --delete-icon-background-dark: var(--shapla-error-variant, #d32535);\n  --delete-icon-color: var(--shapla-on-error, #fff)\n}'}}customElements.define("shapla-cross",e)}},t={};function s(a){var i=t[a];if(void 0!==i)return i.exports;var r=t[a]={exports:{}};return e[a](r,r.exports,s),r.exports}(()=>{"use strict";s(926);const e=(e,t={},s=[])=>{let a=document.createElement(e);return Object.keys(t).length&&Object.entries(t).forEach((([e,t])=>{a.setAttribute(e,t)})),s.length&&a.append(...s),a};class t extends HTMLElement{el(t,s={},a=[]){return e(t,s,a)}triggerCustomEvent(e){this.dispatchEvent(new CustomEvent(e))}}const a=t;class i extends a{constructor(){super(),this.attachShadow({mode:"open"});const e=document.createElement("style");e.textContent=i.getStyle(),this.shadowRoot.append(e,...this.getWrapperTemplate())}attributeChangedCallback(e,t,s){const a=this.shadowRoot.querySelector(".shapla-modal");if("open"===e&&this.hasAttribute("open")?a.classList.add("is-active"):a.classList.remove("is-active"),"type"===e){const e=this.shadowRoot.querySelector(".shapla-modal-content");"box"===s&&(e.classList.contains("shapla-modal-box")||e.classList.add("shapla-modal-box"))}}static get observedAttributes(){return["open","type"]}connectedCallback(){const e=this.getAttribute("type");if("card"===e){this.renderCardTemplate();const e=this.shadowRoot.querySelector(".shapla-modal-card__footer");e.querySelector("slot").assignedNodes().length<1&&e.classList.add("no-content")}"confirm"===e&&this.updateConfirmDom();const t=this.shadowRoot.querySelector(".shapla-modal-close.is-fixed"),s=this.shadowRoot.querySelector(".shapla-modal-content");"confirm"===e?(t.remove(),s.classList.add("shapla-modal-confirm"),s.innerHTML="",s.append(...this.getConfirmTemplate())):"box"===e&&s.classList.add("shapla-modal-box");const a=this.shadowRoot.querySelector(".shapla-modal-background"),i=this.getAttribute("backdrop-theme");-1!==["dark","light"].indexOf(i)&&a.classList.add(`is-${i}`),this.updateContentSize(),this.closeOnEscape(),this.closeOnBackdropClick(),this.closeOnCrossClick()}renderCardTemplate(){const e=this.shadowRoot.querySelector(".shapla-modal-close.is-fixed"),t=this.shadowRoot.querySelector(".shapla-modal-content");e.remove(),t.classList.add("shapla-modal-card"),t.innerHTML="",t.append(...this.getCartTemplate());const s=this.getAttribute("heading");s&&(this.shadowRoot.querySelector(".shapla-modal-card__title").innerHTML=s)}updateContentSize(){const e=this.getAttribute("content-size");-1!==["small","medium","large","full","custom"].indexOf(e)&&this.shadowRoot.querySelector(".shapla-modal-content").classList.add(`is-${e}`)}updateConfirmDom(){const e=this.getAttribute("icon")??"primary",t=this.getAttribute("heading"),s=this.getAttribute("message")??"Are you sure?",a=this.getAttribute("confirm-button")??"Ok",i=this.getAttribute("cancel-button")??"Cancel",r=this.shadowRoot.querySelector(".button--confirm"),n=this.shadowRoot.querySelector(".button--cancel");a&&(r.innerHTML=a),i&&(n.innerHTML=i);const l=this.shadowRoot.querySelector(".shapla-modal-confirm");-1!==["primary","success","error"].indexOf(e)&&l.querySelector(".shapla-modal-confirm__icon")?.classList.add(`is-${e}`),this.hasAttribute("content-size")||(this.setAttribute("content-size","small"),this.updateContentSize()),this.hasAttribute("disabled-backdrop-click")||this.setAttribute("disabled-backdrop-click",""),t.length&&(l.querySelector(".shapla-modal-confirm__title").innerHTML=t),s.length&&(l.querySelector(".shapla-modal-confirm__message").innerHTML=s),this.closeOnCrossClick()}closeOnCrossClick(){(this.shadowRoot.querySelectorAll(".shapla-modal-close, .button--cancel")||[]).forEach((e=>{e.addEventListener("click",(()=>this.triggerCloseEvent()))}))}closeOnBackdropClick(){const e=this.shadowRoot.querySelector(".shapla-modal-background");this.hasAttribute("disabled-backdrop-click")||"confirm"!==this.getAttribute("type")&&e.addEventListener("click",(()=>this.triggerCloseEvent()))}closeOnEscape(){document.addEventListener("keydown",(e=>{27===(e||window.event).keyCode&&this.hasAttribute("open")&&this.triggerCloseEvent()}))}triggerCloseEvent(){this.triggerCustomEvent("close")}getWrapperTemplate(){return[this.el("div",{class:"shapla-modal"},[this.el("div",{class:"shapla-modal-background"}),this.el("shapla-cross",{class:"shapla-modal-close is-fixed",size:"large"}),this.el("div",{class:"shapla-modal-content"},[this.el("slot")])])]}getCartTemplate(){return[this.el("header",{class:"shapla-modal-card__header"},[this.el("div",{class:"shapla-modal-card__title"},[this.el("slot",{name:"heading"})]),this.el("shapla-cross",{class:"shapla-modal-close",size:"medium"})]),this.el("section",{class:"shapla-modal-card__body"},[this.el("slot")]),this.el("footer",{class:"shapla-modal-card__footer is-pulled-right"},[this.el("slot",{name:"footer"})])]}getConfirmTemplate(){return[this.el("div",{class:"shapla-modal-confirm__content"},[this.el("div",{class:"shapla-modal-confirm__icon"},[this.el("div",{class:"shapla-modal-confirm__icon-content"},["!"])]),this.el("h3",{class:"shapla-modal-confirm__title"}),this.el("div",{class:"shapla-modal-confirm__message"})]),this.el("div",{class:"shapla-modal-confirm__actions"},[this.el("slot",{name:"actions"},[this.el("button",{class:"shapla-button button--cancel"}),this.el("button",{class:"shapla-button is-primary button--confirm"})])])]}static getStyle(){return".shapla-modal,.shapla-modal-background{bottom:0;left:0;position:absolute;right:0;top:0}\n    .shapla-modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;\n    position:fixed;z-index:var(--modal-z-index,100000)}\n    .shapla-modal.is-active{display:flex}\n    .shapla-modal-background{background-color:var(--modal-backdrop-color,rgba(0,0,0,.5))}\n    .shapla-modal-background.is-light{--modal-backdrop-color:var(--modal-backdrop-color-light,hsla(0,0%,100%,.5))}\n    .shapla-modal .shapla-delete-icon.is-fixed,.shapla-modal .shapla-modal-close.is-fixed{\n    position:fixed;right:var(--modal-close-right,1.25rem);top:var(--modal-close-top,1.25rem)}\n    .shapla-modal-content{margin:0 var(--modal-content-margin,20px);\n    max-height:calc(100vh - var(--modal-content-spacing, 160px));overflow:auto;position:relative;\n    width:var(--modal-content-width,calc(100% - var(--modal-content-margin, 20px)*2))}\n    .shapla-modal-content.is-small{--modal-content-width:var(--modal-content-width-small,320px)}\n    .shapla-modal-content.is-full{height:calc(100vh - var(--modal-content-margin, 20px)*2);\n    width:calc(100vw - var(--modal-content-margin, 20px)*2)}\n    @media print,screen and (min-width:768px){\n    .shapla-modal-content{--modal-content-spacing:40px;margin:0 auto}\n    .shapla-modal-content:not(.is-small):not(.is-full):not(.is-large){\n    --modal-content-width:var(--modal-content-width-medium,640px)}}\n    @media screen and (min-width:1024px){\n    .shapla-modal-content.is-large{--modal-content-width:var(--modal-content-width-large,960px)}}\n    .shapla-modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden}\n    .shapla-modal-card__footer,.shapla-modal-card__header{align-items:center;background-color:#fff;display:flex;\n    flex-shrink:0;justify-content:flex-start;padding:1rem;position:relative}\n    .shapla-modal-card__footer>*+*,.shapla-modal-card__header>*+*{margin-left:.5rem}\n    .shapla-modal-card__header{border-bottom:1px solid rgba(0,0,0,.12);border-top-left-radius:4px;\n    border-top-right-radius:4px}\n    .shapla-modal-card__title{flex-grow:1;flex-shrink:0;font-size:1.5rem;font-weight:400;line-height:1;margin:0}\n    .shapla-modal-card__footer{border-bottom-left-radius:4px;border-bottom-right-radius:4px;\n    border-top:1px solid rgba(0,0,0,.12)}\n    .shapla-modal-card__footer.is-pulled-right{justify-content:flex-end}\n    .shapla-modal-card__footer.no-content{border-top:none;padding:2px}\n    .shapla-modal-card__body{background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:1rem}\n    .shapla-modal-box,.shapla-modal-confirm{background-color:#fff;border-radius:4px;\n    box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2);padding:1rem}\n    .shapla-modal-confirm__content{padding:1rem;text-align:center}\n    .shapla-modal-confirm__icon{border:.25em solid var(--shapla-primary,#0d6efd);border-radius:50%;\n    color:var(--shapla-primary,#0d6efd);cursor:default;display:flex;height:5em;justify-content:center;\n    margin:1.25em auto 1.875em;-webkit-user-select:none;user-select:none;width:5em}\n    .shapla-modal-confirm__icon.is-success{border-color:var(--shapla-success,#198754);color:var(--shapla-success,#198754)}\n    .shapla-modal-confirm__icon.is-error{border-color:var(--shapla-error,#dc3545);color:var(--shapla-error,#dc3545)}\n    .shapla-modal-confirm__icon-content{align-items:center;display:flex;font-size:3.75em}\n    .shapla-modal-confirm__title{font-size:1.875em;margin:0 0 .4em;text-align:center}\n    .shapla-modal-confirm__actions{display:flex;justify-content:center;padding:1rem}\n    .shapla-modal-confirm__actions>*+*{margin-left:.5rem}"}}customElements.define("shapla-dialog",i);class r extends a{constructor(){super(),this.attachShadow({mode:"open"});const e=document.createElement("style");e.textContent=r.getStyle();let t=this.getElement();this.hasAttribute("rounded")&&t.classList.add("is-rounded"),this.hasAttribute("width")||t.classList.add("is-fullwidth"),t.innerHTML=this.innerHTML,this.shadowRoot.append(e,t),this.getDynamicStyle()}getElement(){return this.el("div",{class:"shapla-aspect-ratio"})}getDynamicStyle(){let e=this.getAttribute("width"),t=this.getAttribute("height"),s=this.getAttribute("width-ratio")??"1",a=this.getAttribute("height-ratio")??"1";const i=this.shadowRoot.querySelector(".shapla-aspect-ratio");i&&(this.hasAttribute("width")?(i.style.width=e,i.style.height=t||e):(i.style.paddingTop=100/parseInt(s)*parseInt(a)+"%",i.style.width="100%"))}static getStyle(){return".shapla-aspect-ratio {  display: block;  position: relative;}\n.shapla-aspect-ratio.is-rounded > * {  border-radius: 290486px;}\n.shapla-aspect-ratio > * {  display: block;  bottom: 0;  left: 0;  position: absolute;  right: 0;  top: 0; height: 100%;  width: 100%;}"}}function n(e){return null!==e&&"object"==typeof e&&"constructor"in e&&e.constructor===Object}function l(e,t){void 0===e&&(e={}),void 0===t&&(t={});const s=["__proto__","constructor","prototype"];Object.keys(t).filter((e=>s.indexOf(e)<0)).forEach((s=>{void 0===e[s]?e[s]=t[s]:n(t[s])&&n(e[s])&&Object.keys(t[s]).length>0&&l(e[s],t[s])}))}customElements.define("shapla-aspect-ratio",r);const o={body:{},addEventListener(){},removeEventListener(){},activeElement:{blur(){},nodeName:""},querySelector:()=>null,querySelectorAll:()=>[],getElementById:()=>null,createEvent:()=>({initEvent(){}}),createElement:()=>({children:[],childNodes:[],style:{},setAttribute(){},getElementsByTagName:()=>[]}),createElementNS:()=>({}),importNode:()=>null,location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""}};function d(){const e="undefined"!=typeof document?document:{};return l(e,o),e}const c={document:o,navigator:{userAgent:""},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""},history:{replaceState(){},pushState(){},go(){},back(){}},CustomEvent:function(){return this},addEventListener(){},removeEventListener(){},getComputedStyle:()=>({getPropertyValue:()=>""}),Image(){},Date(){},screen:{},setTimeout(){},clearTimeout(){},matchMedia:()=>({}),requestAnimationFrame:e=>"undefined"==typeof setTimeout?(e(),null):setTimeout(e,0),cancelAnimationFrame(e){"undefined"!=typeof setTimeout&&clearTimeout(e)}};function p(){const e="undefined"!=typeof window?window:{};return l(e,c),e}function u(e){return void 0===e&&(e=""),e.trim().split(" ").filter((e=>!!e.trim()))}function m(e,t){return void 0===t&&(t=0),setTimeout(e,t)}function h(){return Date.now()}function f(e,t){void 0===t&&(t="x");const s=p();let a,i,r;const n=function(e){const t=p();let s;return t.getComputedStyle&&(s=t.getComputedStyle(e,null)),!s&&e.currentStyle&&(s=e.currentStyle),s||(s=e.style),s}(e);return s.WebKitCSSMatrix?(i=n.transform||n.webkitTransform,i.split(",").length>6&&(i=i.split(", ").map((e=>e.replace(",","."))).join(", ")),r=new s.WebKitCSSMatrix("none"===i?"":i)):(r=n.MozTransform||n.OTransform||n.MsTransform||n.msTransform||n.transform||n.getPropertyValue("transform").replace("translate(","matrix(1, 0, 0, 1,"),a=r.toString().split(",")),"x"===t&&(i=s.WebKitCSSMatrix?r.m41:16===a.length?parseFloat(a[12]):parseFloat(a[4])),"y"===t&&(i=s.WebKitCSSMatrix?r.m42:16===a.length?parseFloat(a[13]):parseFloat(a[5])),i||0}function g(e){return"object"==typeof e&&null!==e&&e.constructor&&"Object"===Object.prototype.toString.call(e).slice(8,-1)}function v(){const e=Object(arguments.length<=0?void 0:arguments[0]),t=["__proto__","constructor","prototype"];for(let a=1;a<arguments.length;a+=1){const i=a<0||arguments.length<=a?void 0:arguments[a];if(null!=i&&(s=i,!("undefined"!=typeof window&&void 0!==window.HTMLElement?s instanceof HTMLElement:s&&(1===s.nodeType||11===s.nodeType)))){const s=Object.keys(Object(i)).filter((e=>t.indexOf(e)<0));for(let t=0,a=s.length;t<a;t+=1){const a=s[t],r=Object.getOwnPropertyDescriptor(i,a);void 0!==r&&r.enumerable&&(g(e[a])&&g(i[a])?i[a].__swiper__?e[a]=i[a]:v(e[a],i[a]):!g(e[a])&&g(i[a])?(e[a]={},i[a].__swiper__?e[a]=i[a]:v(e[a],i[a])):e[a]=i[a])}}}var s;return e}function b(e,t,s){e.style.setProperty(t,s)}function w(e){let{swiper:t,targetPosition:s,side:a}=e;const i=p(),r=-t.translate;let n,l=null;const o=t.params.speed;t.wrapperEl.style.scrollSnapType="none",i.cancelAnimationFrame(t.cssModeFrameID);const d=s>r?"next":"prev",c=(e,t)=>"next"===d&&e>=t||"prev"===d&&e<=t,u=()=>{n=(new Date).getTime(),null===l&&(l=n);const e=Math.max(Math.min((n-l)/o,1),0),d=.5-Math.cos(e*Math.PI)/2;let p=r+d*(s-r);if(c(p,s)&&(p=s),t.wrapperEl.scrollTo({[a]:p}),c(p,s))return t.wrapperEl.style.overflow="hidden",t.wrapperEl.style.scrollSnapType="",setTimeout((()=>{t.wrapperEl.style.overflow="",t.wrapperEl.scrollTo({[a]:p})})),void i.cancelAnimationFrame(t.cssModeFrameID);t.cssModeFrameID=i.requestAnimationFrame(u)};u()}function y(e){return e.querySelector(".swiper-slide-transform")||e.shadowRoot&&e.shadowRoot.querySelector(".swiper-slide-transform")||e}function x(e,t){void 0===t&&(t="");const s=p(),a=[...e.children];return s.HTMLSlotElement&&e instanceof HTMLSlotElement&&a.push(...e.assignedElements()),t?a.filter((e=>e.matches(t))):a}function S(e){try{return void console.warn(e)}catch(e){}}function T(e,t){void 0===t&&(t=[]);const s=document.createElement(e);return s.classList.add(...Array.isArray(t)?t:u(t)),s}function E(e){const t=p(),s=d(),a=e.getBoundingClientRect(),i=s.body,r=e.clientTop||i.clientTop||0,n=e.clientLeft||i.clientLeft||0,l=e===t?t.scrollY:e.scrollTop,o=e===t?t.scrollX:e.scrollLeft;return{top:a.top+l-r,left:a.left+o-n}}function M(e,t){return p().getComputedStyle(e,null).getPropertyValue(t)}function C(e){let t,s=e;if(s){for(t=0;null!==(s=s.previousSibling);)1===s.nodeType&&(t+=1);return t}}function L(e,t){const s=[];let a=e.parentElement;for(;a;)t?a.matches(t)&&s.push(a):s.push(a),a=a.parentElement;return s}function P(e,t,s){const a=p();return s?e["width"===t?"offsetWidth":"offsetHeight"]+parseFloat(a.getComputedStyle(e,null).getPropertyValue("width"===t?"margin-right":"margin-top"))+parseFloat(a.getComputedStyle(e,null).getPropertyValue("width"===t?"margin-left":"margin-bottom")):e.offsetWidth}function k(e){return(Array.isArray(e)?e:[e]).filter((e=>!!e))}function O(e){return t=>Math.abs(t)>0&&e.browser&&e.browser.need3dFix&&Math.abs(t)%90==0?t+.001:t}let A,z,I;function $(){return A||(A=function(){const e=p(),t=d();return{smoothScroll:t.documentElement&&t.documentElement.style&&"scrollBehavior"in t.documentElement.style,touch:!!("ontouchstart"in e||e.DocumentTouch&&t instanceof e.DocumentTouch)}}()),A}function D(e){return void 0===e&&(e={}),z||(z=function(e){let{userAgent:t}=void 0===e?{}:e;const s=$(),a=p(),i=a.navigator.platform,r=t||a.navigator.userAgent,n={ios:!1,android:!1},l=a.screen.width,o=a.screen.height,d=r.match(/(Android);?[\s\/]+([\d.]+)?/);let c=r.match(/(iPad).*OS\s([\d_]+)/);const u=r.match(/(iPod)(.*OS\s([\d_]+))?/),m=!c&&r.match(/(iPhone\sOS|iOS)\s([\d_]+)/),h="Win32"===i;let f="MacIntel"===i;return!c&&f&&s.touch&&["1024x1366","1366x1024","834x1194","1194x834","834x1112","1112x834","768x1024","1024x768","820x1180","1180x820","810x1080","1080x810"].indexOf(`${l}x${o}`)>=0&&(c=r.match(/(Version)\/([\d.]+)/),c||(c=[0,1,"13_0_0"]),f=!1),d&&!h&&(n.os="android",n.android=!0),(c||m||u)&&(n.os="ios",n.ios=!0),n}(e)),z}function _(){return I||(I=function(){const e=p(),t=D();let s=!1;function a(){const t=e.navigator.userAgent.toLowerCase();return t.indexOf("safari")>=0&&t.indexOf("chrome")<0&&t.indexOf("android")<0}if(a()){const t=String(e.navigator.userAgent);if(t.includes("Version/")){const[e,a]=t.split("Version/")[1].split(" ")[0].split(".").map((e=>Number(e)));s=e<16||16===e&&a<2}}const i=/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(e.navigator.userAgent),r=a();return{isSafari:s||r,needPerspectiveFix:s,need3dFix:r||i&&t.ios,isWebView:i}}()),I}var G={on(e,t,s){const a=this;if(!a.eventsListeners||a.destroyed)return a;if("function"!=typeof t)return a;const i=s?"unshift":"push";return e.split(" ").forEach((e=>{a.eventsListeners[e]||(a.eventsListeners[e]=[]),a.eventsListeners[e][i](t)})),a},once(e,t,s){const a=this;if(!a.eventsListeners||a.destroyed)return a;if("function"!=typeof t)return a;function i(){a.off(e,i),i.__emitterProxy&&delete i.__emitterProxy;for(var s=arguments.length,r=new Array(s),n=0;n<s;n++)r[n]=arguments[n];t.apply(a,r)}return i.__emitterProxy=t,a.on(e,i,s)},onAny(e,t){const s=this;if(!s.eventsListeners||s.destroyed)return s;if("function"!=typeof e)return s;const a=t?"unshift":"push";return s.eventsAnyListeners.indexOf(e)<0&&s.eventsAnyListeners[a](e),s},offAny(e){const t=this;if(!t.eventsListeners||t.destroyed)return t;if(!t.eventsAnyListeners)return t;const s=t.eventsAnyListeners.indexOf(e);return s>=0&&t.eventsAnyListeners.splice(s,1),t},off(e,t){const s=this;return!s.eventsListeners||s.destroyed?s:s.eventsListeners?(e.split(" ").forEach((e=>{void 0===t?s.eventsListeners[e]=[]:s.eventsListeners[e]&&s.eventsListeners[e].forEach(((a,i)=>{(a===t||a.__emitterProxy&&a.__emitterProxy===t)&&s.eventsListeners[e].splice(i,1)}))})),s):s},emit(){const e=this;if(!e.eventsListeners||e.destroyed)return e;if(!e.eventsListeners)return e;let t,s,a;for(var i=arguments.length,r=new Array(i),n=0;n<i;n++)r[n]=arguments[n];"string"==typeof r[0]||Array.isArray(r[0])?(t=r[0],s=r.slice(1,r.length),a=e):(t=r[0].events,s=r[0].data,a=r[0].context||e),s.unshift(a);return(Array.isArray(t)?t:t.split(" ")).forEach((t=>{e.eventsAnyListeners&&e.eventsAnyListeners.length&&e.eventsAnyListeners.forEach((e=>{e.apply(a,[t,...s])})),e.eventsListeners&&e.eventsListeners[t]&&e.eventsListeners[t].forEach((e=>{e.apply(a,s)}))})),e}};const H=(e,t,s)=>{t&&!e.classList.contains(s)?e.classList.add(s):!t&&e.classList.contains(s)&&e.classList.remove(s)};const q=(e,t,s)=>{t&&!e.classList.contains(s)?e.classList.add(s):!t&&e.classList.contains(s)&&e.classList.remove(s)};const B=(e,t)=>{if(!e||e.destroyed||!e.params)return;const s=t.closest(e.isElement?"swiper-slide":`.${e.params.slideClass}`);if(s){let t=s.querySelector(`.${e.params.lazyPreloaderClass}`);!t&&e.isElement&&(s.shadowRoot?t=s.shadowRoot.querySelector(`.${e.params.lazyPreloaderClass}`):requestAnimationFrame((()=>{s.shadowRoot&&(t=s.shadowRoot.querySelector(`.${e.params.lazyPreloaderClass}`),t&&t.remove())}))),t&&t.remove()}},N=(e,t)=>{if(!e.slides[t])return;const s=e.slides[t].querySelector('[loading="lazy"]');s&&s.removeAttribute("loading")},R=e=>{if(!e||e.destroyed||!e.params)return;let t=e.params.lazyPreloadPrevNext;const s=e.slides.length;if(!s||!t||t<0)return;t=Math.min(t,s);const a="auto"===e.params.slidesPerView?e.slidesPerViewDynamic():Math.ceil(e.params.slidesPerView),i=e.activeIndex;if(e.params.grid&&e.params.grid.rows>1){const s=i,r=[s-t];return r.push(...Array.from({length:t}).map(((e,t)=>s+a+t))),void e.slides.forEach(((t,s)=>{r.includes(t.column)&&N(e,s)}))}const r=i+a-1;if(e.params.rewind||e.params.loop)for(let a=i-t;a<=r+t;a+=1){const t=(a%s+s)%s;(t<i||t>r)&&N(e,t)}else for(let a=Math.max(i-t,0);a<=Math.min(r+t,s-1);a+=1)a!==i&&(a>r||a<i)&&N(e,a)};var F={updateSize:function(){const e=this;let t,s;const a=e.el;t=void 0!==e.params.width&&null!==e.params.width?e.params.width:a.clientWidth,s=void 0!==e.params.height&&null!==e.params.height?e.params.height:a.clientHeight,0===t&&e.isHorizontal()||0===s&&e.isVertical()||(t=t-parseInt(M(a,"padding-left")||0,10)-parseInt(M(a,"padding-right")||0,10),s=s-parseInt(M(a,"padding-top")||0,10)-parseInt(M(a,"padding-bottom")||0,10),Number.isNaN(t)&&(t=0),Number.isNaN(s)&&(s=0),Object.assign(e,{width:t,height:s,size:e.isHorizontal()?t:s}))},updateSlides:function(){const e=this;function t(t,s){return parseFloat(t.getPropertyValue(e.getDirectionLabel(s))||0)}const s=e.params,{wrapperEl:a,slidesEl:i,size:r,rtlTranslate:n,wrongRTL:l}=e,o=e.virtual&&s.virtual.enabled,d=o?e.virtual.slides.length:e.slides.length,c=x(i,`.${e.params.slideClass}, swiper-slide`),p=o?e.virtual.slides.length:c.length;let u=[];const m=[],h=[];let f=s.slidesOffsetBefore;"function"==typeof f&&(f=s.slidesOffsetBefore.call(e));let g=s.slidesOffsetAfter;"function"==typeof g&&(g=s.slidesOffsetAfter.call(e));const v=e.snapGrid.length,w=e.slidesGrid.length;let y=s.spaceBetween,S=-f,T=0,E=0;if(void 0===r)return;"string"==typeof y&&y.indexOf("%")>=0?y=parseFloat(y.replace("%",""))/100*r:"string"==typeof y&&(y=parseFloat(y)),e.virtualSize=-y,c.forEach((e=>{n?e.style.marginLeft="":e.style.marginRight="",e.style.marginBottom="",e.style.marginTop=""})),s.centeredSlides&&s.cssMode&&(b(a,"--swiper-centered-offset-before",""),b(a,"--swiper-centered-offset-after",""));const C=s.grid&&s.grid.rows>1&&e.grid;let L;C?e.grid.initSlides(c):e.grid&&e.grid.unsetSlides();const k="auto"===s.slidesPerView&&s.breakpoints&&Object.keys(s.breakpoints).filter((e=>void 0!==s.breakpoints[e].slidesPerView)).length>0;for(let a=0;a<p;a+=1){let i;if(L=0,c[a]&&(i=c[a]),C&&e.grid.updateSlide(a,i,c),!c[a]||"none"!==M(i,"display")){if("auto"===s.slidesPerView){k&&(c[a].style[e.getDirectionLabel("width")]="");const r=getComputedStyle(i),n=i.style.transform,l=i.style.webkitTransform;if(n&&(i.style.transform="none"),l&&(i.style.webkitTransform="none"),s.roundLengths)L=e.isHorizontal()?P(i,"width",!0):P(i,"height",!0);else{const e=t(r,"width"),s=t(r,"padding-left"),a=t(r,"padding-right"),n=t(r,"margin-left"),l=t(r,"margin-right"),o=r.getPropertyValue("box-sizing");if(o&&"border-box"===o)L=e+n+l;else{const{clientWidth:t,offsetWidth:r}=i;L=e+s+a+n+l+(r-t)}}n&&(i.style.transform=n),l&&(i.style.webkitTransform=l),s.roundLengths&&(L=Math.floor(L))}else L=(r-(s.slidesPerView-1)*y)/s.slidesPerView,s.roundLengths&&(L=Math.floor(L)),c[a]&&(c[a].style[e.getDirectionLabel("width")]=`${L}px`);c[a]&&(c[a].swiperSlideSize=L),h.push(L),s.centeredSlides?(S=S+L/2+T/2+y,0===T&&0!==a&&(S=S-r/2-y),0===a&&(S=S-r/2-y),Math.abs(S)<.001&&(S=0),s.roundLengths&&(S=Math.floor(S)),E%s.slidesPerGroup==0&&u.push(S),m.push(S)):(s.roundLengths&&(S=Math.floor(S)),(E-Math.min(e.params.slidesPerGroupSkip,E))%e.params.slidesPerGroup==0&&u.push(S),m.push(S),S=S+L+y),e.virtualSize+=L+y,T=L,E+=1}}if(e.virtualSize=Math.max(e.virtualSize,r)+g,n&&l&&("slide"===s.effect||"coverflow"===s.effect)&&(a.style.width=`${e.virtualSize+y}px`),s.setWrapperSize&&(a.style[e.getDirectionLabel("width")]=`${e.virtualSize+y}px`),C&&e.grid.updateWrapperSize(L,u),!s.centeredSlides){const t=[];for(let a=0;a<u.length;a+=1){let i=u[a];s.roundLengths&&(i=Math.floor(i)),u[a]<=e.virtualSize-r&&t.push(i)}u=t,Math.floor(e.virtualSize-r)-Math.floor(u[u.length-1])>1&&u.push(e.virtualSize-r)}if(o&&s.loop){const t=h[0]+y;if(s.slidesPerGroup>1){const a=Math.ceil((e.virtual.slidesBefore+e.virtual.slidesAfter)/s.slidesPerGroup),i=t*s.slidesPerGroup;for(let e=0;e<a;e+=1)u.push(u[u.length-1]+i)}for(let a=0;a<e.virtual.slidesBefore+e.virtual.slidesAfter;a+=1)1===s.slidesPerGroup&&u.push(u[u.length-1]+t),m.push(m[m.length-1]+t),e.virtualSize+=t}if(0===u.length&&(u=[0]),0!==y){const t=e.isHorizontal()&&n?"marginLeft":e.getDirectionLabel("marginRight");c.filter(((e,t)=>!(s.cssMode&&!s.loop)||t!==c.length-1)).forEach((e=>{e.style[t]=`${y}px`}))}if(s.centeredSlides&&s.centeredSlidesBounds){let e=0;h.forEach((t=>{e+=t+(y||0)})),e-=y;const t=e>r?e-r:0;u=u.map((e=>e<=0?-f:e>t?t+g:e))}if(s.centerInsufficientSlides){let e=0;h.forEach((t=>{e+=t+(y||0)})),e-=y;const t=(s.slidesOffsetBefore||0)+(s.slidesOffsetAfter||0);if(e+t<r){const s=(r-e-t)/2;u.forEach(((e,t)=>{u[t]=e-s})),m.forEach(((e,t)=>{m[t]=e+s}))}}if(Object.assign(e,{slides:c,snapGrid:u,slidesGrid:m,slidesSizesGrid:h}),s.centeredSlides&&s.cssMode&&!s.centeredSlidesBounds){b(a,"--swiper-centered-offset-before",-u[0]+"px"),b(a,"--swiper-centered-offset-after",e.size/2-h[h.length-1]/2+"px");const t=-e.snapGrid[0],s=-e.slidesGrid[0];e.snapGrid=e.snapGrid.map((e=>e+t)),e.slidesGrid=e.slidesGrid.map((e=>e+s))}if(p!==d&&e.emit("slidesLengthChange"),u.length!==v&&(e.params.watchOverflow&&e.checkOverflow(),e.emit("snapGridLengthChange")),m.length!==w&&e.emit("slidesGridLengthChange"),s.watchSlidesProgress&&e.updateSlidesOffset(),e.emit("slidesUpdated"),!(o||s.cssMode||"slide"!==s.effect&&"fade"!==s.effect)){const t=`${s.containerModifierClass}backface-hidden`,a=e.el.classList.contains(t);p<=s.maxBackfaceHiddenSlides?a||e.el.classList.add(t):a&&e.el.classList.remove(t)}},updateAutoHeight:function(e){const t=this,s=[],a=t.virtual&&t.params.virtual.enabled;let i,r=0;"number"==typeof e?t.setTransition(e):!0===e&&t.setTransition(t.params.speed);const n=e=>a?t.slides[t.getSlideIndexByData(e)]:t.slides[e];if("auto"!==t.params.slidesPerView&&t.params.slidesPerView>1)if(t.params.centeredSlides)(t.visibleSlides||[]).forEach((e=>{s.push(e)}));else for(i=0;i<Math.ceil(t.params.slidesPerView);i+=1){const e=t.activeIndex+i;if(e>t.slides.length&&!a)break;s.push(n(e))}else s.push(n(t.activeIndex));for(i=0;i<s.length;i+=1)if(void 0!==s[i]){const e=s[i].offsetHeight;r=e>r?e:r}(r||0===r)&&(t.wrapperEl.style.height=`${r}px`)},updateSlidesOffset:function(){const e=this,t=e.slides,s=e.isElement?e.isHorizontal()?e.wrapperEl.offsetLeft:e.wrapperEl.offsetTop:0;for(let a=0;a<t.length;a+=1)t[a].swiperSlideOffset=(e.isHorizontal()?t[a].offsetLeft:t[a].offsetTop)-s-e.cssOverflowAdjustment()},updateSlidesProgress:function(e){void 0===e&&(e=this&&this.translate||0);const t=this,s=t.params,{slides:a,rtlTranslate:i,snapGrid:r}=t;if(0===a.length)return;void 0===a[0].swiperSlideOffset&&t.updateSlidesOffset();let n=-e;i&&(n=e),t.visibleSlidesIndexes=[],t.visibleSlides=[];let l=s.spaceBetween;"string"==typeof l&&l.indexOf("%")>=0?l=parseFloat(l.replace("%",""))/100*t.size:"string"==typeof l&&(l=parseFloat(l));for(let e=0;e<a.length;e+=1){const o=a[e];let d=o.swiperSlideOffset;s.cssMode&&s.centeredSlides&&(d-=a[0].swiperSlideOffset);const c=(n+(s.centeredSlides?t.minTranslate():0)-d)/(o.swiperSlideSize+l),p=(n-r[0]+(s.centeredSlides?t.minTranslate():0)-d)/(o.swiperSlideSize+l),u=-(n-d),m=u+t.slidesSizesGrid[e],h=u>=0&&u<=t.size-t.slidesSizesGrid[e],f=u>=0&&u<t.size-1||m>1&&m<=t.size||u<=0&&m>=t.size;f&&(t.visibleSlides.push(o),t.visibleSlidesIndexes.push(e)),H(o,f,s.slideVisibleClass),H(o,h,s.slideFullyVisibleClass),o.progress=i?-c:c,o.originalProgress=i?-p:p}},updateProgress:function(e){const t=this;if(void 0===e){const s=t.rtlTranslate?-1:1;e=t&&t.translate&&t.translate*s||0}const s=t.params,a=t.maxTranslate()-t.minTranslate();let{progress:i,isBeginning:r,isEnd:n,progressLoop:l}=t;const o=r,d=n;if(0===a)i=0,r=!0,n=!0;else{i=(e-t.minTranslate())/a;const s=Math.abs(e-t.minTranslate())<1,l=Math.abs(e-t.maxTranslate())<1;r=s||i<=0,n=l||i>=1,s&&(i=0),l&&(i=1)}if(s.loop){const s=t.getSlideIndexByData(0),a=t.getSlideIndexByData(t.slides.length-1),i=t.slidesGrid[s],r=t.slidesGrid[a],n=t.slidesGrid[t.slidesGrid.length-1],o=Math.abs(e);l=o>=i?(o-i)/n:(o+n-r)/n,l>1&&(l-=1)}Object.assign(t,{progress:i,progressLoop:l,isBeginning:r,isEnd:n}),(s.watchSlidesProgress||s.centeredSlides&&s.autoHeight)&&t.updateSlidesProgress(e),r&&!o&&t.emit("reachBeginning toEdge"),n&&!d&&t.emit("reachEnd toEdge"),(o&&!r||d&&!n)&&t.emit("fromEdge"),t.emit("progress",i)},updateSlidesClasses:function(){const e=this,{slides:t,params:s,slidesEl:a,activeIndex:i}=e,r=e.virtual&&s.virtual.enabled,n=e.grid&&s.grid&&s.grid.rows>1,l=e=>x(a,`.${s.slideClass}${e}, swiper-slide${e}`)[0];let o,d,c;if(r)if(s.loop){let t=i-e.virtual.slidesBefore;t<0&&(t=e.virtual.slides.length+t),t>=e.virtual.slides.length&&(t-=e.virtual.slides.length),o=l(`[data-swiper-slide-index="${t}"]`)}else o=l(`[data-swiper-slide-index="${i}"]`);else n?(o=t.find((e=>e.column===i)),c=t.find((e=>e.column===i+1)),d=t.find((e=>e.column===i-1))):o=t[i];o&&(n||(c=function(e,t){const s=[];for(;e.nextElementSibling;){const a=e.nextElementSibling;t?a.matches(t)&&s.push(a):s.push(a),e=a}return s}(o,`.${s.slideClass}, swiper-slide`)[0],s.loop&&!c&&(c=t[0]),d=function(e,t){const s=[];for(;e.previousElementSibling;){const a=e.previousElementSibling;t?a.matches(t)&&s.push(a):s.push(a),e=a}return s}(o,`.${s.slideClass}, swiper-slide`)[0],s.loop&&0===!d&&(d=t[t.length-1]))),t.forEach((e=>{q(e,e===o,s.slideActiveClass),q(e,e===c,s.slideNextClass),q(e,e===d,s.slidePrevClass)})),e.emitSlidesClasses()},updateActiveIndex:function(e){const t=this,s=t.rtlTranslate?t.translate:-t.translate,{snapGrid:a,params:i,activeIndex:r,realIndex:n,snapIndex:l}=t;let o,d=e;const c=e=>{let s=e-t.virtual.slidesBefore;return s<0&&(s=t.virtual.slides.length+s),s>=t.virtual.slides.length&&(s-=t.virtual.slides.length),s};if(void 0===d&&(d=function(e){const{slidesGrid:t,params:s}=e,a=e.rtlTranslate?e.translate:-e.translate;let i;for(let e=0;e<t.length;e+=1)void 0!==t[e+1]?a>=t[e]&&a<t[e+1]-(t[e+1]-t[e])/2?i=e:a>=t[e]&&a<t[e+1]&&(i=e+1):a>=t[e]&&(i=e);return s.normalizeSlideIndex&&(i<0||void 0===i)&&(i=0),i}(t)),a.indexOf(s)>=0)o=a.indexOf(s);else{const e=Math.min(i.slidesPerGroupSkip,d);o=e+Math.floor((d-e)/i.slidesPerGroup)}if(o>=a.length&&(o=a.length-1),d===r&&!t.params.loop)return void(o!==l&&(t.snapIndex=o,t.emit("snapIndexChange")));if(d===r&&t.params.loop&&t.virtual&&t.params.virtual.enabled)return void(t.realIndex=c(d));const p=t.grid&&i.grid&&i.grid.rows>1;let u;if(t.virtual&&i.virtual.enabled&&i.loop)u=c(d);else if(p){const e=t.slides.find((e=>e.column===d));let s=parseInt(e.getAttribute("data-swiper-slide-index"),10);Number.isNaN(s)&&(s=Math.max(t.slides.indexOf(e),0)),u=Math.floor(s/i.grid.rows)}else if(t.slides[d]){const e=t.slides[d].getAttribute("data-swiper-slide-index");u=e?parseInt(e,10):d}else u=d;Object.assign(t,{previousSnapIndex:l,snapIndex:o,previousRealIndex:n,realIndex:u,previousIndex:r,activeIndex:d}),t.initialized&&R(t),t.emit("activeIndexChange"),t.emit("snapIndexChange"),(t.initialized||t.params.runCallbacksOnInit)&&(n!==u&&t.emit("realIndexChange"),t.emit("slideChange"))},updateClickedSlide:function(e,t){const s=this,a=s.params;let i=e.closest(`.${a.slideClass}, swiper-slide`);!i&&s.isElement&&t&&t.length>1&&t.includes(e)&&[...t.slice(t.indexOf(e)+1,t.length)].forEach((e=>{!i&&e.matches&&e.matches(`.${a.slideClass}, swiper-slide`)&&(i=e)}));let r,n=!1;if(i)for(let e=0;e<s.slides.length;e+=1)if(s.slides[e]===i){n=!0,r=e;break}if(!i||!n)return s.clickedSlide=void 0,void(s.clickedIndex=void 0);s.clickedSlide=i,s.virtual&&s.params.virtual.enabled?s.clickedIndex=parseInt(i.getAttribute("data-swiper-slide-index"),10):s.clickedIndex=r,a.slideToClickedSlide&&void 0!==s.clickedIndex&&s.clickedIndex!==s.activeIndex&&s.slideToClickedSlide()}};var V={getTranslate:function(e){void 0===e&&(e=this.isHorizontal()?"x":"y");const{params:t,rtlTranslate:s,translate:a,wrapperEl:i}=this;if(t.virtualTranslate)return s?-a:a;if(t.cssMode)return a;let r=f(i,e);return r+=this.cssOverflowAdjustment(),s&&(r=-r),r||0},setTranslate:function(e,t){const s=this,{rtlTranslate:a,params:i,wrapperEl:r,progress:n}=s;let l,o=0,d=0;s.isHorizontal()?o=a?-e:e:d=e,i.roundLengths&&(o=Math.floor(o),d=Math.floor(d)),s.previousTranslate=s.translate,s.translate=s.isHorizontal()?o:d,i.cssMode?r[s.isHorizontal()?"scrollLeft":"scrollTop"]=s.isHorizontal()?-o:-d:i.virtualTranslate||(s.isHorizontal()?o-=s.cssOverflowAdjustment():d-=s.cssOverflowAdjustment(),r.style.transform=`translate3d(${o}px, ${d}px, 0px)`);const c=s.maxTranslate()-s.minTranslate();l=0===c?0:(e-s.minTranslate())/c,l!==n&&s.updateProgress(e),s.emit("setTranslate",s.translate,t)},minTranslate:function(){return-this.snapGrid[0]},maxTranslate:function(){return-this.snapGrid[this.snapGrid.length-1]},translateTo:function(e,t,s,a,i){void 0===e&&(e=0),void 0===t&&(t=this.params.speed),void 0===s&&(s=!0),void 0===a&&(a=!0);const r=this,{params:n,wrapperEl:l}=r;if(r.animating&&n.preventInteractionOnTransition)return!1;const o=r.minTranslate(),d=r.maxTranslate();let c;if(c=a&&e>o?o:a&&e<d?d:e,r.updateProgress(c),n.cssMode){const e=r.isHorizontal();if(0===t)l[e?"scrollLeft":"scrollTop"]=-c;else{if(!r.support.smoothScroll)return w({swiper:r,targetPosition:-c,side:e?"left":"top"}),!0;l.scrollTo({[e?"left":"top"]:-c,behavior:"smooth"})}return!0}return 0===t?(r.setTransition(0),r.setTranslate(c),s&&(r.emit("beforeTransitionStart",t,i),r.emit("transitionEnd"))):(r.setTransition(t),r.setTranslate(c),s&&(r.emit("beforeTransitionStart",t,i),r.emit("transitionStart")),r.animating||(r.animating=!0,r.onTranslateToWrapperTransitionEnd||(r.onTranslateToWrapperTransitionEnd=function(e){r&&!r.destroyed&&e.target===this&&(r.wrapperEl.removeEventListener("transitionend",r.onTranslateToWrapperTransitionEnd),r.onTranslateToWrapperTransitionEnd=null,delete r.onTranslateToWrapperTransitionEnd,r.animating=!1,s&&r.emit("transitionEnd"))}),r.wrapperEl.addEventListener("transitionend",r.onTranslateToWrapperTransitionEnd))),!0}};function j(e){let{swiper:t,runCallbacks:s,direction:a,step:i}=e;const{activeIndex:r,previousIndex:n}=t;let l=a;if(l||(l=r>n?"next":r<n?"prev":"reset"),t.emit(`transition${i}`),s&&r!==n){if("reset"===l)return void t.emit(`slideResetTransition${i}`);t.emit(`slideChangeTransition${i}`),"next"===l?t.emit(`slideNextTransition${i}`):t.emit(`slidePrevTransition${i}`)}}var X={slideTo:function(e,t,s,a,i){void 0===e&&(e=0),void 0===s&&(s=!0),"string"==typeof e&&(e=parseInt(e,10));const r=this;let n=e;n<0&&(n=0);const{params:l,snapGrid:o,slidesGrid:d,previousIndex:c,activeIndex:p,rtlTranslate:u,wrapperEl:m,enabled:h}=r;if(!h&&!a&&!i||r.destroyed||r.animating&&l.preventInteractionOnTransition)return!1;void 0===t&&(t=r.params.speed);const f=Math.min(r.params.slidesPerGroupSkip,n);let g=f+Math.floor((n-f)/r.params.slidesPerGroup);g>=o.length&&(g=o.length-1);const v=-o[g];if(l.normalizeSlideIndex)for(let e=0;e<d.length;e+=1){const t=-Math.floor(100*v),s=Math.floor(100*d[e]),a=Math.floor(100*d[e+1]);void 0!==d[e+1]?t>=s&&t<a-(a-s)/2?n=e:t>=s&&t<a&&(n=e+1):t>=s&&(n=e)}if(r.initialized&&n!==p){if(!r.allowSlideNext&&(u?v>r.translate&&v>r.minTranslate():v<r.translate&&v<r.minTranslate()))return!1;if(!r.allowSlidePrev&&v>r.translate&&v>r.maxTranslate()&&(p||0)!==n)return!1}let b;n!==(c||0)&&s&&r.emit("beforeSlideChangeStart"),r.updateProgress(v),b=n>p?"next":n<p?"prev":"reset";const y=r.virtual&&r.params.virtual.enabled;if(!(y&&i)&&(u&&-v===r.translate||!u&&v===r.translate))return r.updateActiveIndex(n),l.autoHeight&&r.updateAutoHeight(),r.updateSlidesClasses(),"slide"!==l.effect&&r.setTranslate(v),"reset"!==b&&(r.transitionStart(s,b),r.transitionEnd(s,b)),!1;if(l.cssMode){const e=r.isHorizontal(),s=u?v:-v;if(0===t)y&&(r.wrapperEl.style.scrollSnapType="none",r._immediateVirtual=!0),y&&!r._cssModeVirtualInitialSet&&r.params.initialSlide>0?(r._cssModeVirtualInitialSet=!0,requestAnimationFrame((()=>{m[e?"scrollLeft":"scrollTop"]=s}))):m[e?"scrollLeft":"scrollTop"]=s,y&&requestAnimationFrame((()=>{r.wrapperEl.style.scrollSnapType="",r._immediateVirtual=!1}));else{if(!r.support.smoothScroll)return w({swiper:r,targetPosition:s,side:e?"left":"top"}),!0;m.scrollTo({[e?"left":"top"]:s,behavior:"smooth"})}return!0}const x=_().isSafari;return y&&!i&&x&&r.isElement&&r.virtual.update(!1,!1,n),r.setTransition(t),r.setTranslate(v),r.updateActiveIndex(n),r.updateSlidesClasses(),r.emit("beforeTransitionStart",t,a),r.transitionStart(s,b),0===t?r.transitionEnd(s,b):r.animating||(r.animating=!0,r.onSlideToWrapperTransitionEnd||(r.onSlideToWrapperTransitionEnd=function(e){r&&!r.destroyed&&e.target===this&&(r.wrapperEl.removeEventListener("transitionend",r.onSlideToWrapperTransitionEnd),r.onSlideToWrapperTransitionEnd=null,delete r.onSlideToWrapperTransitionEnd,r.transitionEnd(s,b))}),r.wrapperEl.addEventListener("transitionend",r.onSlideToWrapperTransitionEnd)),!0},slideToLoop:function(e,t,s,a){if(void 0===e&&(e=0),void 0===s&&(s=!0),"string"==typeof e){e=parseInt(e,10)}const i=this;if(i.destroyed)return;void 0===t&&(t=i.params.speed);const r=i.grid&&i.params.grid&&i.params.grid.rows>1;let n=e;if(i.params.loop)if(i.virtual&&i.params.virtual.enabled)n+=i.virtual.slidesBefore;else{let e;if(r){const t=n*i.params.grid.rows;e=i.slides.find((e=>1*e.getAttribute("data-swiper-slide-index")===t)).column}else e=i.getSlideIndexByData(n);const t=r?Math.ceil(i.slides.length/i.params.grid.rows):i.slides.length,{centeredSlides:s}=i.params;let l=i.params.slidesPerView;"auto"===l?l=i.slidesPerViewDynamic():(l=Math.ceil(parseFloat(i.params.slidesPerView,10)),s&&l%2==0&&(l+=1));let o=t-e<l;if(s&&(o=o||e<Math.ceil(l/2)),a&&s&&"auto"!==i.params.slidesPerView&&!r&&(o=!1),o){const a=s?e<i.activeIndex?"prev":"next":e-i.activeIndex-1<i.params.slidesPerView?"next":"prev";i.loopFix({direction:a,slideTo:!0,activeSlideIndex:"next"===a?e+1:e-t+1,slideRealIndex:"next"===a?i.realIndex:void 0})}if(r){const e=n*i.params.grid.rows;n=i.slides.find((t=>1*t.getAttribute("data-swiper-slide-index")===e)).column}else n=i.getSlideIndexByData(n)}return requestAnimationFrame((()=>{i.slideTo(n,t,s,a)})),i},slideNext:function(e,t,s){void 0===t&&(t=!0);const a=this,{enabled:i,params:r,animating:n}=a;if(!i||a.destroyed)return a;void 0===e&&(e=a.params.speed);let l=r.slidesPerGroup;"auto"===r.slidesPerView&&1===r.slidesPerGroup&&r.slidesPerGroupAuto&&(l=Math.max(a.slidesPerViewDynamic("current",!0),1));const o=a.activeIndex<r.slidesPerGroupSkip?1:l,d=a.virtual&&r.virtual.enabled;if(r.loop){if(n&&!d&&r.loopPreventsSliding)return!1;if(a.loopFix({direction:"next"}),a._clientLeft=a.wrapperEl.clientLeft,a.activeIndex===a.slides.length-1&&r.cssMode)return requestAnimationFrame((()=>{a.slideTo(a.activeIndex+o,e,t,s)})),!0}return r.rewind&&a.isEnd?a.slideTo(0,e,t,s):a.slideTo(a.activeIndex+o,e,t,s)},slidePrev:function(e,t,s){void 0===t&&(t=!0);const a=this,{params:i,snapGrid:r,slidesGrid:n,rtlTranslate:l,enabled:o,animating:d}=a;if(!o||a.destroyed)return a;void 0===e&&(e=a.params.speed);const c=a.virtual&&i.virtual.enabled;if(i.loop){if(d&&!c&&i.loopPreventsSliding)return!1;a.loopFix({direction:"prev"}),a._clientLeft=a.wrapperEl.clientLeft}function p(e){return e<0?-Math.floor(Math.abs(e)):Math.floor(e)}const u=p(l?a.translate:-a.translate),m=r.map((e=>p(e))),h=i.freeMode&&i.freeMode.enabled;let f=r[m.indexOf(u)-1];if(void 0===f&&(i.cssMode||h)){let e;r.forEach(((t,s)=>{u>=t&&(e=s)})),void 0!==e&&(f=h?r[e]:r[e>0?e-1:e])}let g=0;if(void 0!==f&&(g=n.indexOf(f),g<0&&(g=a.activeIndex-1),"auto"===i.slidesPerView&&1===i.slidesPerGroup&&i.slidesPerGroupAuto&&(g=g-a.slidesPerViewDynamic("previous",!0)+1,g=Math.max(g,0))),i.rewind&&a.isBeginning){const i=a.params.virtual&&a.params.virtual.enabled&&a.virtual?a.virtual.slides.length-1:a.slides.length-1;return a.slideTo(i,e,t,s)}return i.loop&&0===a.activeIndex&&i.cssMode?(requestAnimationFrame((()=>{a.slideTo(g,e,t,s)})),!0):a.slideTo(g,e,t,s)},slideReset:function(e,t,s){void 0===t&&(t=!0);const a=this;if(!a.destroyed)return void 0===e&&(e=a.params.speed),a.slideTo(a.activeIndex,e,t,s)},slideToClosest:function(e,t,s,a){void 0===t&&(t=!0),void 0===a&&(a=.5);const i=this;if(i.destroyed)return;void 0===e&&(e=i.params.speed);let r=i.activeIndex;const n=Math.min(i.params.slidesPerGroupSkip,r),l=n+Math.floor((r-n)/i.params.slidesPerGroup),o=i.rtlTranslate?i.translate:-i.translate;if(o>=i.snapGrid[l]){const e=i.snapGrid[l];o-e>(i.snapGrid[l+1]-e)*a&&(r+=i.params.slidesPerGroup)}else{const e=i.snapGrid[l-1];o-e<=(i.snapGrid[l]-e)*a&&(r-=i.params.slidesPerGroup)}return r=Math.max(r,0),r=Math.min(r,i.slidesGrid.length-1),i.slideTo(r,e,t,s)},slideToClickedSlide:function(){const e=this;if(e.destroyed)return;const{params:t,slidesEl:s}=e,a="auto"===t.slidesPerView?e.slidesPerViewDynamic():t.slidesPerView;let i,r=e.clickedIndex;const n=e.isElement?"swiper-slide":`.${t.slideClass}`;if(t.loop){if(e.animating)return;i=parseInt(e.clickedSlide.getAttribute("data-swiper-slide-index"),10),t.centeredSlides?r<e.loopedSlides-a/2||r>e.slides.length-e.loopedSlides+a/2?(e.loopFix(),r=e.getSlideIndex(x(s,`${n}[data-swiper-slide-index="${i}"]`)[0]),m((()=>{e.slideTo(r)}))):e.slideTo(r):r>e.slides.length-a?(e.loopFix(),r=e.getSlideIndex(x(s,`${n}[data-swiper-slide-index="${i}"]`)[0]),m((()=>{e.slideTo(r)}))):e.slideTo(r)}else e.slideTo(r)}};var Y={loopCreate:function(e,t){const s=this,{params:a,slidesEl:i}=s;if(!a.loop||s.virtual&&s.params.virtual.enabled)return;const r=()=>{x(i,`.${a.slideClass}, swiper-slide`).forEach(((e,t)=>{e.setAttribute("data-swiper-slide-index",t)}))},n=s.grid&&a.grid&&a.grid.rows>1,l=a.slidesPerGroup*(n?a.grid.rows:1),o=s.slides.length%l!=0,d=n&&s.slides.length%a.grid.rows!=0,c=e=>{for(let t=0;t<e;t+=1){const e=s.isElement?T("swiper-slide",[a.slideBlankClass]):T("div",[a.slideClass,a.slideBlankClass]);s.slidesEl.append(e)}};if(o){if(a.loopAddBlankSlides){c(l-s.slides.length%l),s.recalcSlides(),s.updateSlides()}else S("Swiper Loop Warning: The number of slides is not even to slidesPerGroup, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)");r()}else if(d){if(a.loopAddBlankSlides){c(a.grid.rows-s.slides.length%a.grid.rows),s.recalcSlides(),s.updateSlides()}else S("Swiper Loop Warning: The number of slides is not even to grid.rows, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)");r()}else r();s.loopFix({slideRealIndex:e,direction:a.centeredSlides?void 0:"next",initial:t})},loopFix:function(e){let{slideRealIndex:t,slideTo:s=!0,direction:a,setTranslate:i,activeSlideIndex:r,initial:n,byController:l,byMousewheel:o}=void 0===e?{}:e;const d=this;if(!d.params.loop)return;d.emit("beforeLoopFix");const{slides:c,allowSlidePrev:p,allowSlideNext:u,slidesEl:m,params:h}=d,{centeredSlides:f,initialSlide:g}=h;if(d.allowSlidePrev=!0,d.allowSlideNext=!0,d.virtual&&h.virtual.enabled)return s&&(h.centeredSlides||0!==d.snapIndex?h.centeredSlides&&d.snapIndex<h.slidesPerView?d.slideTo(d.virtual.slides.length+d.snapIndex,0,!1,!0):d.snapIndex===d.snapGrid.length-1&&d.slideTo(d.virtual.slidesBefore,0,!1,!0):d.slideTo(d.virtual.slides.length,0,!1,!0)),d.allowSlidePrev=p,d.allowSlideNext=u,void d.emit("loopFix");let v=h.slidesPerView;"auto"===v?v=d.slidesPerViewDynamic():(v=Math.ceil(parseFloat(h.slidesPerView,10)),f&&v%2==0&&(v+=1));const b=h.slidesPerGroupAuto?v:h.slidesPerGroup;let w=b;w%b!=0&&(w+=b-w%b),w+=h.loopAdditionalSlides,d.loopedSlides=w;const y=d.grid&&h.grid&&h.grid.rows>1;c.length<v+w||"cards"===d.params.effect&&c.length<v+2*w?S("Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled or not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters"):y&&"row"===h.grid.fill&&S("Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`");const x=[],T=[],E=y?Math.ceil(c.length/h.grid.rows):c.length,M=n&&E-g<v&&!f;let C=M?g:d.activeIndex;void 0===r?r=d.getSlideIndex(c.find((e=>e.classList.contains(h.slideActiveClass)))):C=r;const L="next"===a||!a,P="prev"===a||!a;let k=0,O=0;const A=(y?c[r].column:r)+(f&&void 0===i?-v/2+.5:0);if(A<w){k=Math.max(w-A,b);for(let e=0;e<w-A;e+=1){const t=e-Math.floor(e/E)*E;if(y){const e=E-t-1;for(let t=c.length-1;t>=0;t-=1)c[t].column===e&&x.push(t)}else x.push(E-t-1)}}else if(A+v>E-w){O=Math.max(A-(E-2*w),b),M&&(O=Math.max(O,v-E+g+1));for(let e=0;e<O;e+=1){const t=e-Math.floor(e/E)*E;y?c.forEach(((e,s)=>{e.column===t&&T.push(s)})):T.push(t)}}if(d.__preventObserver__=!0,requestAnimationFrame((()=>{d.__preventObserver__=!1})),"cards"===d.params.effect&&c.length<v+2*w&&(T.includes(r)&&T.splice(T.indexOf(r),1),x.includes(r)&&x.splice(x.indexOf(r),1)),P&&x.forEach((e=>{c[e].swiperLoopMoveDOM=!0,m.prepend(c[e]),c[e].swiperLoopMoveDOM=!1})),L&&T.forEach((e=>{c[e].swiperLoopMoveDOM=!0,m.append(c[e]),c[e].swiperLoopMoveDOM=!1})),d.recalcSlides(),"auto"===h.slidesPerView?d.updateSlides():y&&(x.length>0&&P||T.length>0&&L)&&d.slides.forEach(((e,t)=>{d.grid.updateSlide(t,e,d.slides)})),h.watchSlidesProgress&&d.updateSlidesOffset(),s)if(x.length>0&&P){if(void 0===t){const e=d.slidesGrid[C],t=d.slidesGrid[C+k]-e;o?d.setTranslate(d.translate-t):(d.slideTo(C+Math.ceil(k),0,!1,!0),i&&(d.touchEventsData.startTranslate=d.touchEventsData.startTranslate-t,d.touchEventsData.currentTranslate=d.touchEventsData.currentTranslate-t))}else if(i){const e=y?x.length/h.grid.rows:x.length;d.slideTo(d.activeIndex+e,0,!1,!0),d.touchEventsData.currentTranslate=d.translate}}else if(T.length>0&&L)if(void 0===t){const e=d.slidesGrid[C],t=d.slidesGrid[C-O]-e;o?d.setTranslate(d.translate-t):(d.slideTo(C-O,0,!1,!0),i&&(d.touchEventsData.startTranslate=d.touchEventsData.startTranslate-t,d.touchEventsData.currentTranslate=d.touchEventsData.currentTranslate-t))}else{const e=y?T.length/h.grid.rows:T.length;d.slideTo(d.activeIndex-e,0,!1,!0)}if(d.allowSlidePrev=p,d.allowSlideNext=u,d.controller&&d.controller.control&&!l){const e={slideRealIndex:t,direction:a,setTranslate:i,activeSlideIndex:r,byController:!0};Array.isArray(d.controller.control)?d.controller.control.forEach((t=>{!t.destroyed&&t.params.loop&&t.loopFix({...e,slideTo:t.params.slidesPerView===h.slidesPerView&&s})})):d.controller.control instanceof d.constructor&&d.controller.control.params.loop&&d.controller.control.loopFix({...e,slideTo:d.controller.control.params.slidesPerView===h.slidesPerView&&s})}d.emit("loopFix")},loopDestroy:function(){const e=this,{params:t,slidesEl:s}=e;if(!t.loop||!s||e.virtual&&e.params.virtual.enabled)return;e.recalcSlides();const a=[];e.slides.forEach((e=>{const t=void 0===e.swiperSlideIndex?1*e.getAttribute("data-swiper-slide-index"):e.swiperSlideIndex;a[t]=e})),e.slides.forEach((e=>{e.removeAttribute("data-swiper-slide-index")})),a.forEach((e=>{s.append(e)})),e.recalcSlides(),e.slideTo(e.realIndex,0)}};function W(e,t,s){const a=p(),{params:i}=e,r=i.edgeSwipeDetection,n=i.edgeSwipeThreshold;return!r||!(s<=n||s>=a.innerWidth-n)||"prevent"===r&&(t.preventDefault(),!0)}function U(e){const t=this,s=d();let a=e;a.originalEvent&&(a=a.originalEvent);const i=t.touchEventsData;if("pointerdown"===a.type){if(null!==i.pointerId&&i.pointerId!==a.pointerId)return;i.pointerId=a.pointerId}else"touchstart"===a.type&&1===a.targetTouches.length&&(i.touchId=a.targetTouches[0].identifier);if("touchstart"===a.type)return void W(t,a,a.targetTouches[0].pageX);const{params:r,touches:n,enabled:l}=t;if(!l)return;if(!r.simulateTouch&&"mouse"===a.pointerType)return;if(t.animating&&r.preventInteractionOnTransition)return;!t.animating&&r.cssMode&&r.loop&&t.loopFix();let o=a.target;if("wrapper"===r.touchEventsTarget&&!function(e,t){const s=p();let a=t.contains(e);!a&&s.HTMLSlotElement&&t instanceof HTMLSlotElement&&(a=[...t.assignedElements()].includes(e),a||(a=function(e,t){const s=[t];for(;s.length>0;){const t=s.shift();if(e===t)return!0;s.push(...t.children,...t.shadowRoot?t.shadowRoot.children:[],...t.assignedElements?t.assignedElements():[])}}(e,t)));return a}(o,t.wrapperEl))return;if("which"in a&&3===a.which)return;if("button"in a&&a.button>0)return;if(i.isTouched&&i.isMoved)return;const c=!!r.noSwipingClass&&""!==r.noSwipingClass,u=a.composedPath?a.composedPath():a.path;c&&a.target&&a.target.shadowRoot&&u&&(o=u[0]);const m=r.noSwipingSelector?r.noSwipingSelector:`.${r.noSwipingClass}`,f=!(!a.target||!a.target.shadowRoot);if(r.noSwiping&&(f?function(e,t){return void 0===t&&(t=this),function t(s){if(!s||s===d()||s===p())return null;s.assignedSlot&&(s=s.assignedSlot);const a=s.closest(e);return a||s.getRootNode?a||t(s.getRootNode().host):null}(t)}(m,o):o.closest(m)))return void(t.allowClick=!0);if(r.swipeHandler&&!o.closest(r.swipeHandler))return;n.currentX=a.pageX,n.currentY=a.pageY;const g=n.currentX,v=n.currentY;if(!W(t,a,g))return;Object.assign(i,{isTouched:!0,isMoved:!1,allowTouchCallbacks:!0,isScrolling:void 0,startMoving:void 0}),n.startX=g,n.startY=v,i.touchStartTime=h(),t.allowClick=!0,t.updateSize(),t.swipeDirection=void 0,r.threshold>0&&(i.allowThresholdMove=!1);let b=!0;o.matches(i.focusableElements)&&(b=!1,"SELECT"===o.nodeName&&(i.isTouched=!1)),s.activeElement&&s.activeElement.matches(i.focusableElements)&&s.activeElement!==o&&("mouse"===a.pointerType||"mouse"!==a.pointerType&&!o.matches(i.focusableElements))&&s.activeElement.blur();const w=b&&t.allowTouchMove&&r.touchStartPreventDefault;!r.touchStartForcePreventDefault&&!w||o.isContentEditable||a.preventDefault(),r.freeMode&&r.freeMode.enabled&&t.freeMode&&t.animating&&!r.cssMode&&t.freeMode.onTouchStart(),t.emit("touchStart",a)}function K(e){const t=d(),s=this,a=s.touchEventsData,{params:i,touches:r,rtlTranslate:n,enabled:l}=s;if(!l)return;if(!i.simulateTouch&&"mouse"===e.pointerType)return;let o,c=e;if(c.originalEvent&&(c=c.originalEvent),"pointermove"===c.type){if(null!==a.touchId)return;if(c.pointerId!==a.pointerId)return}if("touchmove"===c.type){if(o=[...c.changedTouches].find((e=>e.identifier===a.touchId)),!o||o.identifier!==a.touchId)return}else o=c;if(!a.isTouched)return void(a.startMoving&&a.isScrolling&&s.emit("touchMoveOpposite",c));const p=o.pageX,u=o.pageY;if(c.preventedByNestedSwiper)return r.startX=p,void(r.startY=u);if(!s.allowTouchMove)return c.target.matches(a.focusableElements)||(s.allowClick=!1),void(a.isTouched&&(Object.assign(r,{startX:p,startY:u,currentX:p,currentY:u}),a.touchStartTime=h()));if(i.touchReleaseOnEdges&&!i.loop)if(s.isVertical()){if(u<r.startY&&s.translate<=s.maxTranslate()||u>r.startY&&s.translate>=s.minTranslate())return a.isTouched=!1,void(a.isMoved=!1)}else{if(n&&(p>r.startX&&-s.translate<=s.maxTranslate()||p<r.startX&&-s.translate>=s.minTranslate()))return;if(!n&&(p<r.startX&&s.translate<=s.maxTranslate()||p>r.startX&&s.translate>=s.minTranslate()))return}if(t.activeElement&&t.activeElement.matches(a.focusableElements)&&t.activeElement!==c.target&&"mouse"!==c.pointerType&&t.activeElement.blur(),t.activeElement&&c.target===t.activeElement&&c.target.matches(a.focusableElements))return a.isMoved=!0,void(s.allowClick=!1);a.allowTouchCallbacks&&s.emit("touchMove",c),r.previousX=r.currentX,r.previousY=r.currentY,r.currentX=p,r.currentY=u;const m=r.currentX-r.startX,f=r.currentY-r.startY;if(s.params.threshold&&Math.sqrt(m**2+f**2)<s.params.threshold)return;if(void 0===a.isScrolling){let e;s.isHorizontal()&&r.currentY===r.startY||s.isVertical()&&r.currentX===r.startX?a.isScrolling=!1:m*m+f*f>=25&&(e=180*Math.atan2(Math.abs(f),Math.abs(m))/Math.PI,a.isScrolling=s.isHorizontal()?e>i.touchAngle:90-e>i.touchAngle)}if(a.isScrolling&&s.emit("touchMoveOpposite",c),void 0===a.startMoving&&(r.currentX===r.startX&&r.currentY===r.startY||(a.startMoving=!0)),a.isScrolling||"touchmove"===c.type&&a.preventTouchMoveFromPointerMove)return void(a.isTouched=!1);if(!a.startMoving)return;s.allowClick=!1,!i.cssMode&&c.cancelable&&c.preventDefault(),i.touchMoveStopPropagation&&!i.nested&&c.stopPropagation();let g=s.isHorizontal()?m:f,v=s.isHorizontal()?r.currentX-r.previousX:r.currentY-r.previousY;i.oneWayMovement&&(g=Math.abs(g)*(n?1:-1),v=Math.abs(v)*(n?1:-1)),r.diff=g,g*=i.touchRatio,n&&(g=-g,v=-v);const b=s.touchesDirection;s.swipeDirection=g>0?"prev":"next",s.touchesDirection=v>0?"prev":"next";const w=s.params.loop&&!i.cssMode,y="next"===s.touchesDirection&&s.allowSlideNext||"prev"===s.touchesDirection&&s.allowSlidePrev;if(!a.isMoved){if(w&&y&&s.loopFix({direction:s.swipeDirection}),a.startTranslate=s.getTranslate(),s.setTransition(0),s.animating){const e=new window.CustomEvent("transitionend",{bubbles:!0,cancelable:!0,detail:{bySwiperTouchMove:!0}});s.wrapperEl.dispatchEvent(e)}a.allowMomentumBounce=!1,!i.grabCursor||!0!==s.allowSlideNext&&!0!==s.allowSlidePrev||s.setGrabCursor(!0),s.emit("sliderFirstMove",c)}if((new Date).getTime(),!1!==i._loopSwapReset&&a.isMoved&&a.allowThresholdMove&&b!==s.touchesDirection&&w&&y&&Math.abs(g)>=1)return Object.assign(r,{startX:p,startY:u,currentX:p,currentY:u,startTranslate:a.currentTranslate}),a.loopSwapReset=!0,void(a.startTranslate=a.currentTranslate);s.emit("sliderMove",c),a.isMoved=!0,a.currentTranslate=g+a.startTranslate;let x=!0,S=i.resistanceRatio;if(i.touchReleaseOnEdges&&(S=0),g>0?(w&&y&&a.allowThresholdMove&&a.currentTranslate>(i.centeredSlides?s.minTranslate()-s.slidesSizesGrid[s.activeIndex+1]-("auto"!==i.slidesPerView&&s.slides.length-i.slidesPerView>=2?s.slidesSizesGrid[s.activeIndex+1]+s.params.spaceBetween:0)-s.params.spaceBetween:s.minTranslate())&&s.loopFix({direction:"prev",setTranslate:!0,activeSlideIndex:0}),a.currentTranslate>s.minTranslate()&&(x=!1,i.resistance&&(a.currentTranslate=s.minTranslate()-1+(-s.minTranslate()+a.startTranslate+g)**S))):g<0&&(w&&y&&a.allowThresholdMove&&a.currentTranslate<(i.centeredSlides?s.maxTranslate()+s.slidesSizesGrid[s.slidesSizesGrid.length-1]+s.params.spaceBetween+("auto"!==i.slidesPerView&&s.slides.length-i.slidesPerView>=2?s.slidesSizesGrid[s.slidesSizesGrid.length-1]+s.params.spaceBetween:0):s.maxTranslate())&&s.loopFix({direction:"next",setTranslate:!0,activeSlideIndex:s.slides.length-("auto"===i.slidesPerView?s.slidesPerViewDynamic():Math.ceil(parseFloat(i.slidesPerView,10)))}),a.currentTranslate<s.maxTranslate()&&(x=!1,i.resistance&&(a.currentTranslate=s.maxTranslate()+1-(s.maxTranslate()-a.startTranslate-g)**S))),x&&(c.preventedByNestedSwiper=!0),!s.allowSlideNext&&"next"===s.swipeDirection&&a.currentTranslate<a.startTranslate&&(a.currentTranslate=a.startTranslate),!s.allowSlidePrev&&"prev"===s.swipeDirection&&a.currentTranslate>a.startTranslate&&(a.currentTranslate=a.startTranslate),s.allowSlidePrev||s.allowSlideNext||(a.currentTranslate=a.startTranslate),i.threshold>0){if(!(Math.abs(g)>i.threshold||a.allowThresholdMove))return void(a.currentTranslate=a.startTranslate);if(!a.allowThresholdMove)return a.allowThresholdMove=!0,r.startX=r.currentX,r.startY=r.currentY,a.currentTranslate=a.startTranslate,void(r.diff=s.isHorizontal()?r.currentX-r.startX:r.currentY-r.startY)}i.followFinger&&!i.cssMode&&((i.freeMode&&i.freeMode.enabled&&s.freeMode||i.watchSlidesProgress)&&(s.updateActiveIndex(),s.updateSlidesClasses()),i.freeMode&&i.freeMode.enabled&&s.freeMode&&s.freeMode.onTouchMove(),s.updateProgress(a.currentTranslate),s.setTranslate(a.currentTranslate))}function Z(e){const t=this,s=t.touchEventsData;let a,i=e;i.originalEvent&&(i=i.originalEvent);if("touchend"===i.type||"touchcancel"===i.type){if(a=[...i.changedTouches].find((e=>e.identifier===s.touchId)),!a||a.identifier!==s.touchId)return}else{if(null!==s.touchId)return;if(i.pointerId!==s.pointerId)return;a=i}if(["pointercancel","pointerout","pointerleave","contextmenu"].includes(i.type)){if(!(["pointercancel","contextmenu"].includes(i.type)&&(t.browser.isSafari||t.browser.isWebView)))return}s.pointerId=null,s.touchId=null;const{params:r,touches:n,rtlTranslate:l,slidesGrid:o,enabled:d}=t;if(!d)return;if(!r.simulateTouch&&"mouse"===i.pointerType)return;if(s.allowTouchCallbacks&&t.emit("touchEnd",i),s.allowTouchCallbacks=!1,!s.isTouched)return s.isMoved&&r.grabCursor&&t.setGrabCursor(!1),s.isMoved=!1,void(s.startMoving=!1);r.grabCursor&&s.isMoved&&s.isTouched&&(!0===t.allowSlideNext||!0===t.allowSlidePrev)&&t.setGrabCursor(!1);const c=h(),p=c-s.touchStartTime;if(t.allowClick){const e=i.path||i.composedPath&&i.composedPath();t.updateClickedSlide(e&&e[0]||i.target,e),t.emit("tap click",i),p<300&&c-s.lastClickTime<300&&t.emit("doubleTap doubleClick",i)}if(s.lastClickTime=h(),m((()=>{t.destroyed||(t.allowClick=!0)})),!s.isTouched||!s.isMoved||!t.swipeDirection||0===n.diff&&!s.loopSwapReset||s.currentTranslate===s.startTranslate&&!s.loopSwapReset)return s.isTouched=!1,s.isMoved=!1,void(s.startMoving=!1);let u;if(s.isTouched=!1,s.isMoved=!1,s.startMoving=!1,u=r.followFinger?l?t.translate:-t.translate:-s.currentTranslate,r.cssMode)return;if(r.freeMode&&r.freeMode.enabled)return void t.freeMode.onTouchEnd({currentPos:u});const f=u>=-t.maxTranslate()&&!t.params.loop;let g=0,v=t.slidesSizesGrid[0];for(let e=0;e<o.length;e+=e<r.slidesPerGroupSkip?1:r.slidesPerGroup){const t=e<r.slidesPerGroupSkip-1?1:r.slidesPerGroup;void 0!==o[e+t]?(f||u>=o[e]&&u<o[e+t])&&(g=e,v=o[e+t]-o[e]):(f||u>=o[e])&&(g=e,v=o[o.length-1]-o[o.length-2])}let b=null,w=null;r.rewind&&(t.isBeginning?w=r.virtual&&r.virtual.enabled&&t.virtual?t.virtual.slides.length-1:t.slides.length-1:t.isEnd&&(b=0));const y=(u-o[g])/v,x=g<r.slidesPerGroupSkip-1?1:r.slidesPerGroup;if(p>r.longSwipesMs){if(!r.longSwipes)return void t.slideTo(t.activeIndex);"next"===t.swipeDirection&&(y>=r.longSwipesRatio?t.slideTo(r.rewind&&t.isEnd?b:g+x):t.slideTo(g)),"prev"===t.swipeDirection&&(y>1-r.longSwipesRatio?t.slideTo(g+x):null!==w&&y<0&&Math.abs(y)>r.longSwipesRatio?t.slideTo(w):t.slideTo(g))}else{if(!r.shortSwipes)return void t.slideTo(t.activeIndex);t.navigation&&(i.target===t.navigation.nextEl||i.target===t.navigation.prevEl)?i.target===t.navigation.nextEl?t.slideTo(g+x):t.slideTo(g):("next"===t.swipeDirection&&t.slideTo(null!==b?b:g+x),"prev"===t.swipeDirection&&t.slideTo(null!==w?w:g))}}function J(){const e=this,{params:t,el:s}=e;if(s&&0===s.offsetWidth)return;t.breakpoints&&e.setBreakpoint();const{allowSlideNext:a,allowSlidePrev:i,snapGrid:r}=e,n=e.virtual&&e.params.virtual.enabled;e.allowSlideNext=!0,e.allowSlidePrev=!0,e.updateSize(),e.updateSlides(),e.updateSlidesClasses();const l=n&&t.loop;!("auto"===t.slidesPerView||t.slidesPerView>1)||!e.isEnd||e.isBeginning||e.params.centeredSlides||l?e.params.loop&&!n?e.slideToLoop(e.realIndex,0,!1,!0):e.slideTo(e.activeIndex,0,!1,!0):e.slideTo(e.slides.length-1,0,!1,!0),e.autoplay&&e.autoplay.running&&e.autoplay.paused&&(clearTimeout(e.autoplay.resizeTimeout),e.autoplay.resizeTimeout=setTimeout((()=>{e.autoplay&&e.autoplay.running&&e.autoplay.paused&&e.autoplay.resume()}),500)),e.allowSlidePrev=i,e.allowSlideNext=a,e.params.watchOverflow&&r!==e.snapGrid&&e.checkOverflow()}function Q(e){const t=this;t.enabled&&(t.allowClick||(t.params.preventClicks&&e.preventDefault(),t.params.preventClicksPropagation&&t.animating&&(e.stopPropagation(),e.stopImmediatePropagation())))}function ee(){const e=this,{wrapperEl:t,rtlTranslate:s,enabled:a}=e;if(!a)return;let i;e.previousTranslate=e.translate,e.isHorizontal()?e.translate=-t.scrollLeft:e.translate=-t.scrollTop,0===e.translate&&(e.translate=0),e.updateActiveIndex(),e.updateSlidesClasses();const r=e.maxTranslate()-e.minTranslate();i=0===r?0:(e.translate-e.minTranslate())/r,i!==e.progress&&e.updateProgress(s?-e.translate:e.translate),e.emit("setTranslate",e.translate,!1)}function te(e){const t=this;B(t,e.target),t.params.cssMode||"auto"!==t.params.slidesPerView&&!t.params.autoHeight||t.update()}function se(){const e=this;e.documentTouchHandlerProceeded||(e.documentTouchHandlerProceeded=!0,e.params.touchReleaseOnEdges&&(e.el.style.touchAction="auto"))}const ae=(e,t)=>{const s=d(),{params:a,el:i,wrapperEl:r,device:n}=e,l=!!a.nested,o="on"===t?"addEventListener":"removeEventListener",c=t;i&&"string"!=typeof i&&(s[o]("touchstart",e.onDocumentTouchStart,{passive:!1,capture:l}),i[o]("touchstart",e.onTouchStart,{passive:!1}),i[o]("pointerdown",e.onTouchStart,{passive:!1}),s[o]("touchmove",e.onTouchMove,{passive:!1,capture:l}),s[o]("pointermove",e.onTouchMove,{passive:!1,capture:l}),s[o]("touchend",e.onTouchEnd,{passive:!0}),s[o]("pointerup",e.onTouchEnd,{passive:!0}),s[o]("pointercancel",e.onTouchEnd,{passive:!0}),s[o]("touchcancel",e.onTouchEnd,{passive:!0}),s[o]("pointerout",e.onTouchEnd,{passive:!0}),s[o]("pointerleave",e.onTouchEnd,{passive:!0}),s[o]("contextmenu",e.onTouchEnd,{passive:!0}),(a.preventClicks||a.preventClicksPropagation)&&i[o]("click",e.onClick,!0),a.cssMode&&r[o]("scroll",e.onScroll),a.updateOnWindowResize?e[c](n.ios||n.android?"resize orientationchange observerUpdate":"resize observerUpdate",J,!0):e[c]("observerUpdate",J,!0),i[o]("load",e.onLoad,{capture:!0}))};const ie=(e,t)=>e.grid&&t.grid&&t.grid.rows>1;var re={init:!0,direction:"horizontal",oneWayMovement:!1,swiperElementNodeName:"SWIPER-CONTAINER",touchEventsTarget:"wrapper",initialSlide:0,speed:300,cssMode:!1,updateOnWindowResize:!0,resizeObserver:!0,nested:!1,createElements:!1,eventsPrefix:"swiper",enabled:!0,focusableElements:"input, select, option, textarea, button, video, label",width:null,height:null,preventInteractionOnTransition:!1,userAgent:null,url:null,edgeSwipeDetection:!1,edgeSwipeThreshold:20,autoHeight:!1,setWrapperSize:!1,virtualTranslate:!1,effect:"slide",breakpoints:void 0,breakpointsBase:"window",spaceBetween:0,slidesPerView:1,slidesPerGroup:1,slidesPerGroupSkip:0,slidesPerGroupAuto:!1,centeredSlides:!1,centeredSlidesBounds:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,normalizeSlideIndex:!0,centerInsufficientSlides:!1,watchOverflow:!0,roundLengths:!1,touchRatio:1,touchAngle:45,simulateTouch:!0,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,allowTouchMove:!0,threshold:5,touchMoveStopPropagation:!1,touchStartPreventDefault:!0,touchStartForcePreventDefault:!1,touchReleaseOnEdges:!1,uniqueNavElements:!0,resistance:!0,resistanceRatio:.85,watchSlidesProgress:!1,grabCursor:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,loop:!1,loopAddBlankSlides:!0,loopAdditionalSlides:0,loopPreventsSliding:!0,rewind:!1,allowSlidePrev:!0,allowSlideNext:!0,swipeHandler:null,noSwiping:!0,noSwipingClass:"swiper-no-swiping",noSwipingSelector:null,passiveListeners:!0,maxBackfaceHiddenSlides:10,containerModifierClass:"swiper-",slideClass:"swiper-slide",slideBlankClass:"swiper-slide-blank",slideActiveClass:"swiper-slide-active",slideVisibleClass:"swiper-slide-visible",slideFullyVisibleClass:"swiper-slide-fully-visible",slideNextClass:"swiper-slide-next",slidePrevClass:"swiper-slide-prev",wrapperClass:"swiper-wrapper",lazyPreloaderClass:"swiper-lazy-preloader",lazyPreloadPrevNext:0,runCallbacksOnInit:!0,_emitClasses:!1};function ne(e,t){return function(s){void 0===s&&(s={});const a=Object.keys(s)[0],i=s[a];"object"==typeof i&&null!==i?(!0===e[a]&&(e[a]={enabled:!0}),"navigation"===a&&e[a]&&e[a].enabled&&!e[a].prevEl&&!e[a].nextEl&&(e[a].auto=!0),["pagination","scrollbar"].indexOf(a)>=0&&e[a]&&e[a].enabled&&!e[a].el&&(e[a].auto=!0),a in e&&"enabled"in i?("object"!=typeof e[a]||"enabled"in e[a]||(e[a].enabled=!0),e[a]||(e[a]={enabled:!1}),v(t,s)):v(t,s)):v(t,s)}}const le={eventsEmitter:G,update:F,translate:V,transition:{setTransition:function(e,t){const s=this;s.params.cssMode||(s.wrapperEl.style.transitionDuration=`${e}ms`,s.wrapperEl.style.transitionDelay=0===e?"0ms":""),s.emit("setTransition",e,t)},transitionStart:function(e,t){void 0===e&&(e=!0);const s=this,{params:a}=s;a.cssMode||(a.autoHeight&&s.updateAutoHeight(),j({swiper:s,runCallbacks:e,direction:t,step:"Start"}))},transitionEnd:function(e,t){void 0===e&&(e=!0);const s=this,{params:a}=s;s.animating=!1,a.cssMode||(s.setTransition(0),j({swiper:s,runCallbacks:e,direction:t,step:"End"}))}},slide:X,loop:Y,grabCursor:{setGrabCursor:function(e){const t=this;if(!t.params.simulateTouch||t.params.watchOverflow&&t.isLocked||t.params.cssMode)return;const s="container"===t.params.touchEventsTarget?t.el:t.wrapperEl;t.isElement&&(t.__preventObserver__=!0),s.style.cursor="move",s.style.cursor=e?"grabbing":"grab",t.isElement&&requestAnimationFrame((()=>{t.__preventObserver__=!1}))},unsetGrabCursor:function(){const e=this;e.params.watchOverflow&&e.isLocked||e.params.cssMode||(e.isElement&&(e.__preventObserver__=!0),e["container"===e.params.touchEventsTarget?"el":"wrapperEl"].style.cursor="",e.isElement&&requestAnimationFrame((()=>{e.__preventObserver__=!1})))}},events:{attachEvents:function(){const e=this,{params:t}=e;e.onTouchStart=U.bind(e),e.onTouchMove=K.bind(e),e.onTouchEnd=Z.bind(e),e.onDocumentTouchStart=se.bind(e),t.cssMode&&(e.onScroll=ee.bind(e)),e.onClick=Q.bind(e),e.onLoad=te.bind(e),ae(e,"on")},detachEvents:function(){ae(this,"off")}},breakpoints:{setBreakpoint:function(){const e=this,{realIndex:t,initialized:s,params:a,el:i}=e,r=a.breakpoints;if(!r||r&&0===Object.keys(r).length)return;const n=d(),l="window"!==a.breakpointsBase&&a.breakpointsBase?"container":a.breakpointsBase,o=["window","container"].includes(a.breakpointsBase)||!a.breakpointsBase?e.el:n.querySelector(a.breakpointsBase),c=e.getBreakpoint(r,l,o);if(!c||e.currentBreakpoint===c)return;const p=(c in r?r[c]:void 0)||e.originalParams,u=ie(e,a),m=ie(e,p),h=e.params.grabCursor,f=p.grabCursor,g=a.enabled;u&&!m?(i.classList.remove(`${a.containerModifierClass}grid`,`${a.containerModifierClass}grid-column`),e.emitContainerClasses()):!u&&m&&(i.classList.add(`${a.containerModifierClass}grid`),(p.grid.fill&&"column"===p.grid.fill||!p.grid.fill&&"column"===a.grid.fill)&&i.classList.add(`${a.containerModifierClass}grid-column`),e.emitContainerClasses()),h&&!f?e.unsetGrabCursor():!h&&f&&e.setGrabCursor(),["navigation","pagination","scrollbar"].forEach((t=>{if(void 0===p[t])return;const s=a[t]&&a[t].enabled,i=p[t]&&p[t].enabled;s&&!i&&e[t].disable(),!s&&i&&e[t].enable()}));const b=p.direction&&p.direction!==a.direction,w=a.loop&&(p.slidesPerView!==a.slidesPerView||b),y=a.loop;b&&s&&e.changeDirection(),v(e.params,p);const x=e.params.enabled,S=e.params.loop;Object.assign(e,{allowTouchMove:e.params.allowTouchMove,allowSlideNext:e.params.allowSlideNext,allowSlidePrev:e.params.allowSlidePrev}),g&&!x?e.disable():!g&&x&&e.enable(),e.currentBreakpoint=c,e.emit("_beforeBreakpoint",p),s&&(w?(e.loopDestroy(),e.loopCreate(t),e.updateSlides()):!y&&S?(e.loopCreate(t),e.updateSlides()):y&&!S&&e.loopDestroy()),e.emit("breakpoint",p)},getBreakpoint:function(e,t,s){if(void 0===t&&(t="window"),!e||"container"===t&&!s)return;let a=!1;const i=p(),r="window"===t?i.innerHeight:s.clientHeight,n=Object.keys(e).map((e=>{if("string"==typeof e&&0===e.indexOf("@")){const t=parseFloat(e.substr(1));return{value:r*t,point:e}}return{value:e,point:e}}));n.sort(((e,t)=>parseInt(e.value,10)-parseInt(t.value,10)));for(let e=0;e<n.length;e+=1){const{point:r,value:l}=n[e];"window"===t?i.matchMedia(`(min-width: ${l}px)`).matches&&(a=r):l<=s.clientWidth&&(a=r)}return a||"max"}},checkOverflow:{checkOverflow:function(){const e=this,{isLocked:t,params:s}=e,{slidesOffsetBefore:a}=s;if(a){const t=e.slides.length-1,s=e.slidesGrid[t]+e.slidesSizesGrid[t]+2*a;e.isLocked=e.size>s}else e.isLocked=1===e.snapGrid.length;!0===s.allowSlideNext&&(e.allowSlideNext=!e.isLocked),!0===s.allowSlidePrev&&(e.allowSlidePrev=!e.isLocked),t&&t!==e.isLocked&&(e.isEnd=!1),t!==e.isLocked&&e.emit(e.isLocked?"lock":"unlock")}},classes:{addClasses:function(){const e=this,{classNames:t,params:s,rtl:a,el:i,device:r}=e,n=function(e,t){const s=[];return e.forEach((e=>{"object"==typeof e?Object.keys(e).forEach((a=>{e[a]&&s.push(t+a)})):"string"==typeof e&&s.push(t+e)})),s}(["initialized",s.direction,{"free-mode":e.params.freeMode&&s.freeMode.enabled},{autoheight:s.autoHeight},{rtl:a},{grid:s.grid&&s.grid.rows>1},{"grid-column":s.grid&&s.grid.rows>1&&"column"===s.grid.fill},{android:r.android},{ios:r.ios},{"css-mode":s.cssMode},{centered:s.cssMode&&s.centeredSlides},{"watch-progress":s.watchSlidesProgress}],s.containerModifierClass);t.push(...n),i.classList.add(...t),e.emitContainerClasses()},removeClasses:function(){const{el:e,classNames:t}=this;e&&"string"!=typeof e&&(e.classList.remove(...t),this.emitContainerClasses())}}},oe={};class de{constructor(){let e,t;for(var s=arguments.length,a=new Array(s),i=0;i<s;i++)a[i]=arguments[i];1===a.length&&a[0].constructor&&"Object"===Object.prototype.toString.call(a[0]).slice(8,-1)?t=a[0]:[e,t]=a,t||(t={}),t=v({},t),e&&!t.el&&(t.el=e);const r=d();if(t.el&&"string"==typeof t.el&&r.querySelectorAll(t.el).length>1){const e=[];return r.querySelectorAll(t.el).forEach((s=>{const a=v({},t,{el:s});e.push(new de(a))})),e}const n=this;n.__swiper__=!0,n.support=$(),n.device=D({userAgent:t.userAgent}),n.browser=_(),n.eventsListeners={},n.eventsAnyListeners=[],n.modules=[...n.__modules__],t.modules&&Array.isArray(t.modules)&&n.modules.push(...t.modules);const l={};n.modules.forEach((e=>{e({params:t,swiper:n,extendParams:ne(t,l),on:n.on.bind(n),once:n.once.bind(n),off:n.off.bind(n),emit:n.emit.bind(n)})}));const o=v({},re,l);return n.params=v({},o,oe,t),n.originalParams=v({},n.params),n.passedParams=v({},t),n.params&&n.params.on&&Object.keys(n.params.on).forEach((e=>{n.on(e,n.params.on[e])})),n.params&&n.params.onAny&&n.onAny(n.params.onAny),Object.assign(n,{enabled:n.params.enabled,el:e,classNames:[],slides:[],slidesGrid:[],snapGrid:[],slidesSizesGrid:[],isHorizontal:()=>"horizontal"===n.params.direction,isVertical:()=>"vertical"===n.params.direction,activeIndex:0,realIndex:0,isBeginning:!0,isEnd:!1,translate:0,previousTranslate:0,progress:0,velocity:0,animating:!1,cssOverflowAdjustment(){return Math.trunc(this.translate/2**23)*2**23},allowSlideNext:n.params.allowSlideNext,allowSlidePrev:n.params.allowSlidePrev,touchEventsData:{isTouched:void 0,isMoved:void 0,allowTouchCallbacks:void 0,touchStartTime:void 0,isScrolling:void 0,currentTranslate:void 0,startTranslate:void 0,allowThresholdMove:void 0,focusableElements:n.params.focusableElements,lastClickTime:0,clickTimeout:void 0,velocities:[],allowMomentumBounce:void 0,startMoving:void 0,pointerId:null,touchId:null},allowClick:!0,allowTouchMove:n.params.allowTouchMove,touches:{startX:0,startY:0,currentX:0,currentY:0,diff:0},imagesToLoad:[],imagesLoaded:0}),n.emit("_swiper"),n.params.init&&n.init(),n}getDirectionLabel(e){return this.isHorizontal()?e:{width:"height","margin-top":"margin-left","margin-bottom ":"margin-right","margin-left":"margin-top","margin-right":"margin-bottom","padding-left":"padding-top","padding-right":"padding-bottom",marginRight:"marginBottom"}[e]}getSlideIndex(e){const{slidesEl:t,params:s}=this,a=C(x(t,`.${s.slideClass}, swiper-slide`)[0]);return C(e)-a}getSlideIndexByData(e){return this.getSlideIndex(this.slides.find((t=>1*t.getAttribute("data-swiper-slide-index")===e)))}recalcSlides(){const{slidesEl:e,params:t}=this;this.slides=x(e,`.${t.slideClass}, swiper-slide`)}enable(){const e=this;e.enabled||(e.enabled=!0,e.params.grabCursor&&e.setGrabCursor(),e.emit("enable"))}disable(){const e=this;e.enabled&&(e.enabled=!1,e.params.grabCursor&&e.unsetGrabCursor(),e.emit("disable"))}setProgress(e,t){const s=this;e=Math.min(Math.max(e,0),1);const a=s.minTranslate(),i=(s.maxTranslate()-a)*e+a;s.translateTo(i,void 0===t?0:t),s.updateActiveIndex(),s.updateSlidesClasses()}emitContainerClasses(){const e=this;if(!e.params._emitClasses||!e.el)return;const t=e.el.className.split(" ").filter((t=>0===t.indexOf("swiper")||0===t.indexOf(e.params.containerModifierClass)));e.emit("_containerClasses",t.join(" "))}getSlideClasses(e){const t=this;return t.destroyed?"":e.className.split(" ").filter((e=>0===e.indexOf("swiper-slide")||0===e.indexOf(t.params.slideClass))).join(" ")}emitSlidesClasses(){const e=this;if(!e.params._emitClasses||!e.el)return;const t=[];e.slides.forEach((s=>{const a=e.getSlideClasses(s);t.push({slideEl:s,classNames:a}),e.emit("_slideClass",s,a)})),e.emit("_slideClasses",t)}slidesPerViewDynamic(e,t){void 0===e&&(e="current"),void 0===t&&(t=!1);const{params:s,slides:a,slidesGrid:i,slidesSizesGrid:r,size:n,activeIndex:l}=this;let o=1;if("number"==typeof s.slidesPerView)return s.slidesPerView;if(s.centeredSlides){let e,t=a[l]?Math.ceil(a[l].swiperSlideSize):0;for(let s=l+1;s<a.length;s+=1)a[s]&&!e&&(t+=Math.ceil(a[s].swiperSlideSize),o+=1,t>n&&(e=!0));for(let s=l-1;s>=0;s-=1)a[s]&&!e&&(t+=a[s].swiperSlideSize,o+=1,t>n&&(e=!0))}else if("current"===e)for(let e=l+1;e<a.length;e+=1){(t?i[e]+r[e]-i[l]<n:i[e]-i[l]<n)&&(o+=1)}else for(let e=l-1;e>=0;e-=1){i[l]-i[e]<n&&(o+=1)}return o}update(){const e=this;if(!e||e.destroyed)return;const{snapGrid:t,params:s}=e;function a(){const t=e.rtlTranslate?-1*e.translate:e.translate,s=Math.min(Math.max(t,e.maxTranslate()),e.minTranslate());e.setTranslate(s),e.updateActiveIndex(),e.updateSlidesClasses()}let i;if(s.breakpoints&&e.setBreakpoint(),[...e.el.querySelectorAll('[loading="lazy"]')].forEach((t=>{t.complete&&B(e,t)})),e.updateSize(),e.updateSlides(),e.updateProgress(),e.updateSlidesClasses(),s.freeMode&&s.freeMode.enabled&&!s.cssMode)a(),s.autoHeight&&e.updateAutoHeight();else{if(("auto"===s.slidesPerView||s.slidesPerView>1)&&e.isEnd&&!s.centeredSlides){const t=e.virtual&&s.virtual.enabled?e.virtual.slides:e.slides;i=e.slideTo(t.length-1,0,!1,!0)}else i=e.slideTo(e.activeIndex,0,!1,!0);i||a()}s.watchOverflow&&t!==e.snapGrid&&e.checkOverflow(),e.emit("update")}changeDirection(e,t){void 0===t&&(t=!0);const s=this,a=s.params.direction;return e||(e="horizontal"===a?"vertical":"horizontal"),e===a||"horizontal"!==e&&"vertical"!==e||(s.el.classList.remove(`${s.params.containerModifierClass}${a}`),s.el.classList.add(`${s.params.containerModifierClass}${e}`),s.emitContainerClasses(),s.params.direction=e,s.slides.forEach((t=>{"vertical"===e?t.style.width="":t.style.height=""})),s.emit("changeDirection"),t&&s.update()),s}changeLanguageDirection(e){const t=this;t.rtl&&"rtl"===e||!t.rtl&&"ltr"===e||(t.rtl="rtl"===e,t.rtlTranslate="horizontal"===t.params.direction&&t.rtl,t.rtl?(t.el.classList.add(`${t.params.containerModifierClass}rtl`),t.el.dir="rtl"):(t.el.classList.remove(`${t.params.containerModifierClass}rtl`),t.el.dir="ltr"),t.update())}mount(e){const t=this;if(t.mounted)return!0;let s=e||t.params.el;if("string"==typeof s&&(s=document.querySelector(s)),!s)return!1;s.swiper=t,s.parentNode&&s.parentNode.host&&s.parentNode.host.nodeName===t.params.swiperElementNodeName.toUpperCase()&&(t.isElement=!0);const a=()=>`.${(t.params.wrapperClass||"").trim().split(" ").join(".")}`;let i=(()=>{if(s&&s.shadowRoot&&s.shadowRoot.querySelector){return s.shadowRoot.querySelector(a())}return x(s,a())[0]})();return!i&&t.params.createElements&&(i=T("div",t.params.wrapperClass),s.append(i),x(s,`.${t.params.slideClass}`).forEach((e=>{i.append(e)}))),Object.assign(t,{el:s,wrapperEl:i,slidesEl:t.isElement&&!s.parentNode.host.slideSlots?s.parentNode.host:i,hostEl:t.isElement?s.parentNode.host:s,mounted:!0,rtl:"rtl"===s.dir.toLowerCase()||"rtl"===M(s,"direction"),rtlTranslate:"horizontal"===t.params.direction&&("rtl"===s.dir.toLowerCase()||"rtl"===M(s,"direction")),wrongRTL:"-webkit-box"===M(i,"display")}),!0}init(e){const t=this;if(t.initialized)return t;if(!1===t.mount(e))return t;t.emit("beforeInit"),t.params.breakpoints&&t.setBreakpoint(),t.addClasses(),t.updateSize(),t.updateSlides(),t.params.watchOverflow&&t.checkOverflow(),t.params.grabCursor&&t.enabled&&t.setGrabCursor(),t.params.loop&&t.virtual&&t.params.virtual.enabled?t.slideTo(t.params.initialSlide+t.virtual.slidesBefore,0,t.params.runCallbacksOnInit,!1,!0):t.slideTo(t.params.initialSlide,0,t.params.runCallbacksOnInit,!1,!0),t.params.loop&&t.loopCreate(void 0,!0),t.attachEvents();const s=[...t.el.querySelectorAll('[loading="lazy"]')];return t.isElement&&s.push(...t.hostEl.querySelectorAll('[loading="lazy"]')),s.forEach((e=>{e.complete?B(t,e):e.addEventListener("load",(e=>{B(t,e.target)}))})),R(t),t.initialized=!0,R(t),t.emit("init"),t.emit("afterInit"),t}destroy(e,t){void 0===e&&(e=!0),void 0===t&&(t=!0);const s=this,{params:a,el:i,wrapperEl:r,slides:n}=s;return void 0===s.params||s.destroyed||(s.emit("beforeDestroy"),s.initialized=!1,s.detachEvents(),a.loop&&s.loopDestroy(),t&&(s.removeClasses(),i&&"string"!=typeof i&&i.removeAttribute("style"),r&&r.removeAttribute("style"),n&&n.length&&n.forEach((e=>{e.classList.remove(a.slideVisibleClass,a.slideFullyVisibleClass,a.slideActiveClass,a.slideNextClass,a.slidePrevClass),e.removeAttribute("style"),e.removeAttribute("data-swiper-slide-index")}))),s.emit("destroy"),Object.keys(s.eventsListeners).forEach((e=>{s.off(e)})),!1!==e&&(s.el&&"string"!=typeof s.el&&(s.el.swiper=null),function(e){const t=e;Object.keys(t).forEach((e=>{try{t[e]=null}catch(e){}try{delete t[e]}catch(e){}}))}(s)),s.destroyed=!0),null}static extendDefaults(e){v(oe,e)}static get extendedDefaults(){return oe}static get defaults(){return re}static installModule(e){de.prototype.__modules__||(de.prototype.__modules__=[]);const t=de.prototype.__modules__;"function"==typeof e&&t.indexOf(e)<0&&t.push(e)}static use(e){return Array.isArray(e)?(e.forEach((e=>de.installModule(e))),de):(de.installModule(e),de)}}function ce(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;const r=d(),n=p();function l(e){if(!t.enabled)return;const{rtlTranslate:s}=t;let a=e;a.originalEvent&&(a=a.originalEvent);const l=a.keyCode||a.charCode,o=t.params.keyboard.pageUpDown,d=o&&33===l,c=o&&34===l,p=37===l,u=39===l,m=38===l,h=40===l;if(!t.allowSlideNext&&(t.isHorizontal()&&u||t.isVertical()&&h||c))return!1;if(!t.allowSlidePrev&&(t.isHorizontal()&&p||t.isVertical()&&m||d))return!1;if(!(a.shiftKey||a.altKey||a.ctrlKey||a.metaKey||r.activeElement&&r.activeElement.nodeName&&("input"===r.activeElement.nodeName.toLowerCase()||"textarea"===r.activeElement.nodeName.toLowerCase()))){if(t.params.keyboard.onlyInViewport&&(d||c||p||u||m||h)){let e=!1;if(L(t.el,`.${t.params.slideClass}, swiper-slide`).length>0&&0===L(t.el,`.${t.params.slideActiveClass}`).length)return;const a=t.el,i=a.clientWidth,r=a.clientHeight,l=n.innerWidth,o=n.innerHeight,d=E(a);s&&(d.left-=a.scrollLeft);const c=[[d.left,d.top],[d.left+i,d.top],[d.left,d.top+r],[d.left+i,d.top+r]];for(let t=0;t<c.length;t+=1){const s=c[t];if(s[0]>=0&&s[0]<=l&&s[1]>=0&&s[1]<=o){if(0===s[0]&&0===s[1])continue;e=!0}}if(!e)return}t.isHorizontal()?((d||c||p||u)&&(a.preventDefault?a.preventDefault():a.returnValue=!1),((c||u)&&!s||(d||p)&&s)&&t.slideNext(),((d||p)&&!s||(c||u)&&s)&&t.slidePrev()):((d||c||m||h)&&(a.preventDefault?a.preventDefault():a.returnValue=!1),(c||h)&&t.slideNext(),(d||m)&&t.slidePrev()),i("keyPress",l)}}function o(){t.keyboard.enabled||(r.addEventListener("keydown",l),t.keyboard.enabled=!0)}function c(){t.keyboard.enabled&&(r.removeEventListener("keydown",l),t.keyboard.enabled=!1)}t.keyboard={enabled:!1},s({keyboard:{enabled:!1,onlyInViewport:!0,pageUpDown:!0}}),a("init",(()=>{t.params.keyboard.enabled&&o()})),a("destroy",(()=>{t.keyboard.enabled&&c()})),Object.assign(t.keyboard,{enable:o,disable:c})}function pe(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;const r=p();let n;s({mousewheel:{enabled:!1,releaseOnEdges:!1,invert:!1,forceToAxis:!1,sensitivity:1,eventsTarget:"container",thresholdDelta:null,thresholdTime:null,noMousewheelClass:"swiper-no-mousewheel"}}),t.mousewheel={enabled:!1};let l,o=h();const d=[];function c(){t.enabled&&(t.mouseEntered=!0)}function u(){t.enabled&&(t.mouseEntered=!1)}function f(e){return!(t.params.mousewheel.thresholdDelta&&e.delta<t.params.mousewheel.thresholdDelta)&&(!(t.params.mousewheel.thresholdTime&&h()-o<t.params.mousewheel.thresholdTime)&&(e.delta>=6&&h()-o<60||(e.direction<0?t.isEnd&&!t.params.loop||t.animating||(t.slideNext(),i("scroll",e.raw)):t.isBeginning&&!t.params.loop||t.animating||(t.slidePrev(),i("scroll",e.raw)),o=(new r.Date).getTime(),!1)))}function g(e){let s=e,a=!0;if(!t.enabled)return;if(e.target.closest(`.${t.params.mousewheel.noMousewheelClass}`))return;const r=t.params.mousewheel;t.params.cssMode&&s.preventDefault();let o=t.el;"container"!==t.params.mousewheel.eventsTarget&&(o=document.querySelector(t.params.mousewheel.eventsTarget));const c=o&&o.contains(s.target);if(!t.mouseEntered&&!c&&!r.releaseOnEdges)return!0;s.originalEvent&&(s=s.originalEvent);let p=0;const u=t.rtlTranslate?-1:1,g=function(e){let t=0,s=0,a=0,i=0;return"detail"in e&&(s=e.detail),"wheelDelta"in e&&(s=-e.wheelDelta/120),"wheelDeltaY"in e&&(s=-e.wheelDeltaY/120),"wheelDeltaX"in e&&(t=-e.wheelDeltaX/120),"axis"in e&&e.axis===e.HORIZONTAL_AXIS&&(t=s,s=0),a=10*t,i=10*s,"deltaY"in e&&(i=e.deltaY),"deltaX"in e&&(a=e.deltaX),e.shiftKey&&!a&&(a=i,i=0),(a||i)&&e.deltaMode&&(1===e.deltaMode?(a*=40,i*=40):(a*=800,i*=800)),a&&!t&&(t=a<1?-1:1),i&&!s&&(s=i<1?-1:1),{spinX:t,spinY:s,pixelX:a,pixelY:i}}(s);if(r.forceToAxis)if(t.isHorizontal()){if(!(Math.abs(g.pixelX)>Math.abs(g.pixelY)))return!0;p=-g.pixelX*u}else{if(!(Math.abs(g.pixelY)>Math.abs(g.pixelX)))return!0;p=-g.pixelY}else p=Math.abs(g.pixelX)>Math.abs(g.pixelY)?-g.pixelX*u:-g.pixelY;if(0===p)return!0;r.invert&&(p=-p);let v=t.getTranslate()+p*r.sensitivity;if(v>=t.minTranslate()&&(v=t.minTranslate()),v<=t.maxTranslate()&&(v=t.maxTranslate()),a=!!t.params.loop||!(v===t.minTranslate()||v===t.maxTranslate()),a&&t.params.nested&&s.stopPropagation(),t.params.freeMode&&t.params.freeMode.enabled){const e={time:h(),delta:Math.abs(p),direction:Math.sign(p)},a=l&&e.time<l.time+500&&e.delta<=l.delta&&e.direction===l.direction;if(!a){l=void 0;let o=t.getTranslate()+p*r.sensitivity;const c=t.isBeginning,u=t.isEnd;if(o>=t.minTranslate()&&(o=t.minTranslate()),o<=t.maxTranslate()&&(o=t.maxTranslate()),t.setTransition(0),t.setTranslate(o),t.updateProgress(),t.updateActiveIndex(),t.updateSlidesClasses(),(!c&&t.isBeginning||!u&&t.isEnd)&&t.updateSlidesClasses(),t.params.loop&&t.loopFix({direction:e.direction<0?"next":"prev",byMousewheel:!0}),t.params.freeMode.sticky){clearTimeout(n),n=void 0,d.length>=15&&d.shift();const s=d.length?d[d.length-1]:void 0,a=d[0];if(d.push(e),s&&(e.delta>s.delta||e.direction!==s.direction))d.splice(0);else if(d.length>=15&&e.time-a.time<500&&a.delta-e.delta>=1&&e.delta<=6){const s=p>0?.8:.2;l=e,d.splice(0),n=m((()=>{!t.destroyed&&t.params&&t.slideToClosest(t.params.speed,!0,void 0,s)}),0)}n||(n=m((()=>{if(t.destroyed||!t.params)return;l=e,d.splice(0),t.slideToClosest(t.params.speed,!0,void 0,.5)}),500))}if(a||i("scroll",s),t.params.autoplay&&t.params.autoplay.disableOnInteraction&&t.autoplay.stop(),r.releaseOnEdges&&(o===t.minTranslate()||o===t.maxTranslate()))return!0}}else{const s={time:h(),delta:Math.abs(p),direction:Math.sign(p),raw:e};d.length>=2&&d.shift();const a=d.length?d[d.length-1]:void 0;if(d.push(s),a?(s.direction!==a.direction||s.delta>a.delta||s.time>a.time+150)&&f(s):f(s),function(e){const s=t.params.mousewheel;if(e.direction<0){if(t.isEnd&&!t.params.loop&&s.releaseOnEdges)return!0}else if(t.isBeginning&&!t.params.loop&&s.releaseOnEdges)return!0;return!1}(s))return!0}return s.preventDefault?s.preventDefault():s.returnValue=!1,!1}function v(e){let s=t.el;"container"!==t.params.mousewheel.eventsTarget&&(s=document.querySelector(t.params.mousewheel.eventsTarget)),s[e]("mouseenter",c),s[e]("mouseleave",u),s[e]("wheel",g)}function b(){return t.params.cssMode?(t.wrapperEl.removeEventListener("wheel",g),!0):!t.mousewheel.enabled&&(v("addEventListener"),t.mousewheel.enabled=!0,!0)}function w(){return t.params.cssMode?(t.wrapperEl.addEventListener(event,g),!0):!!t.mousewheel.enabled&&(v("removeEventListener"),t.mousewheel.enabled=!1,!0)}a("init",(()=>{!t.params.mousewheel.enabled&&t.params.cssMode&&w(),t.params.mousewheel.enabled&&b()})),a("destroy",(()=>{t.params.cssMode&&b(),t.mousewheel.enabled&&w()})),Object.assign(t.mousewheel,{enable:b,disable:w})}function ue(e,t,s,a){return e.params.createElements&&Object.keys(a).forEach((i=>{if(!s[i]&&!0===s.auto){let r=x(e.el,`.${a[i]}`)[0];r||(r=T("div",a[i]),r.className=a[i],e.el.append(r)),s[i]=r,t[i]=r}})),s}function me(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;function r(e){let s;return e&&"string"==typeof e&&t.isElement&&(s=t.el.querySelector(e)||t.hostEl.querySelector(e),s)?s:(e&&("string"==typeof e&&(s=[...document.querySelectorAll(e)]),t.params.uniqueNavElements&&"string"==typeof e&&s&&s.length>1&&1===t.el.querySelectorAll(e).length?s=t.el.querySelector(e):s&&1===s.length&&(s=s[0])),e&&!s?e:s)}function n(e,s){const a=t.params.navigation;(e=k(e)).forEach((e=>{e&&(e.classList[s?"add":"remove"](...a.disabledClass.split(" ")),"BUTTON"===e.tagName&&(e.disabled=s),t.params.watchOverflow&&t.enabled&&e.classList[t.isLocked?"add":"remove"](a.lockClass))}))}function l(){const{nextEl:e,prevEl:s}=t.navigation;if(t.params.loop)return n(s,!1),void n(e,!1);n(s,t.isBeginning&&!t.params.rewind),n(e,t.isEnd&&!t.params.rewind)}function o(e){e.preventDefault(),(!t.isBeginning||t.params.loop||t.params.rewind)&&(t.slidePrev(),i("navigationPrev"))}function d(e){e.preventDefault(),(!t.isEnd||t.params.loop||t.params.rewind)&&(t.slideNext(),i("navigationNext"))}function c(){const e=t.params.navigation;if(t.params.navigation=ue(t,t.originalParams.navigation,t.params.navigation,{nextEl:"swiper-button-next",prevEl:"swiper-button-prev"}),!e.nextEl&&!e.prevEl)return;let s=r(e.nextEl),a=r(e.prevEl);Object.assign(t.navigation,{nextEl:s,prevEl:a}),s=k(s),a=k(a);const i=(s,a)=>{s&&s.addEventListener("click","next"===a?d:o),!t.enabled&&s&&s.classList.add(...e.lockClass.split(" "))};s.forEach((e=>i(e,"next"))),a.forEach((e=>i(e,"prev")))}function p(){let{nextEl:e,prevEl:s}=t.navigation;e=k(e),s=k(s);const a=(e,s)=>{e.removeEventListener("click","next"===s?d:o),e.classList.remove(...t.params.navigation.disabledClass.split(" "))};e.forEach((e=>a(e,"next"))),s.forEach((e=>a(e,"prev")))}s({navigation:{nextEl:null,prevEl:null,hideOnClick:!1,disabledClass:"swiper-button-disabled",hiddenClass:"swiper-button-hidden",lockClass:"swiper-button-lock",navigationDisabledClass:"swiper-navigation-disabled"}}),t.navigation={nextEl:null,prevEl:null},a("init",(()=>{!1===t.params.navigation.enabled?u():(c(),l())})),a("toEdge fromEdge lock unlock",(()=>{l()})),a("destroy",(()=>{p()})),a("enable disable",(()=>{let{nextEl:e,prevEl:s}=t.navigation;e=k(e),s=k(s),t.enabled?l():[...e,...s].filter((e=>!!e)).forEach((e=>e.classList.add(t.params.navigation.lockClass)))})),a("click",((e,s)=>{let{nextEl:a,prevEl:r}=t.navigation;a=k(a),r=k(r);const n=s.target;let l=r.includes(n)||a.includes(n);if(t.isElement&&!l){const e=s.path||s.composedPath&&s.composedPath();e&&(l=e.find((e=>a.includes(e)||r.includes(e))))}if(t.params.navigation.hideOnClick&&!l){if(t.pagination&&t.params.pagination&&t.params.pagination.clickable&&(t.pagination.el===n||t.pagination.el.contains(n)))return;let e;a.length?e=a[0].classList.contains(t.params.navigation.hiddenClass):r.length&&(e=r[0].classList.contains(t.params.navigation.hiddenClass)),i(!0===e?"navigationShow":"navigationHide"),[...a,...r].filter((e=>!!e)).forEach((e=>e.classList.toggle(t.params.navigation.hiddenClass)))}}));const u=()=>{t.el.classList.add(...t.params.navigation.navigationDisabledClass.split(" ")),p()};Object.assign(t.navigation,{enable:()=>{t.el.classList.remove(...t.params.navigation.navigationDisabledClass.split(" ")),c(),l()},disable:u,update:l,init:c,destroy:p})}function he(e){return void 0===e&&(e=""),`.${e.trim().replace(/([\.:!+\/])/g,"\\$1").replace(/ /g,".")}`}function fe(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;const r="swiper-pagination";let n;s({pagination:{el:null,bulletElement:"span",clickable:!1,hideOnClick:!1,renderBullet:null,renderProgressbar:null,renderFraction:null,renderCustom:null,progressbarOpposite:!1,type:"bullets",dynamicBullets:!1,dynamicMainBullets:1,formatFractionCurrent:e=>e,formatFractionTotal:e=>e,bulletClass:`${r}-bullet`,bulletActiveClass:`${r}-bullet-active`,modifierClass:`${r}-`,currentClass:`${r}-current`,totalClass:`${r}-total`,hiddenClass:`${r}-hidden`,progressbarFillClass:`${r}-progressbar-fill`,progressbarOppositeClass:`${r}-progressbar-opposite`,clickableClass:`${r}-clickable`,lockClass:`${r}-lock`,horizontalClass:`${r}-horizontal`,verticalClass:`${r}-vertical`,paginationDisabledClass:`${r}-disabled`}}),t.pagination={el:null,bullets:[]};let l=0;function o(){return!t.params.pagination.el||!t.pagination.el||Array.isArray(t.pagination.el)&&0===t.pagination.el.length}function d(e,s){const{bulletActiveClass:a}=t.params.pagination;e&&(e=e[("prev"===s?"previous":"next")+"ElementSibling"])&&(e.classList.add(`${a}-${s}`),(e=e[("prev"===s?"previous":"next")+"ElementSibling"])&&e.classList.add(`${a}-${s}-${s}`))}function c(e){const s=e.target.closest(he(t.params.pagination.bulletClass));if(!s)return;e.preventDefault();const a=C(s)*t.params.slidesPerGroup;if(t.params.loop){if(t.realIndex===a)return;const e=(i=t.realIndex,r=a,n=t.slides.length,(r%=n)==1+(i%=n)?"next":r===i-1?"previous":void 0);"next"===e?t.slideNext():"previous"===e?t.slidePrev():t.slideToLoop(a)}else t.slideTo(a);var i,r,n}function p(){const e=t.rtl,s=t.params.pagination;if(o())return;let a,r,c=t.pagination.el;c=k(c);const p=t.virtual&&t.params.virtual.enabled?t.virtual.slides.length:t.slides.length,u=t.params.loop?Math.ceil(p/t.params.slidesPerGroup):t.snapGrid.length;if(t.params.loop?(r=t.previousRealIndex||0,a=t.params.slidesPerGroup>1?Math.floor(t.realIndex/t.params.slidesPerGroup):t.realIndex):void 0!==t.snapIndex?(a=t.snapIndex,r=t.previousSnapIndex):(r=t.previousIndex||0,a=t.activeIndex||0),"bullets"===s.type&&t.pagination.bullets&&t.pagination.bullets.length>0){const i=t.pagination.bullets;let o,p,u;if(s.dynamicBullets&&(n=P(i[0],t.isHorizontal()?"width":"height",!0),c.forEach((e=>{e.style[t.isHorizontal()?"width":"height"]=n*(s.dynamicMainBullets+4)+"px"})),s.dynamicMainBullets>1&&void 0!==r&&(l+=a-(r||0),l>s.dynamicMainBullets-1?l=s.dynamicMainBullets-1:l<0&&(l=0)),o=Math.max(a-l,0),p=o+(Math.min(i.length,s.dynamicMainBullets)-1),u=(p+o)/2),i.forEach((e=>{const t=[...["","-next","-next-next","-prev","-prev-prev","-main"].map((e=>`${s.bulletActiveClass}${e}`))].map((e=>"string"==typeof e&&e.includes(" ")?e.split(" "):e)).flat();e.classList.remove(...t)})),c.length>1)i.forEach((e=>{const i=C(e);i===a?e.classList.add(...s.bulletActiveClass.split(" ")):t.isElement&&e.setAttribute("part","bullet"),s.dynamicBullets&&(i>=o&&i<=p&&e.classList.add(...`${s.bulletActiveClass}-main`.split(" ")),i===o&&d(e,"prev"),i===p&&d(e,"next"))}));else{const e=i[a];if(e&&e.classList.add(...s.bulletActiveClass.split(" ")),t.isElement&&i.forEach(((e,t)=>{e.setAttribute("part",t===a?"bullet-active":"bullet")})),s.dynamicBullets){const e=i[o],t=i[p];for(let e=o;e<=p;e+=1)i[e]&&i[e].classList.add(...`${s.bulletActiveClass}-main`.split(" "));d(e,"prev"),d(t,"next")}}if(s.dynamicBullets){const a=Math.min(i.length,s.dynamicMainBullets+4),r=(n*a-n)/2-u*n,l=e?"right":"left";i.forEach((e=>{e.style[t.isHorizontal()?l:"top"]=`${r}px`}))}}c.forEach(((e,r)=>{if("fraction"===s.type&&(e.querySelectorAll(he(s.currentClass)).forEach((e=>{e.textContent=s.formatFractionCurrent(a+1)})),e.querySelectorAll(he(s.totalClass)).forEach((e=>{e.textContent=s.formatFractionTotal(u)}))),"progressbar"===s.type){let i;i=s.progressbarOpposite?t.isHorizontal()?"vertical":"horizontal":t.isHorizontal()?"horizontal":"vertical";const r=(a+1)/u;let n=1,l=1;"horizontal"===i?n=r:l=r,e.querySelectorAll(he(s.progressbarFillClass)).forEach((e=>{e.style.transform=`translate3d(0,0,0) scaleX(${n}) scaleY(${l})`,e.style.transitionDuration=`${t.params.speed}ms`}))}"custom"===s.type&&s.renderCustom?(e.innerHTML=s.renderCustom(t,a+1,u),0===r&&i("paginationRender",e)):(0===r&&i("paginationRender",e),i("paginationUpdate",e)),t.params.watchOverflow&&t.enabled&&e.classList[t.isLocked?"add":"remove"](s.lockClass)}))}function u(){const e=t.params.pagination;if(o())return;const s=t.virtual&&t.params.virtual.enabled?t.virtual.slides.length:t.grid&&t.params.grid.rows>1?t.slides.length/Math.ceil(t.params.grid.rows):t.slides.length;let a=t.pagination.el;a=k(a);let r="";if("bullets"===e.type){let a=t.params.loop?Math.ceil(s/t.params.slidesPerGroup):t.snapGrid.length;t.params.freeMode&&t.params.freeMode.enabled&&a>s&&(a=s);for(let s=0;s<a;s+=1)e.renderBullet?r+=e.renderBullet.call(t,s,e.bulletClass):r+=`<${e.bulletElement} ${t.isElement?'part="bullet"':""} class="${e.bulletClass}"></${e.bulletElement}>`}"fraction"===e.type&&(r=e.renderFraction?e.renderFraction.call(t,e.currentClass,e.totalClass):`<span class="${e.currentClass}"></span> / <span class="${e.totalClass}"></span>`),"progressbar"===e.type&&(r=e.renderProgressbar?e.renderProgressbar.call(t,e.progressbarFillClass):`<span class="${e.progressbarFillClass}"></span>`),t.pagination.bullets=[],a.forEach((s=>{"custom"!==e.type&&(s.innerHTML=r||""),"bullets"===e.type&&t.pagination.bullets.push(...s.querySelectorAll(he(e.bulletClass)))})),"custom"!==e.type&&i("paginationRender",a[0])}function m(){t.params.pagination=ue(t,t.originalParams.pagination,t.params.pagination,{el:"swiper-pagination"});const e=t.params.pagination;if(!e.el)return;let s;"string"==typeof e.el&&t.isElement&&(s=t.el.querySelector(e.el)),s||"string"!=typeof e.el||(s=[...document.querySelectorAll(e.el)]),s||(s=e.el),s&&0!==s.length&&(t.params.uniqueNavElements&&"string"==typeof e.el&&Array.isArray(s)&&s.length>1&&(s=[...t.el.querySelectorAll(e.el)],s.length>1&&(s=s.find((e=>L(e,".swiper")[0]===t.el)))),Array.isArray(s)&&1===s.length&&(s=s[0]),Object.assign(t.pagination,{el:s}),s=k(s),s.forEach((s=>{"bullets"===e.type&&e.clickable&&s.classList.add(...(e.clickableClass||"").split(" ")),s.classList.add(e.modifierClass+e.type),s.classList.add(t.isHorizontal()?e.horizontalClass:e.verticalClass),"bullets"===e.type&&e.dynamicBullets&&(s.classList.add(`${e.modifierClass}${e.type}-dynamic`),l=0,e.dynamicMainBullets<1&&(e.dynamicMainBullets=1)),"progressbar"===e.type&&e.progressbarOpposite&&s.classList.add(e.progressbarOppositeClass),e.clickable&&s.addEventListener("click",c),t.enabled||s.classList.add(e.lockClass)})))}function h(){const e=t.params.pagination;if(o())return;let s=t.pagination.el;s&&(s=k(s),s.forEach((s=>{s.classList.remove(e.hiddenClass),s.classList.remove(e.modifierClass+e.type),s.classList.remove(t.isHorizontal()?e.horizontalClass:e.verticalClass),e.clickable&&(s.classList.remove(...(e.clickableClass||"").split(" ")),s.removeEventListener("click",c))}))),t.pagination.bullets&&t.pagination.bullets.forEach((t=>t.classList.remove(...e.bulletActiveClass.split(" "))))}a("changeDirection",(()=>{if(!t.pagination||!t.pagination.el)return;const e=t.params.pagination;let{el:s}=t.pagination;s=k(s),s.forEach((s=>{s.classList.remove(e.horizontalClass,e.verticalClass),s.classList.add(t.isHorizontal()?e.horizontalClass:e.verticalClass)}))})),a("init",(()=>{!1===t.params.pagination.enabled?f():(m(),u(),p())})),a("activeIndexChange",(()=>{void 0===t.snapIndex&&p()})),a("snapIndexChange",(()=>{p()})),a("snapGridLengthChange",(()=>{u(),p()})),a("destroy",(()=>{h()})),a("enable disable",(()=>{let{el:e}=t.pagination;e&&(e=k(e),e.forEach((e=>e.classList[t.enabled?"remove":"add"](t.params.pagination.lockClass))))})),a("lock unlock",(()=>{p()})),a("click",((e,s)=>{const a=s.target,r=k(t.pagination.el);if(t.params.pagination.el&&t.params.pagination.hideOnClick&&r&&r.length>0&&!a.classList.contains(t.params.pagination.bulletClass)){if(t.navigation&&(t.navigation.nextEl&&a===t.navigation.nextEl||t.navigation.prevEl&&a===t.navigation.prevEl))return;const e=r[0].classList.contains(t.params.pagination.hiddenClass);i(!0===e?"paginationShow":"paginationHide"),r.forEach((e=>e.classList.toggle(t.params.pagination.hiddenClass)))}}));const f=()=>{t.el.classList.add(t.params.pagination.paginationDisabledClass);let{el:e}=t.pagination;e&&(e=k(e),e.forEach((e=>e.classList.add(t.params.pagination.paginationDisabledClass)))),h()};Object.assign(t.pagination,{enable:()=>{t.el.classList.remove(t.params.pagination.paginationDisabledClass);let{el:e}=t.pagination;e&&(e=k(e),e.forEach((e=>e.classList.remove(t.params.pagination.paginationDisabledClass)))),m(),u(),p()},disable:f,render:u,update:p,init:m,destroy:h})}function ge(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;const r=d();let n,l,o,c,p=!1,h=null,f=null;function g(){if(!t.params.scrollbar.el||!t.scrollbar.el)return;const{scrollbar:e,rtlTranslate:s}=t,{dragEl:a,el:i}=e,r=t.params.scrollbar,n=t.params.loop?t.progressLoop:t.progress;let d=l,c=(o-l)*n;s?(c=-c,c>0?(d=l-c,c=0):-c+l>o&&(d=o+c)):c<0?(d=l+c,c=0):c+l>o&&(d=o-c),t.isHorizontal()?(a.style.transform=`translate3d(${c}px, 0, 0)`,a.style.width=`${d}px`):(a.style.transform=`translate3d(0px, ${c}px, 0)`,a.style.height=`${d}px`),r.hide&&(clearTimeout(h),i.style.opacity=1,h=setTimeout((()=>{i.style.opacity=0,i.style.transitionDuration="400ms"}),1e3))}function v(){if(!t.params.scrollbar.el||!t.scrollbar.el)return;const{scrollbar:e}=t,{dragEl:s,el:a}=e;s.style.width="",s.style.height="",o=t.isHorizontal()?a.offsetWidth:a.offsetHeight,c=t.size/(t.virtualSize+t.params.slidesOffsetBefore-(t.params.centeredSlides?t.snapGrid[0]:0)),l="auto"===t.params.scrollbar.dragSize?o*c:parseInt(t.params.scrollbar.dragSize,10),t.isHorizontal()?s.style.width=`${l}px`:s.style.height=`${l}px`,a.style.display=c>=1?"none":"",t.params.scrollbar.hide&&(a.style.opacity=0),t.params.watchOverflow&&t.enabled&&e.el.classList[t.isLocked?"add":"remove"](t.params.scrollbar.lockClass)}function b(e){return t.isHorizontal()?e.clientX:e.clientY}function w(e){const{scrollbar:s,rtlTranslate:a}=t,{el:i}=s;let r;r=(b(e)-E(i)[t.isHorizontal()?"left":"top"]-(null!==n?n:l/2))/(o-l),r=Math.max(Math.min(r,1),0),a&&(r=1-r);const d=t.minTranslate()+(t.maxTranslate()-t.minTranslate())*r;t.updateProgress(d),t.setTranslate(d),t.updateActiveIndex(),t.updateSlidesClasses()}function y(e){const s=t.params.scrollbar,{scrollbar:a,wrapperEl:r}=t,{el:l,dragEl:o}=a;p=!0,n=e.target===o?b(e)-e.target.getBoundingClientRect()[t.isHorizontal()?"left":"top"]:null,e.preventDefault(),e.stopPropagation(),r.style.transitionDuration="100ms",o.style.transitionDuration="100ms",w(e),clearTimeout(f),l.style.transitionDuration="0ms",s.hide&&(l.style.opacity=1),t.params.cssMode&&(t.wrapperEl.style["scroll-snap-type"]="none"),i("scrollbarDragStart",e)}function x(e){const{scrollbar:s,wrapperEl:a}=t,{el:r,dragEl:n}=s;p&&(e.preventDefault&&e.cancelable?e.preventDefault():e.returnValue=!1,w(e),a.style.transitionDuration="0ms",r.style.transitionDuration="0ms",n.style.transitionDuration="0ms",i("scrollbarDragMove",e))}function S(e){const s=t.params.scrollbar,{scrollbar:a,wrapperEl:r}=t,{el:n}=a;p&&(p=!1,t.params.cssMode&&(t.wrapperEl.style["scroll-snap-type"]="",r.style.transitionDuration=""),s.hide&&(clearTimeout(f),f=m((()=>{n.style.opacity=0,n.style.transitionDuration="400ms"}),1e3)),i("scrollbarDragEnd",e),s.snapOnRelease&&t.slideToClosest())}function M(e){const{scrollbar:s,params:a}=t,i=s.el;if(!i)return;const n=i,l=!!a.passiveListeners&&{passive:!1,capture:!1},o=!!a.passiveListeners&&{passive:!0,capture:!1};if(!n)return;const d="on"===e?"addEventListener":"removeEventListener";n[d]("pointerdown",y,l),r[d]("pointermove",x,l),r[d]("pointerup",S,o)}function C(){const{scrollbar:e,el:s}=t;t.params.scrollbar=ue(t,t.originalParams.scrollbar,t.params.scrollbar,{el:"swiper-scrollbar"});const a=t.params.scrollbar;if(!a.el)return;let i,n;if("string"==typeof a.el&&t.isElement&&(i=t.el.querySelector(a.el)),i||"string"!=typeof a.el)i||(i=a.el);else if(i=r.querySelectorAll(a.el),!i.length)return;t.params.uniqueNavElements&&"string"==typeof a.el&&i.length>1&&1===s.querySelectorAll(a.el).length&&(i=s.querySelector(a.el)),i.length>0&&(i=i[0]),i.classList.add(t.isHorizontal()?a.horizontalClass:a.verticalClass),i&&(n=i.querySelector(he(t.params.scrollbar.dragClass)),n||(n=T("div",t.params.scrollbar.dragClass),i.append(n))),Object.assign(e,{el:i,dragEl:n}),a.draggable&&t.params.scrollbar.el&&t.scrollbar.el&&M("on"),i&&i.classList[t.enabled?"remove":"add"](...u(t.params.scrollbar.lockClass))}function L(){const e=t.params.scrollbar,s=t.scrollbar.el;s&&s.classList.remove(...u(t.isHorizontal()?e.horizontalClass:e.verticalClass)),t.params.scrollbar.el&&t.scrollbar.el&&M("off")}s({scrollbar:{el:null,dragSize:"auto",hide:!1,draggable:!1,snapOnRelease:!0,lockClass:"swiper-scrollbar-lock",dragClass:"swiper-scrollbar-drag",scrollbarDisabledClass:"swiper-scrollbar-disabled",horizontalClass:"swiper-scrollbar-horizontal",verticalClass:"swiper-scrollbar-vertical"}}),t.scrollbar={el:null,dragEl:null},a("changeDirection",(()=>{if(!t.scrollbar||!t.scrollbar.el)return;const e=t.params.scrollbar;let{el:s}=t.scrollbar;s=k(s),s.forEach((s=>{s.classList.remove(e.horizontalClass,e.verticalClass),s.classList.add(t.isHorizontal()?e.horizontalClass:e.verticalClass)}))})),a("init",(()=>{!1===t.params.scrollbar.enabled?P():(C(),v(),g())})),a("update resize observerUpdate lock unlock changeDirection",(()=>{v()})),a("setTranslate",(()=>{g()})),a("setTransition",((e,s)=>{!function(e){t.params.scrollbar.el&&t.scrollbar.el&&(t.scrollbar.dragEl.style.transitionDuration=`${e}ms`)}(s)})),a("enable disable",(()=>{const{el:e}=t.scrollbar;e&&e.classList[t.enabled?"remove":"add"](...u(t.params.scrollbar.lockClass))})),a("destroy",(()=>{L()}));const P=()=>{t.el.classList.add(...u(t.params.scrollbar.scrollbarDisabledClass)),t.scrollbar.el&&t.scrollbar.el.classList.add(...u(t.params.scrollbar.scrollbarDisabledClass)),L()};Object.assign(t.scrollbar,{enable:()=>{t.el.classList.remove(...u(t.params.scrollbar.scrollbarDisabledClass)),t.scrollbar.el&&t.scrollbar.el.classList.remove(...u(t.params.scrollbar.scrollbarDisabledClass)),C(),v(),g()},disable:P,updateSize:v,setTranslate:g,init:C,destroy:L})}function ve(e){let t,s,{swiper:a,extendParams:i,on:r,emit:n,params:l}=e;a.autoplay={running:!1,paused:!1,timeLeft:0},i({autoplay:{enabled:!1,delay:3e3,waitForTransition:!0,disableOnInteraction:!1,stopOnLastSlide:!1,reverseDirection:!1,pauseOnMouseEnter:!1}});let o,c,p,u,m,h,f,g,v=l&&l.autoplay?l.autoplay.delay:3e3,b=l&&l.autoplay?l.autoplay.delay:3e3,w=(new Date).getTime();function y(e){a&&!a.destroyed&&a.wrapperEl&&e.target===a.wrapperEl&&(a.wrapperEl.removeEventListener("transitionend",y),g||e.detail&&e.detail.bySwiperTouchMove||C())}const x=()=>{if(a.destroyed||!a.autoplay.running)return;a.autoplay.paused?c=!0:c&&(b=o,c=!1);const e=a.autoplay.paused?o:w+b-(new Date).getTime();a.autoplay.timeLeft=e,n("autoplayTimeLeft",e,e/v),s=requestAnimationFrame((()=>{x()}))},S=e=>{if(a.destroyed||!a.autoplay.running)return;cancelAnimationFrame(s),x();let i=void 0===e?a.params.autoplay.delay:e;v=a.params.autoplay.delay,b=a.params.autoplay.delay;const r=(()=>{let e;if(e=a.virtual&&a.params.virtual.enabled?a.slides.find((e=>e.classList.contains("swiper-slide-active"))):a.slides[a.activeIndex],!e)return;return parseInt(e.getAttribute("data-swiper-autoplay"),10)})();!Number.isNaN(r)&&r>0&&void 0===e&&(i=r,v=r,b=r),o=i;const l=a.params.speed,d=()=>{a&&!a.destroyed&&(a.params.autoplay.reverseDirection?!a.isBeginning||a.params.loop||a.params.rewind?(a.slidePrev(l,!0,!0),n("autoplay")):a.params.autoplay.stopOnLastSlide||(a.slideTo(a.slides.length-1,l,!0,!0),n("autoplay")):!a.isEnd||a.params.loop||a.params.rewind?(a.slideNext(l,!0,!0),n("autoplay")):a.params.autoplay.stopOnLastSlide||(a.slideTo(0,l,!0,!0),n("autoplay")),a.params.cssMode&&(w=(new Date).getTime(),requestAnimationFrame((()=>{S()}))))};return i>0?(clearTimeout(t),t=setTimeout((()=>{d()}),i)):requestAnimationFrame((()=>{d()})),i},T=()=>{w=(new Date).getTime(),a.autoplay.running=!0,S(),n("autoplayStart")},E=()=>{a.autoplay.running=!1,clearTimeout(t),cancelAnimationFrame(s),n("autoplayStop")},M=(e,s)=>{if(a.destroyed||!a.autoplay.running)return;clearTimeout(t),e||(f=!0);const i=()=>{n("autoplayPause"),a.params.autoplay.waitForTransition?a.wrapperEl.addEventListener("transitionend",y):C()};if(a.autoplay.paused=!0,s)return h&&(o=a.params.autoplay.delay),h=!1,void i();const r=o||a.params.autoplay.delay;o=r-((new Date).getTime()-w),a.isEnd&&o<0&&!a.params.loop||(o<0&&(o=0),i())},C=()=>{a.isEnd&&o<0&&!a.params.loop||a.destroyed||!a.autoplay.running||(w=(new Date).getTime(),f?(f=!1,S(o)):S(),a.autoplay.paused=!1,n("autoplayResume"))},L=()=>{if(a.destroyed||!a.autoplay.running)return;const e=d();"hidden"===e.visibilityState&&(f=!0,M(!0)),"visible"===e.visibilityState&&C()},P=e=>{"mouse"===e.pointerType&&(f=!0,g=!0,a.animating||a.autoplay.paused||M(!0))},k=e=>{"mouse"===e.pointerType&&(g=!1,a.autoplay.paused&&C())};r("init",(()=>{a.params.autoplay.enabled&&(a.params.autoplay.pauseOnMouseEnter&&(a.el.addEventListener("pointerenter",P),a.el.addEventListener("pointerleave",k)),d().addEventListener("visibilitychange",L),T())})),r("destroy",(()=>{a.el&&"string"!=typeof a.el&&(a.el.removeEventListener("pointerenter",P),a.el.removeEventListener("pointerleave",k)),d().removeEventListener("visibilitychange",L),a.autoplay.running&&E()})),r("_freeModeStaticRelease",(()=>{(u||f)&&C()})),r("_freeModeNoMomentumRelease",(()=>{a.params.autoplay.disableOnInteraction?E():M(!0,!0)})),r("beforeTransitionStart",((e,t,s)=>{!a.destroyed&&a.autoplay.running&&(s||!a.params.autoplay.disableOnInteraction?M(!0,!0):E())})),r("sliderFirstMove",(()=>{!a.destroyed&&a.autoplay.running&&(a.params.autoplay.disableOnInteraction?E():(p=!0,u=!1,f=!1,m=setTimeout((()=>{f=!0,u=!0,M(!0)}),200)))})),r("touchEnd",(()=>{if(!a.destroyed&&a.autoplay.running&&p){if(clearTimeout(m),clearTimeout(t),a.params.autoplay.disableOnInteraction)return u=!1,void(p=!1);u&&a.params.cssMode&&C(),u=!1,p=!1}})),r("slideChange",(()=>{!a.destroyed&&a.autoplay.running&&(h=!0)})),Object.assign(a.autoplay,{start:T,stop:E,pause:M,resume:C})}function be(e){const{effect:t,swiper:s,on:a,setTranslate:i,setTransition:r,overwriteParams:n,perspective:l,recreateShadows:o,getEffectParams:d}=e;let c;a("beforeInit",(()=>{if(s.params.effect!==t)return;s.classNames.push(`${s.params.containerModifierClass}${t}`),l&&l()&&s.classNames.push(`${s.params.containerModifierClass}3d`);const e=n?n():{};Object.assign(s.params,e),Object.assign(s.originalParams,e)})),a("setTranslate",(()=>{s.params.effect===t&&i()})),a("setTransition",((e,a)=>{s.params.effect===t&&r(a)})),a("transitionEnd",(()=>{if(s.params.effect===t&&o){if(!d||!d().slideShadows)return;s.slides.forEach((e=>{e.querySelectorAll(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").forEach((e=>e.remove()))})),o()}})),a("virtualUpdate",(()=>{s.params.effect===t&&(s.slides.length||(c=!0),requestAnimationFrame((()=>{c&&s.slides&&s.slides.length&&(i(),c=!1)})))}))}function we(e,t){const s=y(t);return s!==t&&(s.style.backfaceVisibility="hidden",s.style["-webkit-backface-visibility"]="hidden"),s}function ye(e){let{swiper:t,duration:s,transformElements:a,allSlides:i}=e;const{activeIndex:r}=t;if(t.params.virtualTranslate&&0!==s){let e,s=!1;e=i?a:a.filter((e=>{const s=e.classList.contains("swiper-slide-transform")?(e=>{if(!e.parentElement)return t.slides.find((t=>t.shadowRoot&&t.shadowRoot===e.parentNode));return e.parentElement})(e):e;return t.getSlideIndex(s)===r})),e.forEach((e=>{!function(e,t){t&&e.addEventListener("transitionend",(function s(a){a.target===e&&(t.call(e,a),e.removeEventListener("transitionend",s))}))}(e,(()=>{if(s)return;if(!t||t.destroyed)return;s=!0,t.animating=!1;const e=new window.CustomEvent("transitionend",{bubbles:!0,cancelable:!0});t.wrapperEl.dispatchEvent(e)}))}))}}function xe(e){let{swiper:t,extendParams:s,on:a}=e;s({fadeEffect:{crossFade:!1}});be({effect:"fade",swiper:t,on:a,setTranslate:()=>{const{slides:e}=t;t.params.fadeEffect;for(let s=0;s<e.length;s+=1){const e=t.slides[s];let a=-e.swiperSlideOffset;t.params.virtualTranslate||(a-=t.translate);let i=0;t.isHorizontal()||(i=a,a=0);const r=t.params.fadeEffect.crossFade?Math.max(1-Math.abs(e.progress),0):1+Math.min(Math.max(e.progress,-1),0),n=we(0,e);n.style.opacity=r,n.style.transform=`translate3d(${a}px, ${i}px, 0px)`}},setTransition:e=>{const s=t.slides.map((e=>y(e)));s.forEach((t=>{t.style.transitionDuration=`${e}ms`})),ye({swiper:t,duration:e,transformElements:s,allSlides:!0})},overwriteParams:()=>({slidesPerView:1,slidesPerGroup:1,watchSlidesProgress:!0,spaceBetween:0,virtualTranslate:!t.params.cssMode})})}function Se(e){let{swiper:t,extendParams:s,on:a}=e;s({cubeEffect:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94}});const i=(e,t,s)=>{let a=s?e.querySelector(".swiper-slide-shadow-left"):e.querySelector(".swiper-slide-shadow-top"),i=s?e.querySelector(".swiper-slide-shadow-right"):e.querySelector(".swiper-slide-shadow-bottom");a||(a=T("div",("swiper-slide-shadow-cube swiper-slide-shadow-"+(s?"left":"top")).split(" ")),e.append(a)),i||(i=T("div",("swiper-slide-shadow-cube swiper-slide-shadow-"+(s?"right":"bottom")).split(" ")),e.append(i)),a&&(a.style.opacity=Math.max(-t,0)),i&&(i.style.opacity=Math.max(t,0))};be({effect:"cube",swiper:t,on:a,setTranslate:()=>{const{el:e,wrapperEl:s,slides:a,width:r,height:n,rtlTranslate:l,size:o,browser:d}=t,c=O(t),p=t.params.cubeEffect,u=t.isHorizontal(),m=t.virtual&&t.params.virtual.enabled;let h,f=0;p.shadow&&(u?(h=t.wrapperEl.querySelector(".swiper-cube-shadow"),h||(h=T("div","swiper-cube-shadow"),t.wrapperEl.append(h)),h.style.height=`${r}px`):(h=e.querySelector(".swiper-cube-shadow"),h||(h=T("div","swiper-cube-shadow"),e.append(h))));for(let e=0;e<a.length;e+=1){const t=a[e];let s=e;m&&(s=parseInt(t.getAttribute("data-swiper-slide-index"),10));let r=90*s,n=Math.floor(r/360);l&&(r=-r,n=Math.floor(-r/360));const d=Math.max(Math.min(t.progress,1),-1);let h=0,g=0,v=0;s%4==0?(h=4*-n*o,v=0):(s-1)%4==0?(h=0,v=4*-n*o):(s-2)%4==0?(h=o+4*n*o,v=o):(s-3)%4==0&&(h=-o,v=3*o+4*o*n),l&&(h=-h),u||(g=h,h=0);const b=`rotateX(${c(u?0:-r)}deg) rotateY(${c(u?r:0)}deg) translate3d(${h}px, ${g}px, ${v}px)`;d<=1&&d>-1&&(f=90*s+90*d,l&&(f=90*-s-90*d)),t.style.transform=b,p.slideShadows&&i(t,d,u)}if(s.style.transformOrigin=`50% 50% -${o/2}px`,s.style["-webkit-transform-origin"]=`50% 50% -${o/2}px`,p.shadow)if(u)h.style.transform=`translate3d(0px, ${r/2+p.shadowOffset}px, ${-r/2}px) rotateX(89.99deg) rotateZ(0deg) scale(${p.shadowScale})`;else{const e=Math.abs(f)-90*Math.floor(Math.abs(f)/90),t=1.5-(Math.sin(2*e*Math.PI/360)/2+Math.cos(2*e*Math.PI/360)/2),s=p.shadowScale,a=p.shadowScale/t,i=p.shadowOffset;h.style.transform=`scale3d(${s}, 1, ${a}) translate3d(0px, ${n/2+i}px, ${-n/2/a}px) rotateX(-89.99deg)`}const g=(d.isSafari||d.isWebView)&&d.needPerspectiveFix?-o/2:0;s.style.transform=`translate3d(0px,0,${g}px) rotateX(${c(t.isHorizontal()?0:f)}deg) rotateY(${c(t.isHorizontal()?-f:0)}deg)`,s.style.setProperty("--swiper-cube-translate-z",`${g}px`)},setTransition:e=>{const{el:s,slides:a}=t;if(a.forEach((t=>{t.style.transitionDuration=`${e}ms`,t.querySelectorAll(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").forEach((t=>{t.style.transitionDuration=`${e}ms`}))})),t.params.cubeEffect.shadow&&!t.isHorizontal()){const t=s.querySelector(".swiper-cube-shadow");t&&(t.style.transitionDuration=`${e}ms`)}},recreateShadows:()=>{const e=t.isHorizontal();t.slides.forEach((t=>{const s=Math.max(Math.min(t.progress,1),-1);i(t,s,e)}))},getEffectParams:()=>t.params.cubeEffect,perspective:()=>!0,overwriteParams:()=>({slidesPerView:1,slidesPerGroup:1,watchSlidesProgress:!0,resistanceRatio:0,spaceBetween:0,centeredSlides:!1,virtualTranslate:!0})})}function Te(e,t,s){const a=`swiper-slide-shadow${s?`-${s}`:""}${e?` swiper-slide-shadow-${e}`:""}`,i=y(t);let r=i.querySelector(`.${a.split(" ").join(".")}`);return r||(r=T("div",a.split(" ")),i.append(r)),r}function Ee(e){let{swiper:t,extendParams:s,on:a}=e;s({flipEffect:{slideShadows:!0,limitRotation:!0}});const i=(e,s)=>{let a=t.isHorizontal()?e.querySelector(".swiper-slide-shadow-left"):e.querySelector(".swiper-slide-shadow-top"),i=t.isHorizontal()?e.querySelector(".swiper-slide-shadow-right"):e.querySelector(".swiper-slide-shadow-bottom");a||(a=Te("flip",e,t.isHorizontal()?"left":"top")),i||(i=Te("flip",e,t.isHorizontal()?"right":"bottom")),a&&(a.style.opacity=Math.max(-s,0)),i&&(i.style.opacity=Math.max(s,0))};be({effect:"flip",swiper:t,on:a,setTranslate:()=>{const{slides:e,rtlTranslate:s}=t,a=t.params.flipEffect,r=O(t);for(let n=0;n<e.length;n+=1){const l=e[n];let o=l.progress;t.params.flipEffect.limitRotation&&(o=Math.max(Math.min(l.progress,1),-1));const d=l.swiperSlideOffset;let c=-180*o,p=0,u=t.params.cssMode?-d-t.translate:-d,m=0;t.isHorizontal()?s&&(c=-c):(m=u,u=0,p=-c,c=0),l.style.zIndex=-Math.abs(Math.round(o))+e.length,a.slideShadows&&i(l,o);const h=`translate3d(${u}px, ${m}px, 0px) rotateX(${r(p)}deg) rotateY(${r(c)}deg)`;we(0,l).style.transform=h}},setTransition:e=>{const s=t.slides.map((e=>y(e)));s.forEach((t=>{t.style.transitionDuration=`${e}ms`,t.querySelectorAll(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").forEach((t=>{t.style.transitionDuration=`${e}ms`}))})),ye({swiper:t,duration:e,transformElements:s})},recreateShadows:()=>{t.params.flipEffect,t.slides.forEach((e=>{let s=e.progress;t.params.flipEffect.limitRotation&&(s=Math.max(Math.min(e.progress,1),-1)),i(e,s)}))},getEffectParams:()=>t.params.flipEffect,perspective:()=>!0,overwriteParams:()=>({slidesPerView:1,slidesPerGroup:1,watchSlidesProgress:!0,spaceBetween:0,virtualTranslate:!t.params.cssMode})})}function Me(e){let{swiper:t,extendParams:s,on:a}=e;s({coverflowEffect:{rotate:50,stretch:0,depth:100,scale:1,modifier:1,slideShadows:!0}});be({effect:"coverflow",swiper:t,on:a,setTranslate:()=>{const{width:e,height:s,slides:a,slidesSizesGrid:i}=t,r=t.params.coverflowEffect,n=t.isHorizontal(),l=t.translate,o=n?e/2-l:s/2-l,d=n?r.rotate:-r.rotate,c=r.depth,p=O(t);for(let e=0,t=a.length;e<t;e+=1){const t=a[e],s=i[e],l=(o-t.swiperSlideOffset-s/2)/s,u="function"==typeof r.modifier?r.modifier(l):l*r.modifier;let m=n?d*u:0,h=n?0:d*u,f=-c*Math.abs(u),g=r.stretch;"string"==typeof g&&-1!==g.indexOf("%")&&(g=parseFloat(r.stretch)/100*s);let v=n?0:g*u,b=n?g*u:0,w=1-(1-r.scale)*Math.abs(u);Math.abs(b)<.001&&(b=0),Math.abs(v)<.001&&(v=0),Math.abs(f)<.001&&(f=0),Math.abs(m)<.001&&(m=0),Math.abs(h)<.001&&(h=0),Math.abs(w)<.001&&(w=0);const y=`translate3d(${b}px,${v}px,${f}px)  rotateX(${p(h)}deg) rotateY(${p(m)}deg) scale(${w})`;if(we(0,t).style.transform=y,t.style.zIndex=1-Math.abs(Math.round(u)),r.slideShadows){let e=n?t.querySelector(".swiper-slide-shadow-left"):t.querySelector(".swiper-slide-shadow-top"),s=n?t.querySelector(".swiper-slide-shadow-right"):t.querySelector(".swiper-slide-shadow-bottom");e||(e=Te("coverflow",t,n?"left":"top")),s||(s=Te("coverflow",t,n?"right":"bottom")),e&&(e.style.opacity=u>0?u:0),s&&(s.style.opacity=-u>0?-u:0)}}},setTransition:e=>{t.slides.map((e=>y(e))).forEach((t=>{t.style.transitionDuration=`${e}ms`,t.querySelectorAll(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").forEach((t=>{t.style.transitionDuration=`${e}ms`}))}))},perspective:()=>!0,overwriteParams:()=>({watchSlidesProgress:!0})})}function Ce(e){let{swiper:t,extendParams:s,on:a}=e;s({creativeEffect:{limitProgress:1,shadowPerProgress:!1,progressMultiplier:1,perspective:!0,prev:{translate:[0,0,0],rotate:[0,0,0],opacity:1,scale:1},next:{translate:[0,0,0],rotate:[0,0,0],opacity:1,scale:1}}});const i=e=>"string"==typeof e?e:`${e}px`;be({effect:"creative",swiper:t,on:a,setTranslate:()=>{const{slides:e,wrapperEl:s,slidesSizesGrid:a}=t,r=t.params.creativeEffect,{progressMultiplier:n}=r,l=t.params.centeredSlides,o=O(t);if(l){const e=a[0]/2-t.params.slidesOffsetBefore||0;s.style.transform=`translateX(calc(50% - ${e}px))`}for(let s=0;s<e.length;s+=1){const a=e[s],d=a.progress,c=Math.min(Math.max(a.progress,-r.limitProgress),r.limitProgress);let p=c;l||(p=Math.min(Math.max(a.originalProgress,-r.limitProgress),r.limitProgress));const u=a.swiperSlideOffset,m=[t.params.cssMode?-u-t.translate:-u,0,0],h=[0,0,0];let f=!1;t.isHorizontal()||(m[1]=m[0],m[0]=0);let g={translate:[0,0,0],rotate:[0,0,0],scale:1,opacity:1};c<0?(g=r.next,f=!0):c>0&&(g=r.prev,f=!0),m.forEach(((e,t)=>{m[t]=`calc(${e}px + (${i(g.translate[t])} * ${Math.abs(c*n)}))`})),h.forEach(((e,t)=>{let s=g.rotate[t]*Math.abs(c*n);h[t]=s})),a.style.zIndex=-Math.abs(Math.round(d))+e.length;const v=m.join(", "),b=`rotateX(${o(h[0])}deg) rotateY(${o(h[1])}deg) rotateZ(${o(h[2])}deg)`,w=p<0?`scale(${1+(1-g.scale)*p*n})`:`scale(${1-(1-g.scale)*p*n})`,y=p<0?1+(1-g.opacity)*p*n:1-(1-g.opacity)*p*n,x=`translate3d(${v}) ${b} ${w}`;if(f&&g.shadow||!f){let e=a.querySelector(".swiper-slide-shadow");if(!e&&g.shadow&&(e=Te("creative",a)),e){const t=r.shadowPerProgress?c*(1/r.limitProgress):c;e.style.opacity=Math.min(Math.max(Math.abs(t),0),1)}}const S=we(0,a);S.style.transform=x,S.style.opacity=y,g.origin&&(S.style.transformOrigin=g.origin)}},setTransition:e=>{const s=t.slides.map((e=>y(e)));s.forEach((t=>{t.style.transitionDuration=`${e}ms`,t.querySelectorAll(".swiper-slide-shadow").forEach((t=>{t.style.transitionDuration=`${e}ms`}))})),ye({swiper:t,duration:e,transformElements:s,allSlides:!0})},perspective:()=>t.params.creativeEffect.perspective,overwriteParams:()=>({watchSlidesProgress:!0,virtualTranslate:!t.params.cssMode})})}function Le(e){let{swiper:t,extendParams:s,on:a}=e;s({cardsEffect:{slideShadows:!0,rotate:!0,perSlideRotate:2,perSlideOffset:8}});be({effect:"cards",swiper:t,on:a,setTranslate:()=>{const{slides:e,activeIndex:s,rtlTranslate:a}=t,i=t.params.cardsEffect,{startTranslate:r,isTouched:n}=t.touchEventsData,l=a?-t.translate:t.translate;for(let o=0;o<e.length;o+=1){const d=e[o],c=d.progress,p=Math.min(Math.max(c,-4),4);let u=d.swiperSlideOffset;t.params.centeredSlides&&!t.params.cssMode&&(t.wrapperEl.style.transform=`translateX(${t.minTranslate()}px)`),t.params.centeredSlides&&t.params.cssMode&&(u-=e[0].swiperSlideOffset);let m=t.params.cssMode?-u-t.translate:-u,h=0;const f=-100*Math.abs(p);let g=1,v=-i.perSlideRotate*p,b=i.perSlideOffset-.75*Math.abs(p);const w=t.virtual&&t.params.virtual.enabled?t.virtual.from+o:o,y=(w===s||w===s-1)&&p>0&&p<1&&(n||t.params.cssMode)&&l<r,x=(w===s||w===s+1)&&p<0&&p>-1&&(n||t.params.cssMode)&&l>r;if(y||x){const e=(1-Math.abs((Math.abs(p)-.5)/.5))**.5;v+=-28*p*e,g+=-.5*e,b+=96*e,h=-25*e*Math.abs(p)+"%"}if(m=p<0?`calc(${m}px ${a?"-":"+"} (${b*Math.abs(p)}%))`:p>0?`calc(${m}px ${a?"-":"+"} (-${b*Math.abs(p)}%))`:`${m}px`,!t.isHorizontal()){const e=h;h=m,m=e}const S=p<0?""+(1+(1-g)*p):""+(1-(1-g)*p),T=`\n        translate3d(${m}, ${h}, ${f}px)\n        rotateZ(${i.rotate?a?-v:v:0}deg)\n        scale(${S})\n      `;if(i.slideShadows){let e=d.querySelector(".swiper-slide-shadow");e||(e=Te("cards",d)),e&&(e.style.opacity=Math.min(Math.max((Math.abs(p)-.5)/.5,0),1))}d.style.zIndex=-Math.abs(Math.round(c))+e.length;we(0,d).style.transform=T}},setTransition:e=>{const s=t.slides.map((e=>y(e)));s.forEach((t=>{t.style.transitionDuration=`${e}ms`,t.querySelectorAll(".swiper-slide-shadow").forEach((t=>{t.style.transitionDuration=`${e}ms`}))})),ye({swiper:t,duration:e,transformElements:s})},perspective:()=>!0,overwriteParams:()=>({_loopSwapReset:!1,watchSlidesProgress:!0,loopAdditionalSlides:t.params.cardsEffect.rotate?3:2,centeredSlides:!0,virtualTranslate:!t.params.cssMode})})}function Pe(e,t){var s=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),s.push.apply(s,a)}return s}function ke(e){for(var t=1;t<arguments.length;t++){var s=null!=arguments[t]?arguments[t]:{};t%2?Pe(Object(s),!0).forEach((function(t){Oe(e,t,s[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(s)):Pe(Object(s)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(s,t))}))}return e}function Oe(e,t,s){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var s=e[Symbol.toPrimitive];if(void 0!==s){var a=s.call(e,t||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:s,enumerable:!0,configurable:!0,writable:!0}):e[t]=s,e}Object.keys(le).forEach((e=>{Object.keys(le[e]).forEach((t=>{de.prototype[t]=le[e][t]}))})),de.use([function(e){let{swiper:t,on:s,emit:a}=e;const i=p();let r=null,n=null;const l=()=>{t&&!t.destroyed&&t.initialized&&(a("beforeResize"),a("resize"))},o=()=>{t&&!t.destroyed&&t.initialized&&a("orientationchange")};s("init",(()=>{t.params.resizeObserver&&void 0!==i.ResizeObserver?t&&!t.destroyed&&t.initialized&&(r=new ResizeObserver((e=>{n=i.requestAnimationFrame((()=>{const{width:s,height:a}=t;let i=s,r=a;e.forEach((e=>{let{contentBoxSize:s,contentRect:a,target:n}=e;n&&n!==t.el||(i=a?a.width:(s[0]||s).inlineSize,r=a?a.height:(s[0]||s).blockSize)})),i===s&&r===a||l()}))})),r.observe(t.el)):(i.addEventListener("resize",l),i.addEventListener("orientationchange",o))})),s("destroy",(()=>{n&&i.cancelAnimationFrame(n),r&&r.unobserve&&t.el&&(r.unobserve(t.el),r=null),i.removeEventListener("resize",l),i.removeEventListener("orientationchange",o)}))},function(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;const r=[],n=p(),l=function(e,s){void 0===s&&(s={});const a=new(n.MutationObserver||n.WebkitMutationObserver)((e=>{if(t.__preventObserver__)return;if(1===e.length)return void i("observerUpdate",e[0]);const s=function(){i("observerUpdate",e[0])};n.requestAnimationFrame?n.requestAnimationFrame(s):n.setTimeout(s,0)}));a.observe(e,{attributes:void 0===s.attributes||s.attributes,childList:t.isElement||(void 0===s.childList||s).childList,characterData:void 0===s.characterData||s.characterData}),r.push(a)};s({observer:!1,observeParents:!1,observeSlideChildren:!1}),a("init",(()=>{if(t.params.observer){if(t.params.observeParents){const e=L(t.hostEl);for(let t=0;t<e.length;t+=1)l(e[t])}l(t.hostEl,{childList:t.params.observeSlideChildren}),l(t.wrapperEl,{attributes:!1})}})),a("destroy",(()=>{r.forEach((e=>{e.disconnect()})),r.splice(0,r.length)}))}]);const Ae=(t="medium",s="lightbox")=>{let a=document.querySelector("#carousel-slider-dialog");if(a)return a;let i=e("shapla-dialog",{id:"carousel-slider-dialog",type:s,"content-size":t});return document.body.append(i),i.addEventListener("close",(()=>{i.remove()})),i};document.querySelectorAll(".swiper").forEach((t=>{const s=t.querySelector("[data-swiper]"),a=s.getAttribute("data-swiper"),i=s.getAttribute("data-slide-type"),r=JSON.parse(a),n=new de(t,ke(ke({},r),{},{modules:[ve,pe,me,fe,ge,ce,xe,Se,Me,Ee,Le,Ce]}));setTimeout((()=>{var e,t;e="CarouselSlider.init",t={slider_type:i,swiper:n},document.dispatchEvent(new CustomEvent(e,{detail:t}))}),5),t.querySelectorAll(".magnific-popup").forEach((t=>{t.addEventListener("click",(s=>{if(s.preventDefault(),"video-carousel"===i){let s=Ae("large");s.setAttribute("open","");let a=t.getAttribute("data-embed_url"),i=e("div",{class:"dialog--video-carousel"},[e("shapla-aspect-ratio",{"width-ratio":"16","height-ratio":"9"},[e("iframe",{class:"cs-iframe",src:`${a}`,frameborder:"0",allowfullscreen:""})])]);s.innerHTML=i.outerHTML}else if("product-carousel"===i){let s=Ae("large","box"),a=t.getAttribute("href");s.innerHTML='<div class="dialog--loading">Loading...</div>',(e=>new Promise((t=>{let s=new XMLHttpRequest;s.addEventListener("load",(()=>{t(s.responseText)})),s.open("GET",e),s.send()})))(a).then((t=>{let a=e("div",{class:"dialog--product-carousel mfp-content"});a.innerHTML=t,s.setAttribute("open",""),s.innerHTML=a.outerHTML})),s.setAttribute("open","")}else{let s=Ae();s.setAttribute("open","");let a=t.getAttribute("href"),i=t.getAttribute("data-width"),r=t.getAttribute("data-height"),n=e("div",{class:"dialog--image-carousel"},[e("shapla-aspect-ratio",{"width-ratio":i,"height-ratio":r},[e("img",{src:a})])]);s.innerHTML=n.outerHTML}}))}))})),document.addEventListener("CarouselSlider.init",(e=>{const t=e.detail.swiper;if("hero-banner-slider"===e.detail.slider_type){const e=e=>{let t=e.querySelector(".carousel-slider-hero__cell__content"),s=t.getAttribute("data-animation");t.classList.remove("hidden"),t.classList.add("animated",s)},s=()=>new Promise((e=>{t.el.querySelectorAll(".animated")?.forEach((e=>{let t=e.getAttribute("data-animation");e.classList.remove("animated",t),e.classList.add("hidden")})),e(!0)}));e(t.slides[t.activeIndex]),t.on("slideChangeTransitionEnd",(()=>{s().then((()=>{e(t.slides[t.activeIndex])}))}))}}))})()})();assets/js/admin-gutenberg-block.js000064400000003506151727276560013206 0ustar00(()=>{"use strict";var e={n:l=>{var r=l&&l.__esModule?()=>l.default:()=>l;return e.d(r,{a:r}),r},d:(l,r)=>{for(var t in r)e.o(r,t)&&!e.o(l,t)&&Object.defineProperty(l,t,{enumerable:!0,get:r[t]})},o:(e,l)=>Object.prototype.hasOwnProperty.call(e,l)};(()=>{const l=React;var r=e.n(l);const t=wp.blocks,s=wp.components,a=wp.blockEditor,o=window.i18nCarouselSliderBlock||{sliders:[],site_url:"",block_logo:"",block_title:"",select_slider:""};(0,t.registerBlockType)("carousel-slider/slider",{title:o.block_title,icon:"slides",category:"common",attributes:{sliderID:{type:"integer",default:0}},edit:e=>{let l=e.attributes.sliderID,t=[];l||(l="");let i=new URL(o.site_url);i.searchParams.append("carousel_slider_preview","1"),i.searchParams.append("carousel_slider_iframe","1"),i.searchParams.append("slider_id",l);let c=i.toString();const n=r().createElement(s.SelectControl,{label:o.select_slider,value:l,options:o.sliders,onChange:l=>{e.setAttributes({sliderID:parseInt(l)})}});let d=r().createElement("div",{className:"carousel-slider-iframe-container"},r().createElement("div",{className:"carousel-slider-iframe-overlay"}),r().createElement("iframe",{className:"carousel-slider-iframe",scrolling:"no",src:c,height:"0",width:"500"})),u=r().createElement("div",{className:"carousel-slider-editor-controls"},r().createElement("img",{className:"carousel-slider-editor-controls__logo",src:o.block_logo,alt:""}),r().createElement("div",{className:"carousel-slider-editor-controls__title"},o.block_title),r().createElement("div",{className:"carousel-slider-editor-controls__input"},n)),m=r().createElement(a.InspectorControls,null,r().createElement("div",{className:"carousel-slider-inspector-controls"},n));return""===l?t.push(u):t.push(d),t.push(m),[t]},save:({attributes:e})=>e.sliderID?r().createElement("div",null,`[carousel_slide id='${e.sliderID}']`):""})})()})();assets/js/frontend-style-loader.js000064400000000646151727276560013271 0ustar00(()=>{"use strict";if(window.carouselSliderCssUrl){if(!document.querySelector("#carousel-slider-frontend-css")){let e=((e,t={},r=[])=>{let l=document.createElement(e);return Object.keys(t).length&&Object.entries(t).forEach((([e,t])=>{l.setAttribute(e,t)})),r.length&&l.append(...r),l})("link",{id:"carousel-slider-frontend-css",rel:"stylesheet",media:"all",href:window.carouselSliderCssUrl});document.head.append(e)}}})();assets/js/frontend.js000064400000202446151727276560010671 0ustar00/*! For license information please see frontend.js.LICENSE.txt */
(()=>{var t={586:(t,e,i)=>{var s,n,o;n=[i(669)],s=function(t){var e,i,s,n,o,r,a="Close",l="BeforeClose",h="AfterClose",c="BeforeAppend",p="MarkupParse",d="Open",u="Change",g="mfp",m="."+g,f="mfp-ready",v="mfp-removing",_="mfp-prevent-close",y=function(){},w=!!window.jQuery,x=t(window),C=function(t,i){e.ev.on(g+t+m,i)},b=function(e,i,s,n){var o=document.createElement("div");return o.className="mfp-"+e,s&&(o.innerHTML=s),n?i&&i.appendChild(o):(o=t(o),i&&o.appendTo(i)),o},z=function(t,i){e.ev.triggerHandler(g+t,i),e.st.callbacks&&(t=t.charAt(0).toLowerCase()+t.slice(1),e.st.callbacks[t]&&e.st.callbacks[t].apply(e,Array.isArray(i)?i:[i]))},T=function(i){return i===r&&e.currTemplate.closeBtn||(e.currTemplate.closeBtn=t(e.st.closeMarkup.replace("%title%",e.st.tClose)),r=i),e.currTemplate.closeBtn},I=function(){t.magnificPopup.instance||((e=new y).init(),t.magnificPopup.instance=e)},$=function(){var t=document.createElement("p").style,e=["ms","O","Moz","Webkit"];if(void 0!==t.transition)return!0;for(;e.length;)if(e.pop()+"Transition"in t)return!0;return!1};y.prototype={constructor:y,init:function(){var i=navigator.appVersion;e.isLowIE=e.isIE8=document.all&&!document.addEventListener,e.isAndroid=/android/gi.test(i),e.isIOS=/iphone|ipad|ipod/gi.test(i),e.supportsTransition=$(),e.probablyMobile=e.isAndroid||e.isIOS||/(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent),s=t(document),e.popupsCache={}},open:function(i){var n;if(!1===i.isObj){e.items=i.items.toArray(),e.index=0;var r,a=i.items;for(n=0;n<a.length;n++)if((r=a[n]).parsed&&(r=r.el[0]),r===i.el[0]){e.index=n;break}}else e.items=Array.isArray(i.items)?i.items:[i.items],e.index=i.index||0;if(!e.isOpen){e.types=[],o="",i.mainEl&&i.mainEl.length?e.ev=i.mainEl.eq(0):e.ev=s,i.key?(e.popupsCache[i.key]||(e.popupsCache[i.key]={}),e.currTemplate=e.popupsCache[i.key]):e.currTemplate={},e.st=t.extend(!0,{},t.magnificPopup.defaults,i),e.fixedContentPos="auto"===e.st.fixedContentPos?!e.probablyMobile:e.st.fixedContentPos,e.st.modal&&(e.st.closeOnContentClick=!1,e.st.closeOnBgClick=!1,e.st.showCloseBtn=!1,e.st.enableEscapeKey=!1),e.bgOverlay||(e.bgOverlay=b("bg").on("click"+m,(function(){e.close()})),e.wrap=b("wrap").attr("tabindex",-1).on("click"+m,(function(t){e._checkIfClose(t.target)&&e.close()})),e.container=b("container",e.wrap)),e.contentContainer=b("content"),e.st.preloader&&(e.preloader=b("preloader",e.container,e.st.tLoading));var l=t.magnificPopup.modules;for(n=0;n<l.length;n++){var h=l[n];h=h.charAt(0).toUpperCase()+h.slice(1),e["init"+h].call(e)}z("BeforeOpen"),e.st.showCloseBtn&&(e.st.closeBtnInside?(C(p,(function(t,e,i,s){i.close_replaceWith=T(s.type)})),o+=" mfp-close-btn-in"):e.wrap.append(T())),e.st.alignTop&&(o+=" mfp-align-top"),e.fixedContentPos?e.wrap.css({overflow:e.st.overflowY,overflowX:"hidden",overflowY:e.st.overflowY}):e.wrap.css({top:x.scrollTop(),position:"absolute"}),(!1===e.st.fixedBgPos||"auto"===e.st.fixedBgPos&&!e.fixedContentPos)&&e.bgOverlay.css({height:s.height(),position:"absolute"}),e.st.enableEscapeKey&&s.on("keyup"+m,(function(t){27===t.keyCode&&e.close()})),x.on("resize"+m,(function(){e.updateSize()})),e.st.closeOnContentClick||(o+=" mfp-auto-cursor"),o&&e.wrap.addClass(o);var c=e.wH=x.height(),u={};if(e.fixedContentPos&&e._hasScrollBar(c)){var g=e._getScrollbarSize();g&&(u.marginRight=g)}e.fixedContentPos&&(e.isIE7?t("body, html").css("overflow","hidden"):u.overflow="hidden");var v=e.st.mainClass;return e.isIE7&&(v+=" mfp-ie7"),v&&e._addClassToMFP(v),e.updateItemHTML(),z("BuildControls"),t("html").css(u),e.bgOverlay.add(e.wrap).prependTo(e.st.prependTo||t(document.body)),e._lastFocusedEl=document.activeElement,setTimeout((function(){e.content?(e._addClassToMFP(f),e._setFocus()):e.bgOverlay.addClass(f),s.on("focusin"+m,e._onFocusIn)}),16),e.isOpen=!0,e.updateSize(c),z(d),i}e.updateItemHTML()},close:function(){e.isOpen&&(z(l),e.isOpen=!1,e.st.removalDelay&&!e.isLowIE&&e.supportsTransition?(e._addClassToMFP(v),setTimeout((function(){e._close()}),e.st.removalDelay)):e._close())},_close:function(){z(a);var i=v+" "+f+" ";if(e.bgOverlay.detach(),e.wrap.detach(),e.container.empty(),e.st.mainClass&&(i+=e.st.mainClass+" "),e._removeClassFromMFP(i),e.fixedContentPos){var n={marginRight:""};e.isIE7?t("body, html").css("overflow",""):n.overflow="",t("html").css(n)}s.off("keyup"+m+" focusin"+m),e.ev.off(m),e.wrap.attr("class","mfp-wrap").removeAttr("style"),e.bgOverlay.attr("class","mfp-bg"),e.container.attr("class","mfp-container"),!e.st.showCloseBtn||e.st.closeBtnInside&&!0!==e.currTemplate[e.currItem.type]||e.currTemplate.closeBtn&&e.currTemplate.closeBtn.detach(),e.st.autoFocusLast&&e._lastFocusedEl&&t(e._lastFocusedEl).trigger("focus"),e.currItem=null,e.content=null,e.currTemplate=null,e.prevHeight=0,z(h)},updateSize:function(t){if(e.isIOS){var i=document.documentElement.clientWidth/window.innerWidth,s=window.innerHeight*i;e.wrap.css("height",s),e.wH=s}else e.wH=t||x.height();e.fixedContentPos||e.wrap.css("height",e.wH),z("Resize")},updateItemHTML:function(){var i=e.items[e.index];e.contentContainer.detach(),e.content&&e.content.detach(),i.parsed||(i=e.parseEl(e.index));var s=i.type;if(z("BeforeChange",[e.currItem?e.currItem.type:"",s]),e.currItem=i,!e.currTemplate[s]){var o=!!e.st[s]&&e.st[s].markup;z("FirstMarkupParse",o),e.currTemplate[s]=!o||t(o)}n&&n!==i.type&&e.container.removeClass("mfp-"+n+"-holder");var r=e["get"+s.charAt(0).toUpperCase()+s.slice(1)](i,e.currTemplate[s]);e.appendContent(r,s),i.preloaded=!0,z(u,i),n=i.type,e.container.prepend(e.contentContainer),z("AfterChange")},appendContent:function(t,i){e.content=t,t?e.st.showCloseBtn&&e.st.closeBtnInside&&!0===e.currTemplate[i]?e.content.find(".mfp-close").length||e.content.append(T()):e.content=t:e.content="",z(c),e.container.addClass("mfp-"+i+"-holder"),e.contentContainer.append(e.content)},parseEl:function(i){var s,n=e.items[i];if(n.tagName?n={el:t(n)}:(s=n.type,n={data:n,src:n.src}),n.el){for(var o=e.types,r=0;r<o.length;r++)if(n.el.hasClass("mfp-"+o[r])){s=o[r];break}n.src=n.el.attr("data-mfp-src"),n.src||(n.src=n.el.attr("href"))}return n.type=s||e.st.type||"inline",n.index=i,n.parsed=!0,e.items[i]=n,z("ElementParse",n),e.items[i]},addGroup:function(t,i){var s=function(s){s.mfpEl=this,e._openClick(s,t,i)};i||(i={});var n="click.magnificPopup";i.mainEl=t,i.items?(i.isObj=!0,t.off(n).on(n,s)):(i.isObj=!1,i.delegate?t.off(n).on(n,i.delegate,s):(i.items=t,t.off(n).on(n,s)))},_openClick:function(i,s,n){if((void 0!==n.midClick?n.midClick:t.magnificPopup.defaults.midClick)||!(2===i.which||i.ctrlKey||i.metaKey||i.altKey||i.shiftKey)){var o=void 0!==n.disableOn?n.disableOn:t.magnificPopup.defaults.disableOn;if(o)if("function"==typeof o){if(!o.call(e))return!0}else if(x.width()<o)return!0;i.type&&(i.preventDefault(),e.isOpen&&i.stopPropagation()),n.el=t(i.mfpEl),n.delegate&&(n.items=s.find(n.delegate)),e.open(n)}},updateStatus:function(t,s){if(e.preloader){i!==t&&e.container.removeClass("mfp-s-"+i),s||"loading"!==t||(s=e.st.tLoading);var n={status:t,text:s};z("UpdateStatus",n),t=n.status,s=n.text,e.st.allowHTMLInStatusIndicator?e.preloader.html(s):e.preloader.text(s),e.preloader.find("a").on("click",(function(t){t.stopImmediatePropagation()})),e.container.addClass("mfp-s-"+t),i=t}},_checkIfClose:function(i){if(!t(i).closest("."+_).length){var s=e.st.closeOnContentClick,n=e.st.closeOnBgClick;if(s&&n)return!0;if(!e.content||t(i).closest(".mfp-close").length||e.preloader&&i===e.preloader[0])return!0;if(i===e.content[0]||t.contains(e.content[0],i)){if(s)return!0}else if(n&&t.contains(document,i))return!0;return!1}},_addClassToMFP:function(t){e.bgOverlay.addClass(t),e.wrap.addClass(t)},_removeClassFromMFP:function(t){this.bgOverlay.removeClass(t),e.wrap.removeClass(t)},_hasScrollBar:function(t){return(e.isIE7?s.height():document.body.scrollHeight)>(t||x.height())},_setFocus:function(){(e.st.focus?e.content.find(e.st.focus).eq(0):e.wrap).trigger("focus")},_onFocusIn:function(i){if(i.target!==e.wrap[0]&&!t.contains(e.wrap[0],i.target))return e._setFocus(),!1},_parseMarkup:function(i,s,n){var o;n.data&&(s=t.extend(n.data,s)),z(p,[i,s,n]),t.each(s,(function(s,n){if(void 0===n||!1===n)return!0;if((o=s.split("_")).length>1){var r=i.find(m+"-"+o[0]);if(r.length>0){var a=o[1];"replaceWith"===a?r[0]!==n[0]&&r.replaceWith(n):"img"===a?r.is("img")?r.attr("src",n):r.replaceWith(t("<img>").attr("src",n).attr("class",r.attr("class"))):r.attr(o[1],n)}}else e.st.allowHTMLInTemplate?i.find(m+"-"+s).html(n):i.find(m+"-"+s).text(n)}))},_getScrollbarSize:function(){if(void 0===e.scrollbarSize){var t=document.createElement("div");t.style.cssText="width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;",document.body.appendChild(t),e.scrollbarSize=t.offsetWidth-t.clientWidth,document.body.removeChild(t)}return e.scrollbarSize}},t.magnificPopup={instance:null,proto:y.prototype,modules:[],open:function(e,i){return I(),(e=e?t.extend(!0,{},e):{}).isObj=!0,e.index=i||0,this.instance.open(e)},close:function(){return t.magnificPopup.instance&&t.magnificPopup.instance.close()},registerModule:function(e,i){i.options&&(t.magnificPopup.defaults[e]=i.options),t.extend(this.proto,i.proto),this.modules.push(e)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:"",preloader:!0,focus:"",closeOnContentClick:!1,closeOnBgClick:!0,closeBtnInside:!0,showCloseBtn:!0,enableEscapeKey:!0,modal:!1,alignTop:!1,removalDelay:0,prependTo:null,fixedContentPos:"auto",fixedBgPos:"auto",overflowY:"auto",closeMarkup:'<button title="%title%" type="button" class="mfp-close">&#215;</button>',tClose:"Close (Esc)",tLoading:"Loading...",autoFocusLast:!0,allowHTMLInStatusIndicator:!1,allowHTMLInTemplate:!1}},t.fn.magnificPopup=function(i){I();var s=t(this);if("string"==typeof i)if("open"===i){var n,o=w?s.data("magnificPopup"):s[0].magnificPopup,r=parseInt(arguments[1],10)||0;o.items?n=o.items[r]:(n=s,o.delegate&&(n=n.find(o.delegate)),n=n.eq(r)),e._openClick({mfpEl:n},s,o)}else e.isOpen&&e[i].apply(e,Array.prototype.slice.call(arguments,1));else i=t.extend(!0,{},i),w?s.data("magnificPopup",i):s[0].magnificPopup=i,e.addGroup(s,i);return s};var E,P,k,S="inline",M=function(){k&&(P.after(k.addClass(E)).detach(),k=null)};t.magnificPopup.registerModule(S,{options:{hiddenClass:"hide",markup:"",tNotFound:"Content not found"},proto:{initInline:function(){e.types.push(S),C(a+"."+S,(function(){M()}))},getInline:function(i,s){if(M(),i.src){var n=e.st.inline,o=t(i.src);if(o.length){var r=o[0].parentNode;r&&r.tagName&&(P||(E=n.hiddenClass,P=b(E),E="mfp-"+E),k=o.after(P).detach().removeClass(E)),e.updateStatus("ready")}else e.updateStatus("error",n.tNotFound),o=t("<div>");return i.inlineElement=o,o}return e.updateStatus("ready"),e._parseMarkup(s,{},i),s}}});var O,D="ajax",j=function(){O&&t(document.body).removeClass(O)},L=function(){j(),e.req&&e.req.abort()};t.magnificPopup.registerModule(D,{options:{settings:null,cursor:"mfp-ajax-cur",tError:"The content could not be loaded."},proto:{initAjax:function(){e.types.push(D),O=e.st.ajax.cursor,C(a+"."+D,L),C("BeforeChange."+D,L)},getAjax:function(i){O&&t(document.body).addClass(O),e.updateStatus("loading");var s=t.extend({url:i.src,success:function(s,n,o){var r={data:s,xhr:o};z("ParseAjax",r),e.appendContent(t(r.data),D),i.finished=!0,j(),e._setFocus(),setTimeout((function(){e.wrap.addClass(f)}),16),e.updateStatus("ready"),z("AjaxContentAdded")},error:function(){j(),i.finished=i.loadError=!0,e.updateStatus("error",e.st.ajax.tError.replace("%url%",i.src))}},e.st.ajax.settings);return e.req=t.ajax(s),""}}});var H,B=function(t){if(t.data&&void 0!==t.data.title)return t.data.title;var i=e.st.image.titleSrc;if(i){if("function"==typeof i)return i.call(e,t);if(t.el)return t.el.attr(i)||""}return""};t.magnificPopup.registerModule("image",{options:{markup:'<div class="mfp-figure"><div class="mfp-close"></div><figure><div class="mfp-img"></div><figcaption><div class="mfp-bottom-bar"><div class="mfp-title"></div><div class="mfp-counter"></div></div></figcaption></figure></div>',cursor:"mfp-zoom-out-cur",titleSrc:"title",verticalFit:!0,tError:"The image could not be loaded."},proto:{initImage:function(){var i=e.st.image,s=".image";e.types.push("image"),C(d+s,(function(){"image"===e.currItem.type&&i.cursor&&t(document.body).addClass(i.cursor)})),C(a+s,(function(){i.cursor&&t(document.body).removeClass(i.cursor),x.off("resize"+m)})),C("Resize"+s,e.resizeImage),e.isLowIE&&C("AfterChange",e.resizeImage)},resizeImage:function(){var t=e.currItem;if(t&&t.img&&e.st.image.verticalFit){var i=0;e.isLowIE&&(i=parseInt(t.img.css("padding-top"),10)+parseInt(t.img.css("padding-bottom"),10)),t.img.css("max-height",e.wH-i)}},_onImageHasSize:function(t){t.img&&(t.hasSize=!0,H&&clearInterval(H),t.isCheckingImgSize=!1,z("ImageHasSize",t),t.imgHidden&&(e.content&&e.content.removeClass("mfp-loading"),t.imgHidden=!1))},findImageSize:function(t){var i=0,s=t.img[0],n=function(o){H&&clearInterval(H),H=setInterval((function(){s.naturalWidth>0?e._onImageHasSize(t):(i>200&&clearInterval(H),3==++i?n(10):40===i?n(50):100===i&&n(500))}),o)};n(1)},getImage:function(i,s){var n=0,o=e.st.image,r=function(){i&&(i.img.off(".mfploader"),i===e.currItem&&(e._onImageHasSize(i),e.updateStatus("error",o.tError.replace("%url%",i.src))),i.hasSize=!0,i.loaded=!0,i.loadError=!0)},a=function(){i&&(i.img[0].complete?(i.img.off(".mfploader"),i===e.currItem&&(e._onImageHasSize(i),e.updateStatus("ready")),i.hasSize=!0,i.loaded=!0,z("ImageLoadComplete")):++n<200?setTimeout(a,100):r())},l=s.find(".mfp-img");if(l.length){var h=document.createElement("img");h.className="mfp-img",i.el&&i.el.find("img").length&&(h.alt=i.el.find("img").attr("alt")),i.img=t(h).on("load.mfploader",a).on("error.mfploader",r),h.src=i.src,l.is("img")&&(i.img=i.img.clone()),(h=i.img[0]).naturalWidth>0?i.hasSize=!0:h.width||(i.hasSize=!1)}return e._parseMarkup(s,{title:B(i),img_replaceWith:i.img},i),e.resizeImage(),i.hasSize?(H&&clearInterval(H),i.loadError?(s.addClass("mfp-loading"),e.updateStatus("error",o.tError.replace("%url%",i.src))):(s.removeClass("mfp-loading"),e.updateStatus("ready")),s):(e.updateStatus("loading"),i.loading=!0,i.hasSize||(i.imgHidden=!0,s.addClass("mfp-loading"),e.findImageSize(i)),s)}}});var A,W=function(){return void 0===A&&(A=void 0!==document.createElement("p").style.MozTransform),A};t.magnificPopup.registerModule("zoom",{options:{enabled:!1,easing:"ease-in-out",duration:300,opener:function(t){return t.is("img")?t:t.find("img")}},proto:{initZoom:function(){var t,i=e.st.zoom,s=".zoom";if(i.enabled&&e.supportsTransition){var n,o,r=i.duration,h=function(t){var e=t.clone().removeAttr("style").removeAttr("class").addClass("mfp-animated-image"),s="all "+i.duration/1e3+"s "+i.easing,n={position:"fixed",zIndex:9999,left:0,top:0,"-webkit-backface-visibility":"hidden"},o="transition";return n["-webkit-"+o]=n["-moz-"+o]=n["-o-"+o]=n[o]=s,e.css(n),e},c=function(){e.content.css("visibility","visible")};C("BuildControls"+s,(function(){if(e._allowZoom()){if(clearTimeout(n),e.content.css("visibility","hidden"),!(t=e._getItemToZoom()))return void c();(o=h(t)).css(e._getOffset()),e.wrap.append(o),n=setTimeout((function(){o.css(e._getOffset(!0)),n=setTimeout((function(){c(),setTimeout((function(){o.remove(),t=o=null,z("ZoomAnimationEnded")}),16)}),r)}),16)}})),C(l+s,(function(){if(e._allowZoom()){if(clearTimeout(n),e.st.removalDelay=r,!t){if(!(t=e._getItemToZoom()))return;o=h(t)}o.css(e._getOffset(!0)),e.wrap.append(o),e.content.css("visibility","hidden"),setTimeout((function(){o.css(e._getOffset())}),16)}})),C(a+s,(function(){e._allowZoom()&&(c(),o&&o.remove(),t=null)}))}},_allowZoom:function(){return"image"===e.currItem.type},_getItemToZoom:function(){return!!e.currItem.hasSize&&e.currItem.img},_getOffset:function(i){var s,n=(s=i?e.currItem.img:e.st.zoom.opener(e.currItem.el||e.currItem)).offset(),o=parseInt(s.css("padding-top"),10),r=parseInt(s.css("padding-bottom"),10);n.top-=t(window).scrollTop()-o;var a={width:s.width(),height:(w?s.innerHeight():s[0].offsetHeight)-r-o};return W()?a["-moz-transform"]=a.transform="translate("+n.left+"px,"+n.top+"px)":(a.left=n.left,a.top=n.top),a}}});var N="iframe",F="//about:blank",R=function(t){if(e.currTemplate[N]){var i=e.currTemplate[N].find("iframe");i.length&&(t||(i[0].src=F),e.isIE8&&i.css("display",t?"block":"none"))}};t.magnificPopup.registerModule(N,{options:{markup:'<div class="mfp-iframe-scaler"><div class="mfp-close"></div><iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe></div>',srcAction:"iframe_src",patterns:{youtube:{index:"youtube.com",id:"v=",src:"//www.youtube.com/embed/%id%?autoplay=1"},vimeo:{index:"vimeo.com/",id:"/",src:"//player.vimeo.com/video/%id%?autoplay=1"},gmaps:{index:"//maps.google.",src:"%id%&output=embed"}}},proto:{initIframe:function(){e.types.push(N),C("BeforeChange",(function(t,e,i){e!==i&&(e===N?R():i===N&&R(!0))})),C(a+"."+N,(function(){R()}))},getIframe:function(i,s){var n=i.src,o=e.st.iframe;t.each(o.patterns,(function(){if(n.indexOf(this.index)>-1)return this.id&&(n="string"==typeof this.id?n.substr(n.lastIndexOf(this.id)+this.id.length,n.length):this.id.call(this,n)),n=this.src.replace("%id%",n),!1}));var r={};return o.srcAction&&(r[o.srcAction]=n),e._parseMarkup(s,r,i),e.updateStatus("ready"),s}}});var Z=function(t){var i=e.items.length;return t>i-1?t-i:t<0?i+t:t},q=function(t,e,i){return t.replace(/%curr%/gi,e+1).replace(/%total%/gi,i)};t.magnificPopup.registerModule("gallery",{options:{enabled:!1,arrowMarkup:'<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:"Previous (Left arrow key)",tNext:"Next (Right arrow key)",tCounter:"%curr% of %total%",langDir:null,loop:!0},proto:{initGallery:function(){var i=e.st.gallery,n=".mfp-gallery";if(e.direction=!0,!i||!i.enabled)return!1;i.langDir||(i.langDir=document.dir||"ltr"),o+=" mfp-gallery",C(d+n,(function(){i.navigateByImgClick&&e.wrap.on("click"+n,".mfp-img",(function(){if(e.items.length>1)return e.next(),!1})),s.on("keydown"+n,(function(t){37===t.keyCode?"rtl"===i.langDir?e.next():e.prev():39===t.keyCode&&("rtl"===i.langDir?e.prev():e.next())})),e.updateGalleryButtons()})),C("UpdateStatus"+n,(function(){e.updateGalleryButtons()})),C("UpdateStatus"+n,(function(t,i){i.text&&(i.text=q(i.text,e.currItem.index,e.items.length))})),C(p+n,(function(t,s,n,o){var r=e.items.length;n.counter=r>1?q(i.tCounter,o.index,r):""})),C("BuildControls"+n,(function(){if(e.items.length>1&&i.arrows&&!e.arrowLeft){var s,n,o,r;"rtl"===i.langDir?(s=i.tNext,n=i.tPrev,o="next",r="prev"):(s=i.tPrev,n=i.tNext,o="prev",r="next");var a=i.arrowMarkup,l=e.arrowLeft=t(a.replace(/%title%/gi,s).replace(/%action%/gi,o).replace(/%dir%/gi,"left")).addClass(_),h=e.arrowRight=t(a.replace(/%title%/gi,n).replace(/%action%/gi,r).replace(/%dir%/gi,"right")).addClass(_);"rtl"===i.langDir?(e.arrowNext=l,e.arrowPrev=h):(e.arrowNext=h,e.arrowPrev=l),l.on("click",(function(){"rtl"===i.langDir?e.next():e.prev()})),h.on("click",(function(){"rtl"===i.langDir?e.prev():e.next()})),e.container.append(l.add(h))}})),C(u+n,(function(){e._preloadTimeout&&clearTimeout(e._preloadTimeout),e._preloadTimeout=setTimeout((function(){e.preloadNearbyImages(),e._preloadTimeout=null}),16)})),C(a+n,(function(){s.off(n),e.wrap.off("click"+n),e.arrowRight=e.arrowLeft=null}))},next:function(){var t=Z(e.index+1);if(!e.st.gallery.loop&&0===t)return!1;e.direction=!0,e.index=t,e.updateItemHTML()},prev:function(){var t=e.index-1;if(!e.st.gallery.loop&&t<0)return!1;e.direction=!1,e.index=Z(t),e.updateItemHTML()},goTo:function(t){e.direction=t>=e.index,e.index=t,e.updateItemHTML()},preloadNearbyImages:function(){var t,i=e.st.gallery.preload,s=Math.min(i[0],e.items.length),n=Math.min(i[1],e.items.length);for(t=1;t<=(e.direction?n:s);t++)e._preloadItem(e.index+t);for(t=1;t<=(e.direction?s:n);t++)e._preloadItem(e.index-t)},_preloadItem:function(i){if(i=Z(i),!e.items[i].preloaded){var s=e.items[i];s.parsed||(s=e.parseEl(i)),z("LazyLoad",s),"image"===s.type&&(s.img=t('<img class="mfp-img" />').on("load.mfploader",(function(){s.hasSize=!0})).on("error.mfploader",(function(){s.hasSize=!0,s.loadError=!0,z("LazyLoadError",s)})).attr("src",s.src)),s.preloaded=!0}},updateGalleryButtons:function(){e.st.gallery.loop||"object"!=typeof e.arrowPrev||null===e.arrowPrev||(0===e.index?e.arrowPrev.hide():e.arrowPrev.show(),e.index===e.items.length-1?e.arrowNext.hide():e.arrowNext.show())}}});var Q="retina";t.magnificPopup.registerModule(Q,{options:{replaceSrc:function(t){return t.src.replace(/\.\w+$/,(function(t){return"@2x"+t}))},ratio:1},proto:{initRetina:function(){if(window.devicePixelRatio>1){var t=e.st.retina,i=t.ratio;(i=isNaN(i)?i():i)>1&&(C("ImageHasSize."+Q,(function(t,e){e.img.css({"max-width":e.img[0].naturalWidth/i,width:"100%"})})),C("ElementParse."+Q,(function(e,s){s.src=t.replaceSrc(s,i)})))}}}}),I()},void 0===(o="function"==typeof s?s.apply(e,n):s)||(t.exports=o)},626:()=>{!function(t,e,i,s){function n(e,i){this.settings=null,this.options=t.extend({},n.Defaults,i),this.$element=t(e),this._handlers={},this._plugins={},this._supress={},this._current=null,this._speed=null,this._coordinates=[],this._breakpoint=null,this._width=null,this._items=[],this._clones=[],this._mergers=[],this._widths=[],this._invalidated={},this._pipe=[],this._drag={time:null,target:null,pointer:null,stage:{start:null,current:null},direction:null},this._states={current:{},tags:{initializing:["busy"],animating:["busy"],dragging:["interacting"]}},t.each(["onResize","onThrottledResize"],t.proxy((function(e,i){this._handlers[i]=t.proxy(this[i],this)}),this)),t.each(n.Plugins,t.proxy((function(t,e){this._plugins[t.charAt(0).toLowerCase()+t.slice(1)]=new e(this)}),this)),t.each(n.Workers,t.proxy((function(e,i){this._pipe.push({filter:i.filter,run:t.proxy(i.run,this)})}),this)),this.setup(),this.initialize()}n.Defaults={items:3,loop:!1,center:!1,rewind:!1,checkVisibility:!0,mouseDrag:!0,touchDrag:!0,pullDrag:!0,freeDrag:!1,margin:0,stagePadding:0,merge:!1,mergeFit:!0,autoWidth:!1,startPosition:0,rtl:!1,smartSpeed:250,fluidSpeed:!1,dragEndSpeed:!1,responsive:{},responsiveRefreshRate:200,responsiveBaseElement:e,fallbackEasing:"swing",slideTransition:"",info:!1,nestedItemSelector:!1,itemElement:"div",stageElement:"div",refreshClass:"owl-refresh",loadedClass:"owl-loaded",loadingClass:"owl-loading",rtlClass:"owl-rtl",responsiveClass:"owl-responsive",dragClass:"owl-drag",itemClass:"owl-item",stageClass:"owl-stage",stageOuterClass:"owl-stage-outer",grabClass:"owl-grab"},n.Width={Default:"default",Inner:"inner",Outer:"outer"},n.Type={Event:"event",State:"state"},n.Plugins={},n.Workers=[{filter:["width","settings"],run:function(){this._width=this.$element.width()}},{filter:["width","items","settings"],run:function(t){t.current=this._items&&this._items[this.relative(this._current)]}},{filter:["items","settings"],run:function(){this.$stage.children(".cloned").remove()}},{filter:["width","items","settings"],run:function(t){var e=this.settings.margin||"",i=!this.settings.autoWidth,s=this.settings.rtl,n={width:"auto","margin-left":s?e:"","margin-right":s?"":e};!i&&this.$stage.children().css(n),t.css=n}},{filter:["width","items","settings"],run:function(t){var e=(this.width()/this.settings.items).toFixed(3)-this.settings.margin,i=null,s=this._items.length,n=!this.settings.autoWidth,o=[];for(t.items={merge:!1,width:e};s--;)i=this._mergers[s],i=this.settings.mergeFit&&Math.min(i,this.settings.items)||i,t.items.merge=i>1||t.items.merge,o[s]=n?e*i:this._items[s].width();this._widths=o}},{filter:["items","settings"],run:function(){var e=[],i=this._items,s=this.settings,n=Math.max(2*s.items,4),o=2*Math.ceil(i.length/2),r=s.loop&&i.length?s.rewind?n:Math.max(n,o):0,a="",l="";for(r/=2;r>0;)e.push(this.normalize(e.length/2,!0)),a+=i[e[e.length-1]][0].outerHTML,e.push(this.normalize(i.length-1-(e.length-1)/2,!0)),l=i[e[e.length-1]][0].outerHTML+l,r-=1;this._clones=e,t(a).addClass("cloned").appendTo(this.$stage),t(l).addClass("cloned").prependTo(this.$stage)}},{filter:["width","items","settings"],run:function(){for(var t=this.settings.rtl?1:-1,e=this._clones.length+this._items.length,i=-1,s=0,n=0,o=[];++i<e;)s=o[i-1]||0,n=this._widths[this.relative(i)]+this.settings.margin,o.push(s+n*t);this._coordinates=o}},{filter:["width","items","settings"],run:function(){var t=this.settings.stagePadding,e=this._coordinates,i={width:Math.ceil(Math.abs(e[e.length-1]))+2*t,"padding-left":t||"","padding-right":t||""};this.$stage.css(i)}},{filter:["width","items","settings"],run:function(t){var e=this._coordinates.length,i=!this.settings.autoWidth,s=this.$stage.children();if(i&&t.items.merge)for(;e--;)t.css.width=this._widths[this.relative(e)],s.eq(e).css(t.css);else i&&(t.css.width=t.items.width,s.css(t.css))}},{filter:["items"],run:function(){this._coordinates.length<1&&this.$stage.removeAttr("style")}},{filter:["width","items","settings"],run:function(t){t.current=t.current?this.$stage.children().index(t.current):0,t.current=Math.max(this.minimum(),Math.min(this.maximum(),t.current)),this.reset(t.current)}},{filter:["position"],run:function(){this.animate(this.coordinates(this._current))}},{filter:["width","position","items","settings"],run:function(){var t,e,i,s,n=this.settings.rtl?1:-1,o=2*this.settings.stagePadding,r=this.coordinates(this.current())+o,a=r+this.width()*n,l=[];for(i=0,s=this._coordinates.length;i<s;i++)t=this._coordinates[i-1]||0,e=Math.abs(this._coordinates[i])+o*n,(this.op(t,"<=",r)&&this.op(t,">",a)||this.op(e,"<",r)&&this.op(e,">",a))&&l.push(i);this.$stage.children(".active").removeClass("active"),this.$stage.children(":eq("+l.join("), :eq(")+")").addClass("active"),this.$stage.children(".center").removeClass("center"),this.settings.center&&this.$stage.children().eq(this.current()).addClass("center")}}],n.prototype.initializeStage=function(){this.$stage=this.$element.find("."+this.settings.stageClass),this.$stage.length||(this.$element.addClass(this.options.loadingClass),this.$stage=t("<"+this.settings.stageElement+">",{class:this.settings.stageClass}).wrap(t("<div/>",{class:this.settings.stageOuterClass})),this.$element.append(this.$stage.parent()))},n.prototype.initializeItems=function(){var e=this.$element.find(".owl-item");if(e.length)return this._items=e.get().map((function(e){return t(e)})),this._mergers=this._items.map((function(){return 1})),void this.refresh();this.replace(this.$element.children().not(this.$stage.parent())),this.isVisible()?this.refresh():this.invalidate("width"),this.$element.removeClass(this.options.loadingClass).addClass(this.options.loadedClass)},n.prototype.initialize=function(){var t,e,i;(this.enter("initializing"),this.trigger("initialize"),this.$element.toggleClass(this.settings.rtlClass,this.settings.rtl),this.settings.autoWidth&&!this.is("pre-loading"))&&(t=this.$element.find("img"),e=this.settings.nestedItemSelector?"."+this.settings.nestedItemSelector:s,i=this.$element.children(e).width(),t.length&&i<=0&&this.preloadAutoWidthImages(t));this.initializeStage(),this.initializeItems(),this.registerEventHandlers(),this.leave("initializing"),this.trigger("initialized")},n.prototype.isVisible=function(){return!this.settings.checkVisibility||this.$element.is(":visible")},n.prototype.setup=function(){var e=this.viewport(),i=this.options.responsive,s=-1,n=null;i?(t.each(i,(function(t){t<=e&&t>s&&(s=Number(t))})),"function"==typeof(n=t.extend({},this.options,i[s])).stagePadding&&(n.stagePadding=n.stagePadding()),delete n.responsive,n.responsiveClass&&this.$element.attr("class",this.$element.attr("class").replace(new RegExp("("+this.options.responsiveClass+"-)\\S+\\s","g"),"$1"+s))):n=t.extend({},this.options),this.trigger("change",{property:{name:"settings",value:n}}),this._breakpoint=s,this.settings=n,this.invalidate("settings"),this.trigger("changed",{property:{name:"settings",value:this.settings}})},n.prototype.optionsLogic=function(){this.settings.autoWidth&&(this.settings.stagePadding=!1,this.settings.merge=!1)},n.prototype.prepare=function(e){var i=this.trigger("prepare",{content:e});return i.data||(i.data=t("<"+this.settings.itemElement+"/>").addClass(this.options.itemClass).append(e)),this.trigger("prepared",{content:i.data}),i.data},n.prototype.update=function(){for(var e=0,i=this._pipe.length,s=t.proxy((function(t){return this[t]}),this._invalidated),n={};e<i;)(this._invalidated.all||t.grep(this._pipe[e].filter,s).length>0)&&this._pipe[e].run(n),e++;this._invalidated={},!this.is("valid")&&this.enter("valid")},n.prototype.width=function(t){switch(t=t||n.Width.Default){case n.Width.Inner:case n.Width.Outer:return this._width;default:return this._width-2*this.settings.stagePadding+this.settings.margin}},n.prototype.refresh=function(){this.enter("refreshing"),this.trigger("refresh"),this.setup(),this.optionsLogic(),this.$element.addClass(this.options.refreshClass),this.update(),this.$element.removeClass(this.options.refreshClass),this.leave("refreshing"),this.trigger("refreshed")},n.prototype.onThrottledResize=function(){e.clearTimeout(this.resizeTimer),this.resizeTimer=e.setTimeout(this._handlers.onResize,this.settings.responsiveRefreshRate)},n.prototype.onResize=function(){return!!this._items.length&&(this._width!==this.$element.width()&&(!!this.isVisible()&&(this.enter("resizing"),this.trigger("resize").isDefaultPrevented()?(this.leave("resizing"),!1):(this.invalidate("width"),this.refresh(),this.leave("resizing"),void this.trigger("resized")))))},n.prototype.registerEventHandlers=function(){t.support.transition&&this.$stage.on(t.support.transition.end+".owl.core",t.proxy(this.onTransitionEnd,this)),!1!==this.settings.responsive&&this.on(e,"resize",this._handlers.onThrottledResize),this.settings.mouseDrag&&(this.$element.addClass(this.options.dragClass),this.$stage.on("mousedown.owl.core",t.proxy(this.onDragStart,this)),this.$stage.on("dragstart.owl.core selectstart.owl.core",(function(){return!1}))),this.settings.touchDrag&&(this.$stage.on("touchstart.owl.core",t.proxy(this.onDragStart,this)),this.$stage.on("touchcancel.owl.core",t.proxy(this.onDragEnd,this)))},n.prototype.onDragStart=function(e){var s=null;3!==e.which&&(t.support.transform?s={x:(s=this.$stage.css("transform").replace(/.*\(|\)| /g,"").split(","))[16===s.length?12:4],y:s[16===s.length?13:5]}:(s=this.$stage.position(),s={x:this.settings.rtl?s.left+this.$stage.width()-this.width()+this.settings.margin:s.left,y:s.top}),this.is("animating")&&(t.support.transform?this.animate(s.x):this.$stage.stop(),this.invalidate("position")),this.$element.toggleClass(this.options.grabClass,"mousedown"===e.type),this.speed(0),this._drag.time=(new Date).getTime(),this._drag.target=t(e.target),this._drag.stage.start=s,this._drag.stage.current=s,this._drag.pointer=this.pointer(e),t(i).on("mouseup.owl.core touchend.owl.core",t.proxy(this.onDragEnd,this)),t(i).one("mousemove.owl.core touchmove.owl.core",t.proxy((function(e){var s=this.difference(this._drag.pointer,this.pointer(e));t(i).on("mousemove.owl.core touchmove.owl.core",t.proxy(this.onDragMove,this)),Math.abs(s.x)<Math.abs(s.y)&&this.is("valid")||(e.preventDefault(),this.enter("dragging"),this.trigger("drag"))}),this)))},n.prototype.onDragMove=function(t){var e=null,i=null,s=null,n=this.difference(this._drag.pointer,this.pointer(t)),o=this.difference(this._drag.stage.start,n);this.is("dragging")&&(t.preventDefault(),this.settings.loop?(e=this.coordinates(this.minimum()),i=this.coordinates(this.maximum()+1)-e,o.x=((o.x-e)%i+i)%i+e):(e=this.settings.rtl?this.coordinates(this.maximum()):this.coordinates(this.minimum()),i=this.settings.rtl?this.coordinates(this.minimum()):this.coordinates(this.maximum()),s=this.settings.pullDrag?-1*n.x/5:0,o.x=Math.max(Math.min(o.x,e+s),i+s)),this._drag.stage.current=o,this.animate(o.x))},n.prototype.onDragEnd=function(e){var s=this.difference(this._drag.pointer,this.pointer(e)),n=this._drag.stage.current,o=s.x>0^this.settings.rtl?"left":"right";t(i).off(".owl.core"),this.$element.removeClass(this.options.grabClass),(0!==s.x&&this.is("dragging")||!this.is("valid"))&&(this.speed(this.settings.dragEndSpeed||this.settings.smartSpeed),this.current(this.closest(n.x,0!==s.x?o:this._drag.direction)),this.invalidate("position"),this.update(),this._drag.direction=o,(Math.abs(s.x)>3||(new Date).getTime()-this._drag.time>300)&&this._drag.target.one("click.owl.core",(function(){return!1}))),this.is("dragging")&&(this.leave("dragging"),this.trigger("dragged"))},n.prototype.closest=function(e,i){var n=-1,o=this.width(),r=this.coordinates();return this.settings.freeDrag||t.each(r,t.proxy((function(t,a){return"left"===i&&e>a-30&&e<a+30?n=t:"right"===i&&e>a-o-30&&e<a-o+30?n=t+1:this.op(e,"<",a)&&this.op(e,">",r[t+1]!==s?r[t+1]:a-o)&&(n="left"===i?t+1:t),-1===n}),this)),this.settings.loop||(this.op(e,">",r[this.minimum()])?n=e=this.minimum():this.op(e,"<",r[this.maximum()])&&(n=e=this.maximum())),n},n.prototype.animate=function(e){var i=this.speed()>0;this.is("animating")&&this.onTransitionEnd(),i&&(this.enter("animating"),this.trigger("translate")),t.support.transform3d&&t.support.transition?this.$stage.css({transform:"translate3d("+e+"px,0px,0px)",transition:this.speed()/1e3+"s"+(this.settings.slideTransition?" "+this.settings.slideTransition:"")}):i?this.$stage.animate({left:e+"px"},this.speed(),this.settings.fallbackEasing,t.proxy(this.onTransitionEnd,this)):this.$stage.css({left:e+"px"})},n.prototype.is=function(t){return this._states.current[t]&&this._states.current[t]>0},n.prototype.current=function(t){if(t===s)return this._current;if(0===this._items.length)return s;if(t=this.normalize(t),this._current!==t){var e=this.trigger("change",{property:{name:"position",value:t}});e.data!==s&&(t=this.normalize(e.data)),this._current=t,this.invalidate("position"),this.trigger("changed",{property:{name:"position",value:this._current}})}return this._current},n.prototype.invalidate=function(e){return"string"===t.type(e)&&(this._invalidated[e]=!0,this.is("valid")&&this.leave("valid")),t.map(this._invalidated,(function(t,e){return e}))},n.prototype.reset=function(t){(t=this.normalize(t))!==s&&(this._speed=0,this._current=t,this.suppress(["translate","translated"]),this.animate(this.coordinates(t)),this.release(["translate","translated"]))},n.prototype.normalize=function(t,e){var i=this._items.length,n=e?0:this._clones.length;return!this.isNumeric(t)||i<1?t=s:(t<0||t>=i+n)&&(t=((t-n/2)%i+i)%i+n/2),t},n.prototype.relative=function(t){return t-=this._clones.length/2,this.normalize(t,!0)},n.prototype.maximum=function(t){var e,i,s,n=this.settings,o=this._coordinates.length;if(n.loop)o=this._clones.length/2+this._items.length-1;else if(n.autoWidth||n.merge){if(e=this._items.length)for(i=this._items[--e].width(),s=this.$element.width();e--&&!((i+=this._items[e].width()+this.settings.margin)>s););o=e+1}else o=n.center?this._items.length-1:this._items.length-n.items;return t&&(o-=this._clones.length/2),Math.max(o,0)},n.prototype.minimum=function(t){return t?0:this._clones.length/2},n.prototype.items=function(t){return t===s?this._items.slice():(t=this.normalize(t,!0),this._items[t])},n.prototype.mergers=function(t){return t===s?this._mergers.slice():(t=this.normalize(t,!0),this._mergers[t])},n.prototype.clones=function(e){var i=this._clones.length/2,n=i+this._items.length,o=function(t){return t%2==0?n+t/2:i-(t+1)/2};return e===s?t.map(this._clones,(function(t,e){return o(e)})):t.map(this._clones,(function(t,i){return t===e?o(i):null}))},n.prototype.speed=function(t){return t!==s&&(this._speed=t),this._speed},n.prototype.coordinates=function(e){var i,n=1,o=e-1;return e===s?t.map(this._coordinates,t.proxy((function(t,e){return this.coordinates(e)}),this)):(this.settings.center?(this.settings.rtl&&(n=-1,o=e+1),i=this._coordinates[e],i+=(this.width()-i+(this._coordinates[o]||0))/2*n):i=this._coordinates[o]||0,i=Math.ceil(i))},n.prototype.duration=function(t,e,i){return 0===i?0:Math.min(Math.max(Math.abs(e-t),1),6)*Math.abs(i||this.settings.smartSpeed)},n.prototype.to=function(t,e){var i=this.current(),s=null,n=t-this.relative(i),o=(n>0)-(n<0),r=this._items.length,a=this.minimum(),l=this.maximum();this.settings.loop?(!this.settings.rewind&&Math.abs(n)>r/2&&(n+=-1*o*r),(s=(((t=i+n)-a)%r+r)%r+a)!==t&&s-n<=l&&s-n>0&&(i=s-n,t=s,this.reset(i))):t=this.settings.rewind?(t%(l+=1)+l)%l:Math.max(a,Math.min(l,t)),this.speed(this.duration(i,t,e)),this.current(t),this.isVisible()&&this.update()},n.prototype.next=function(t){t=t||!1,this.to(this.relative(this.current())+1,t)},n.prototype.prev=function(t){t=t||!1,this.to(this.relative(this.current())-1,t)},n.prototype.onTransitionEnd=function(t){if(t!==s&&(t.stopPropagation(),(t.target||t.srcElement||t.originalTarget)!==this.$stage.get(0)))return!1;this.leave("animating"),this.trigger("translated")},n.prototype.viewport=function(){var s;return this.options.responsiveBaseElement!==e?s=t(this.options.responsiveBaseElement).width():e.innerWidth?s=e.innerWidth:i.documentElement&&i.documentElement.clientWidth?s=i.documentElement.clientWidth:console.warn("Can not detect viewport width."),s},n.prototype.replace=function(e){this.$stage.empty(),this._items=[],e&&(e=e instanceof jQuery?e:t(e)),this.settings.nestedItemSelector&&(e=e.find("."+this.settings.nestedItemSelector)),e.filter((function(){return 1===this.nodeType})).each(t.proxy((function(t,e){e=this.prepare(e),this.$stage.append(e),this._items.push(e),this._mergers.push(1*e.find("[data-merge]").addBack("[data-merge]").attr("data-merge")||1)}),this)),this.reset(this.isNumeric(this.settings.startPosition)?this.settings.startPosition:0),this.invalidate("items")},n.prototype.add=function(e,i){var n=this.relative(this._current);i=i===s?this._items.length:this.normalize(i,!0),e=e instanceof jQuery?e:t(e),this.trigger("add",{content:e,position:i}),e=this.prepare(e),0===this._items.length||i===this._items.length?(0===this._items.length&&this.$stage.append(e),0!==this._items.length&&this._items[i-1].after(e),this._items.push(e),this._mergers.push(1*e.find("[data-merge]").addBack("[data-merge]").attr("data-merge")||1)):(this._items[i].before(e),this._items.splice(i,0,e),this._mergers.splice(i,0,1*e.find("[data-merge]").addBack("[data-merge]").attr("data-merge")||1)),this._items[n]&&this.reset(this._items[n].index()),this.invalidate("items"),this.trigger("added",{content:e,position:i})},n.prototype.remove=function(t){(t=this.normalize(t,!0))!==s&&(this.trigger("remove",{content:this._items[t],position:t}),this._items[t].remove(),this._items.splice(t,1),this._mergers.splice(t,1),this.invalidate("items"),this.trigger("removed",{content:null,position:t}))},n.prototype.preloadAutoWidthImages=function(e){e.each(t.proxy((function(e,i){this.enter("pre-loading"),i=t(i),t(new Image).one("load",t.proxy((function(t){i.attr("src",t.target.src),i.css("opacity",1),this.leave("pre-loading"),!this.is("pre-loading")&&!this.is("initializing")&&this.refresh()}),this)).attr("src",i.attr("src")||i.attr("data-src")||i.attr("data-src-retina"))}),this))},n.prototype.destroy=function(){for(var s in this.$element.off(".owl.core"),this.$stage.off(".owl.core"),t(i).off(".owl.core"),!1!==this.settings.responsive&&(e.clearTimeout(this.resizeTimer),this.off(e,"resize",this._handlers.onThrottledResize)),this._plugins)this._plugins[s].destroy();this.$stage.children(".cloned").remove(),this.$stage.unwrap(),this.$stage.children().contents().unwrap(),this.$stage.children().unwrap(),this.$stage.remove(),this.$element.removeClass(this.options.refreshClass).removeClass(this.options.loadingClass).removeClass(this.options.loadedClass).removeClass(this.options.rtlClass).removeClass(this.options.dragClass).removeClass(this.options.grabClass).attr("class",this.$element.attr("class").replace(new RegExp(this.options.responsiveClass+"-\\S+\\s","g"),"")).removeData("owl.carousel")},n.prototype.op=function(t,e,i){var s=this.settings.rtl;switch(e){case"<":return s?t>i:t<i;case">":return s?t<i:t>i;case">=":return s?t<=i:t>=i;case"<=":return s?t>=i:t<=i}},n.prototype.on=function(t,e,i,s){t.addEventListener?t.addEventListener(e,i,s):t.attachEvent&&t.attachEvent("on"+e,i)},n.prototype.off=function(t,e,i,s){t.removeEventListener?t.removeEventListener(e,i,s):t.detachEvent&&t.detachEvent("on"+e,i)},n.prototype.trigger=function(e,i,s,o,r){var a={item:{count:this._items.length,index:this.current()}},l=t.camelCase(t.grep(["on",e,s],(function(t){return t})).join("-").toLowerCase()),h=t.Event([e,"owl",s||"carousel"].join(".").toLowerCase(),t.extend({relatedTarget:this},a,i));return this._supress[e]||(t.each(this._plugins,(function(t,e){e.onTrigger&&e.onTrigger(h)})),this.register({type:n.Type.Event,name:e}),this.$element.trigger(h),this.settings&&"function"==typeof this.settings[l]&&this.settings[l].call(this,h)),h},n.prototype.enter=function(e){t.each([e].concat(this._states.tags[e]||[]),t.proxy((function(t,e){this._states.current[e]===s&&(this._states.current[e]=0),this._states.current[e]++}),this))},n.prototype.leave=function(e){t.each([e].concat(this._states.tags[e]||[]),t.proxy((function(t,e){this._states.current[e]--}),this))},n.prototype.register=function(e){if(e.type===n.Type.Event){if(t.event.special[e.name]||(t.event.special[e.name]={}),!t.event.special[e.name].owl){var i=t.event.special[e.name]._default;t.event.special[e.name]._default=function(t){return!i||!i.apply||t.namespace&&-1!==t.namespace.indexOf("owl")?t.namespace&&t.namespace.indexOf("owl")>-1:i.apply(this,arguments)},t.event.special[e.name].owl=!0}}else e.type===n.Type.State&&(this._states.tags[e.name]?this._states.tags[e.name]=this._states.tags[e.name].concat(e.tags):this._states.tags[e.name]=e.tags,this._states.tags[e.name]=t.grep(this._states.tags[e.name],t.proxy((function(i,s){return t.inArray(i,this._states.tags[e.name])===s}),this)))},n.prototype.suppress=function(e){t.each(e,t.proxy((function(t,e){this._supress[e]=!0}),this))},n.prototype.release=function(e){t.each(e,t.proxy((function(t,e){delete this._supress[e]}),this))},n.prototype.pointer=function(t){var i={x:null,y:null};return(t=(t=t.originalEvent||t||e.event).touches&&t.touches.length?t.touches[0]:t.changedTouches&&t.changedTouches.length?t.changedTouches[0]:t).pageX?(i.x=t.pageX,i.y=t.pageY):(i.x=t.clientX,i.y=t.clientY),i},n.prototype.isNumeric=function(t){return!isNaN(parseFloat(t))},n.prototype.difference=function(t,e){return{x:t.x-e.x,y:t.y-e.y}},t.fn.owlCarousel=function(e){var i=Array.prototype.slice.call(arguments,1);return this.each((function(){var s=t(this),o=s.data("owl.carousel");o||(o=new n(this,"object"==typeof e&&e),s.data("owl.carousel",o),t.each(["next","prev","to","destroy","refresh","replace","add","remove"],(function(e,i){o.register({type:n.Type.Event,name:i}),o.$element.on(i+".owl.carousel.core",t.proxy((function(t){t.namespace&&t.relatedTarget!==this&&(this.suppress([i]),o[i].apply(this,[].slice.call(arguments,1)),this.release([i]))}),o))}))),"string"==typeof e&&"_"!==e.charAt(0)&&o[e].apply(o,i)}))},t.fn.owlCarousel.Constructor=n}(window.Zepto||window.jQuery,window,document),function(t,e){var i=function(e){this._core=e,this._interval=null,this._visible=null,this._handlers={"initialized.owl.carousel":t.proxy((function(t){t.namespace&&this._core.settings.autoRefresh&&this.watch()}),this)},this._core.options=t.extend({},i.Defaults,this._core.options),this._core.$element.on(this._handlers)};i.Defaults={autoRefresh:!0,autoRefreshInterval:500},i.prototype.watch=function(){this._interval||(this._visible=this._core.isVisible(),this._interval=e.setInterval(t.proxy(this.refresh,this),this._core.settings.autoRefreshInterval))},i.prototype.refresh=function(){this._core.isVisible()!==this._visible&&(this._visible=!this._visible,this._core.$element.toggleClass("owl-hidden",!this._visible),this._visible&&this._core.invalidate("width")&&this._core.refresh())},i.prototype.destroy=function(){var t,i;for(t in e.clearInterval(this._interval),this._handlers)this._core.$element.off(t,this._handlers[t]);for(i in Object.getOwnPropertyNames(this))"function"!=typeof this[i]&&(this[i]=null)},t.fn.owlCarousel.Constructor.Plugins.AutoRefresh=i}(window.Zepto||window.jQuery,window,document),function(t,e){var i=function(e){this._core=e,this._loaded=[],this._handlers={"initialized.owl.carousel change.owl.carousel resized.owl.carousel":t.proxy((function(e){if(e.namespace&&this._core.settings&&this._core.settings.lazyLoad&&(e.property&&"position"==e.property.name||"initialized"==e.type)){var i=this._core.settings,s=i.center&&Math.ceil(i.items/2)||i.items,n=i.center&&-1*s||0,o=(e.property&&undefined!==e.property.value?e.property.value:this._core.current())+n,r=this._core.clones().length,a=t.proxy((function(t,e){this.load(e)}),this);for(i.lazyLoadEager>0&&(s+=i.lazyLoadEager,i.loop&&(o-=i.lazyLoadEager,s++));n++<s;)this.load(r/2+this._core.relative(o)),r&&t.each(this._core.clones(this._core.relative(o)),a),o++}}),this)},this._core.options=t.extend({},i.Defaults,this._core.options),this._core.$element.on(this._handlers)};i.Defaults={lazyLoad:!1,lazyLoadEager:0},i.prototype.load=function(i){var s=this._core.$stage.children().eq(i),n=s&&s.find(".owl-lazy");!n||t.inArray(s.get(0),this._loaded)>-1||(n.each(t.proxy((function(i,s){var n,o=t(s),r=e.devicePixelRatio>1&&o.attr("data-src-retina")||o.attr("data-src")||o.attr("data-srcset");this._core.trigger("load",{element:o,url:r},"lazy"),o.is("img")?o.one("load.owl.lazy",t.proxy((function(){o.css("opacity",1),this._core.trigger("loaded",{element:o,url:r},"lazy")}),this)).attr("src",r):o.is("source")?o.one("load.owl.lazy",t.proxy((function(){this._core.trigger("loaded",{element:o,url:r},"lazy")}),this)).attr("srcset",r):((n=new Image).onload=t.proxy((function(){o.css({"background-image":'url("'+r+'")',opacity:"1"}),this._core.trigger("loaded",{element:o,url:r},"lazy")}),this),n.src=r)}),this)),this._loaded.push(s.get(0)))},i.prototype.destroy=function(){var t,e;for(t in this.handlers)this._core.$element.off(t,this.handlers[t]);for(e in Object.getOwnPropertyNames(this))"function"!=typeof this[e]&&(this[e]=null)},t.fn.owlCarousel.Constructor.Plugins.Lazy=i}(window.Zepto||window.jQuery,window,document),function(t,e){var i=function(s){this._core=s,this._previousHeight=null,this._handlers={"initialized.owl.carousel refreshed.owl.carousel":t.proxy((function(t){t.namespace&&this._core.settings.autoHeight&&this.update()}),this),"changed.owl.carousel":t.proxy((function(t){t.namespace&&this._core.settings.autoHeight&&"position"===t.property.name&&this.update()}),this),"loaded.owl.lazy":t.proxy((function(t){t.namespace&&this._core.settings.autoHeight&&t.element.closest("."+this._core.settings.itemClass).index()===this._core.current()&&this.update()}),this)},this._core.options=t.extend({},i.Defaults,this._core.options),this._core.$element.on(this._handlers),this._intervalId=null;var n=this;t(e).on("load",(function(){n._core.settings.autoHeight&&n.update()})),t(e).resize((function(){n._core.settings.autoHeight&&(null!=n._intervalId&&clearTimeout(n._intervalId),n._intervalId=setTimeout((function(){n.update()}),250))}))};i.Defaults={autoHeight:!1,autoHeightClass:"owl-height"},i.prototype.update=function(){var e=this._core._current,i=e+this._core.settings.items,s=this._core.settings.lazyLoad,n=this._core.$stage.children().toArray().slice(e,i),o=[],r=0;t.each(n,(function(e,i){o.push(t(i).height())})),(r=Math.max.apply(null,o))<=1&&s&&this._previousHeight&&(r=this._previousHeight),this._previousHeight=r,this._core.$stage.parent().height(r).addClass(this._core.settings.autoHeightClass)},i.prototype.destroy=function(){var t,e;for(t in this._handlers)this._core.$element.off(t,this._handlers[t]);for(e in Object.getOwnPropertyNames(this))"function"!=typeof this[e]&&(this[e]=null)},t.fn.owlCarousel.Constructor.Plugins.AutoHeight=i}(window.Zepto||window.jQuery,window,document),function(t,e,i){var s=function(e){this._core=e,this._videos={},this._playing=null,this._handlers={"initialized.owl.carousel":t.proxy((function(t){t.namespace&&this._core.register({type:"state",name:"playing",tags:["interacting"]})}),this),"resize.owl.carousel":t.proxy((function(t){t.namespace&&this._core.settings.video&&this.isInFullScreen()&&t.preventDefault()}),this),"refreshed.owl.carousel":t.proxy((function(t){t.namespace&&this._core.is("resizing")&&this._core.$stage.find(".cloned .owl-video-frame").remove()}),this),"changed.owl.carousel":t.proxy((function(t){t.namespace&&"position"===t.property.name&&this._playing&&this.stop()}),this),"prepared.owl.carousel":t.proxy((function(e){if(e.namespace){var i=t(e.content).find(".owl-video");i.length&&(i.css("display","none"),this.fetch(i,t(e.content)))}}),this)},this._core.options=t.extend({},s.Defaults,this._core.options),this._core.$element.on(this._handlers),this._core.$element.on("click.owl.video",".owl-video-play-icon",t.proxy((function(t){this.play(t)}),this))};s.Defaults={video:!1,videoHeight:!1,videoWidth:!1},s.prototype.fetch=function(t,e){var i=t.attr("data-vimeo-id")?"vimeo":t.attr("data-vzaar-id")?"vzaar":"youtube",s=t.attr("data-vimeo-id")||t.attr("data-youtube-id")||t.attr("data-vzaar-id"),n=t.attr("data-width")||this._core.settings.videoWidth,o=t.attr("data-height")||this._core.settings.videoHeight,r=t.attr("href");if(!r)throw new Error("Missing video URL.");if((s=r.match(/(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com|be\-nocookie\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/))[3].indexOf("youtu")>-1)i="youtube";else if(s[3].indexOf("vimeo")>-1)i="vimeo";else{if(!(s[3].indexOf("vzaar")>-1))throw new Error("Video URL not supported.");i="vzaar"}s=s[6],this._videos[r]={type:i,id:s,width:n,height:o},e.attr("data-video",r),this.thumbnail(t,this._videos[r])},s.prototype.thumbnail=function(e,i){var s,n,o=i.width&&i.height?"width:"+i.width+"px;height:"+i.height+"px;":"",r=e.find("img"),a="src",l="",h=this._core.settings,c=function(i){s=h.lazyLoad?t("<div/>",{class:"owl-video-tn "+l,srcType:i}):t("<div/>",{class:"owl-video-tn",style:"opacity:1;background-image:url("+i+")"}),e.after(s),e.after('<div class="owl-video-play-icon"></div>')};if(e.wrap(t("<div/>",{class:"owl-video-wrapper",style:o})),this._core.settings.lazyLoad&&(a="data-src",l="owl-lazy"),r.length)return c(r.attr(a)),r.remove(),!1;"youtube"===i.type?(n="//img.youtube.com/vi/"+i.id+"/hqdefault.jpg",c(n)):"vimeo"===i.type?t.ajax({type:"GET",url:"//vimeo.com/api/v2/video/"+i.id+".json",jsonp:"callback",dataType:"jsonp",success:function(t){n=t[0].thumbnail_large,c(n)}}):"vzaar"===i.type&&t.ajax({type:"GET",url:"//vzaar.com/api/videos/"+i.id+".json",jsonp:"callback",dataType:"jsonp",success:function(t){n=t.framegrab_url,c(n)}})},s.prototype.stop=function(){this._core.trigger("stop",null,"video"),this._playing.find(".owl-video-frame").remove(),this._playing.removeClass("owl-video-playing"),this._playing=null,this._core.leave("playing"),this._core.trigger("stopped",null,"video")},s.prototype.play=function(e){var i,s=t(e.target).closest("."+this._core.settings.itemClass),n=this._videos[s.attr("data-video")],o=n.width||"100%",r=n.height||this._core.$stage.height();this._playing||(this._core.enter("playing"),this._core.trigger("play",null,"video"),s=this._core.items(this._core.relative(s.index())),this._core.reset(s.index()),(i=t('<iframe frameborder="0" allowfullscreen mozallowfullscreen webkitAllowFullScreen ></iframe>')).attr("height",r),i.attr("width",o),"youtube"===n.type?i.attr("src","//www.youtube.com/embed/"+n.id+"?autoplay=1&rel=0&v="+n.id):"vimeo"===n.type?i.attr("src","//player.vimeo.com/video/"+n.id+"?autoplay=1"):"vzaar"===n.type&&i.attr("src","//view.vzaar.com/"+n.id+"/player?autoplay=true"),t(i).wrap('<div class="owl-video-frame" />').insertAfter(s.find(".owl-video")),this._playing=s.addClass("owl-video-playing"))},s.prototype.isInFullScreen=function(){var e=i.fullscreenElement||i.mozFullScreenElement||i.webkitFullscreenElement;return e&&t(e).parent().hasClass("owl-video-frame")},s.prototype.destroy=function(){var t,e;for(t in this._core.$element.off("click.owl.video"),this._handlers)this._core.$element.off(t,this._handlers[t]);for(e in Object.getOwnPropertyNames(this))"function"!=typeof this[e]&&(this[e]=null)},t.fn.owlCarousel.Constructor.Plugins.Video=s}(window.Zepto||window.jQuery,window,document),function(t,e,i,s){var n=function(e){this.core=e,this.core.options=t.extend({},n.Defaults,this.core.options),this.swapping=!0,this.previous=s,this.next=s,this.handlers={"change.owl.carousel":t.proxy((function(t){t.namespace&&"position"==t.property.name&&(this.previous=this.core.current(),this.next=t.property.value)}),this),"drag.owl.carousel dragged.owl.carousel translated.owl.carousel":t.proxy((function(t){t.namespace&&(this.swapping="translated"==t.type)}),this),"translate.owl.carousel":t.proxy((function(t){t.namespace&&this.swapping&&(this.core.options.animateOut||this.core.options.animateIn)&&this.swap()}),this)},this.core.$element.on(this.handlers)};n.Defaults={animateOut:!1,animateIn:!1},n.prototype.swap=function(){if(1===this.core.settings.items&&t.support.animation&&t.support.transition){this.core.speed(0);var e,i=t.proxy(this.clear,this),s=this.core.$stage.children().eq(this.previous),n=this.core.$stage.children().eq(this.next),o=this.core.settings.animateIn,r=this.core.settings.animateOut;this.core.current()!==this.previous&&(r&&(e=this.core.coordinates(this.previous)-this.core.coordinates(this.next),s.one(t.support.animation.end,i).css({left:e+"px"}).addClass("animated owl-animated-out").addClass(r)),o&&n.one(t.support.animation.end,i).addClass("animated owl-animated-in").addClass(o))}},n.prototype.clear=function(e){t(e.target).css({left:""}).removeClass("animated owl-animated-out owl-animated-in").removeClass(this.core.settings.animateIn).removeClass(this.core.settings.animateOut),this.core.onTransitionEnd()},n.prototype.destroy=function(){var t,e;for(t in this.handlers)this.core.$element.off(t,this.handlers[t]);for(e in Object.getOwnPropertyNames(this))"function"!=typeof this[e]&&(this[e]=null)},t.fn.owlCarousel.Constructor.Plugins.Animate=n}(window.Zepto||window.jQuery,window,document),function(t,e,i){var s=function(e){this._core=e,this._call=null,this._time=0,this._timeout=0,this._paused=!0,this._handlers={"changed.owl.carousel":t.proxy((function(t){t.namespace&&"settings"===t.property.name?this._core.settings.autoplay?this.play():this.stop():t.namespace&&"position"===t.property.name&&this._paused&&(this._time=0)}),this),"initialized.owl.carousel":t.proxy((function(t){t.namespace&&this._core.settings.autoplay&&this.play()}),this),"play.owl.autoplay":t.proxy((function(t,e,i){t.namespace&&this.play(e,i)}),this),"stop.owl.autoplay":t.proxy((function(t){t.namespace&&this.stop()}),this),"mouseover.owl.autoplay":t.proxy((function(){this._core.settings.autoplayHoverPause&&this._core.is("rotating")&&this.pause()}),this),"mouseleave.owl.autoplay":t.proxy((function(){this._core.settings.autoplayHoverPause&&this._core.is("rotating")&&this.play()}),this),"touchstart.owl.core":t.proxy((function(){this._core.settings.autoplayHoverPause&&this._core.is("rotating")&&this.pause()}),this),"touchend.owl.core":t.proxy((function(){this._core.settings.autoplayHoverPause&&this.play()}),this)},this._core.$element.on(this._handlers),this._core.options=t.extend({},s.Defaults,this._core.options)};s.Defaults={autoplay:!1,autoplayTimeout:5e3,autoplayHoverPause:!1,autoplaySpeed:!1},s.prototype._next=function(s){this._call=e.setTimeout(t.proxy(this._next,this,s),this._timeout*(Math.round(this.read()/this._timeout)+1)-this.read()),this._core.is("interacting")||i.hidden||this._core.next(s||this._core.settings.autoplaySpeed)},s.prototype.read=function(){return(new Date).getTime()-this._time},s.prototype.play=function(i,s){var n;this._core.is("rotating")||this._core.enter("rotating"),i=i||this._core.settings.autoplayTimeout,n=Math.min(this._time%(this._timeout||i),i),this._paused?(this._time=this.read(),this._paused=!1):e.clearTimeout(this._call),this._time+=this.read()%i-n,this._timeout=i,this._call=e.setTimeout(t.proxy(this._next,this,s),i-n)},s.prototype.stop=function(){this._core.is("rotating")&&(this._time=0,this._paused=!0,e.clearTimeout(this._call),this._core.leave("rotating"))},s.prototype.pause=function(){this._core.is("rotating")&&!this._paused&&(this._time=this.read(),this._paused=!0,e.clearTimeout(this._call))},s.prototype.destroy=function(){var t,e;for(t in this.stop(),this._handlers)this._core.$element.off(t,this._handlers[t]);for(e in Object.getOwnPropertyNames(this))"function"!=typeof this[e]&&(this[e]=null)},t.fn.owlCarousel.Constructor.Plugins.autoplay=s}(window.Zepto||window.jQuery,window,document),function(t){"use strict";var e=function(i){this._core=i,this._initialized=!1,this._pages=[],this._controls={},this._templates=[],this.$element=this._core.$element,this._overrides={next:this._core.next,prev:this._core.prev,to:this._core.to},this._handlers={"prepared.owl.carousel":t.proxy((function(e){e.namespace&&this._core.settings.dotsData&&this._templates.push('<div class="'+this._core.settings.dotClass+'">'+t(e.content).find("[data-dot]").addBack("[data-dot]").attr("data-dot")+"</div>")}),this),"added.owl.carousel":t.proxy((function(t){t.namespace&&this._core.settings.dotsData&&this._templates.splice(t.position,0,this._templates.pop())}),this),"remove.owl.carousel":t.proxy((function(t){t.namespace&&this._core.settings.dotsData&&this._templates.splice(t.position,1)}),this),"changed.owl.carousel":t.proxy((function(t){t.namespace&&"position"==t.property.name&&this.draw()}),this),"initialized.owl.carousel":t.proxy((function(t){t.namespace&&!this._initialized&&(this._core.trigger("initialize",null,"navigation"),this.initialize(),this.update(),this.draw(),this._initialized=!0,this._core.trigger("initialized",null,"navigation"))}),this),"refreshed.owl.carousel":t.proxy((function(t){t.namespace&&this._initialized&&(this._core.trigger("refresh",null,"navigation"),this.update(),this.draw(),this._core.trigger("refreshed",null,"navigation"))}),this)},this._core.options=t.extend({},e.Defaults,this._core.options),this.$element.on(this._handlers)};e.Defaults={nav:!1,navText:['<span aria-label="Previous">&#x2039;</span>','<span aria-label="Next">&#x203a;</span>'],navSpeed:!1,navElement:'button type="button" role="presentation"',navContainer:!1,navContainerClass:"owl-nav",navClass:["owl-prev","owl-next"],slideBy:1,dotClass:"owl-dot",dotsClass:"owl-dots",dots:!0,dotsEach:!1,dotsData:!1,dotsSpeed:!1,dotsContainer:!1},e.prototype.initialize=function(){var e,i=this._core.settings;for(e in this._controls.$relative=(i.navContainer?t(i.navContainer):t("<div>").addClass(i.navContainerClass).appendTo(this.$element)).addClass("disabled"),this._controls.$previous=t("<"+i.navElement+">").addClass(i.navClass[0]).html(i.navText[0]).prependTo(this._controls.$relative).on("click",t.proxy((function(t){this.prev(i.navSpeed)}),this)),this._controls.$next=t("<"+i.navElement+">").addClass(i.navClass[1]).html(i.navText[1]).appendTo(this._controls.$relative).on("click",t.proxy((function(t){this.next(i.navSpeed)}),this)),i.dotsData||(this._templates=[t('<button role="button">').addClass(i.dotClass).append(t("<span>")).prop("outerHTML")]),this._controls.$absolute=(i.dotsContainer?t(i.dotsContainer):t("<div>").addClass(i.dotsClass).appendTo(this.$element)).addClass("disabled"),this._controls.$absolute.on("click","button",t.proxy((function(e){var s=t(e.target).parent().is(this._controls.$absolute)?t(e.target).index():t(e.target).parent().index();e.preventDefault(),this.to(s,i.dotsSpeed)}),this)),this._overrides)this._core[e]=t.proxy(this[e],this)},e.prototype.destroy=function(){var t,e,i,s,n;for(t in n=this._core.settings,this._handlers)this.$element.off(t,this._handlers[t]);for(e in this._controls)"$relative"===e&&n.navContainer?this._controls[e].html(""):this._controls[e].remove();for(s in this.overides)this._core[s]=this._overrides[s];for(i in Object.getOwnPropertyNames(this))"function"!=typeof this[i]&&(this[i]=null)},e.prototype.update=function(){var t,e,i=this._core.clones().length/2,s=i+this._core.items().length,n=this._core.maximum(!0),o=this._core.settings,r=o.center||o.autoWidth||o.dotsData?1:o.dotsEach||o.items;if("page"!==o.slideBy&&(o.slideBy=Math.min(o.slideBy,o.items)),o.dots||"page"==o.slideBy)for(this._pages=[],t=i,e=0,0;t<s;t++){if(e>=r||0===e){if(this._pages.push({start:Math.min(n,t-i),end:t-i+r-1}),Math.min(n,t-i)===n)break;e=0}e+=this._core.mergers(this._core.relative(t))}},e.prototype.draw=function(){var e,i=this._core.settings,s=this._core.items().length<=i.items,n=this._core.relative(this._core.current()),o=i.loop||i.rewind;this._controls.$relative.toggleClass("disabled",!i.nav||s),i.nav&&(this._controls.$previous.toggleClass("disabled",!o&&n<=this._core.minimum(!0)),this._controls.$next.toggleClass("disabled",!o&&n>=this._core.maximum(!0))),this._controls.$absolute.toggleClass("disabled",!i.dots||s),i.dots&&(e=this._pages.length-this._controls.$absolute.children().length,i.dotsData&&0!==e?this._controls.$absolute.html(this._templates.join("")):e>0?this._controls.$absolute.append(new Array(e+1).join(this._templates[0])):e<0&&this._controls.$absolute.children().slice(e).remove(),this._controls.$absolute.find(".active").removeClass("active"),this._controls.$absolute.children().eq(t.inArray(this.current(),this._pages)).addClass("active"))},e.prototype.onTrigger=function(e){var i=this._core.settings;e.page={index:t.inArray(this.current(),this._pages),count:this._pages.length,size:i&&(i.center||i.autoWidth||i.dotsData?1:i.dotsEach||i.items)}},e.prototype.current=function(){var e=this._core.relative(this._core.current());return t.grep(this._pages,t.proxy((function(t,i){return t.start<=e&&t.end>=e}),this)).pop()},e.prototype.getPosition=function(e){var i,s,n=this._core.settings;return"page"==n.slideBy?(i=t.inArray(this.current(),this._pages),s=this._pages.length,e?++i:--i,i=this._pages[(i%s+s)%s].start):(i=this._core.relative(this._core.current()),s=this._core.items().length,e?i+=n.slideBy:i-=n.slideBy),i},e.prototype.next=function(e){t.proxy(this._overrides.to,this._core)(this.getPosition(!0),e)},e.prototype.prev=function(e){t.proxy(this._overrides.to,this._core)(this.getPosition(!1),e)},e.prototype.to=function(e,i,s){var n;!s&&this._pages.length?(n=this._pages.length,t.proxy(this._overrides.to,this._core)(this._pages[(e%n+n)%n].start,i)):t.proxy(this._overrides.to,this._core)(e,i)},t.fn.owlCarousel.Constructor.Plugins.Navigation=e}(window.Zepto||window.jQuery,window,document),function(t,e){"use strict";var i=function(s){this._core=s,this._hashes={},this.$element=this._core.$element,this._handlers={"initialized.owl.carousel":t.proxy((function(i){i.namespace&&"URLHash"===this._core.settings.startPosition&&t(e).trigger("hashchange.owl.navigation")}),this),"prepared.owl.carousel":t.proxy((function(e){if(e.namespace){var i=t(e.content).find("[data-hash]").addBack("[data-hash]").attr("data-hash");if(!i)return;this._hashes[i]=e.content}}),this),"changed.owl.carousel":t.proxy((function(i){if(i.namespace&&"position"===i.property.name){var s=this._core.items(this._core.relative(this._core.current())),n=t.map(this._hashes,(function(t,e){return t===s?e:null})).join();if(!n||e.location.hash.slice(1)===n)return;e.location.hash=n}}),this)},this._core.options=t.extend({},i.Defaults,this._core.options),this.$element.on(this._handlers),t(e).on("hashchange.owl.navigation",t.proxy((function(t){var i=e.location.hash.substring(1),s=this._core.$stage.children(),n=this._hashes[i]&&s.index(this._hashes[i]);undefined!==n&&n!==this._core.current()&&this._core.to(this._core.relative(n),!1,!0)}),this))};i.Defaults={URLhashListener:!1},i.prototype.destroy=function(){var i,s;for(i in t(e).off("hashchange.owl.navigation"),this._handlers)this._core.$element.off(i,this._handlers[i]);for(s in Object.getOwnPropertyNames(this))"function"!=typeof this[s]&&(this[s]=null)},t.fn.owlCarousel.Constructor.Plugins.Hash=i}(window.Zepto||window.jQuery,window,document),function(t){var e=t("<support>").get(0).style,i="Webkit Moz O ms".split(" "),s={transition:{end:{WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",transition:"transitionend"}},animation:{end:{WebkitAnimation:"webkitAnimationEnd",MozAnimation:"animationend",OAnimation:"oAnimationEnd",animation:"animationend"}}},n=function(){return!!a("transform")},o=function(){return!!a("perspective")},r=function(){return!!a("animation")};function a(s,n){var o=!1,r=s.charAt(0).toUpperCase()+s.slice(1);return t.each((s+" "+i.join(r+" ")+r).split(" "),(function(t,i){if(undefined!==e[i])return o=!n||i,!1})),o}function l(t){return a(t,!0)}(function(){return!!a("transition")})()&&(t.support.transition=new String(l("transition")),t.support.transition.end=s.transition.end[t.support.transition]),r()&&(t.support.animation=new String(l("animation")),t.support.animation.end=s.animation.end[t.support.animation]),n()&&(t.support.transform=new String(l("transform")),t.support.transform3d=o())}(window.Zepto||window.jQuery,window,document)},669:t=>{"use strict";t.exports=jQuery}},e={};function i(s){var n=e[s];if(void 0!==n)return n.exports;var o=e[s]={exports:{}};return t[s](o,o.exports,i),o.exports}i.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return i.d(e,{a:e}),e},i.d=(t,e)=>{for(var s in e)i.o(e,s)&&!i.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:e[s]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{"use strict";i(626),i(586);var t=i(669),e=i.n(t);e()("body").find(".carousel-slider").each((function(){let t=e()(this),i=t.data("owl-settings");"object"==typeof i&&Object.assign(i,{navText:['<svg class="carousel-slider-nav-icon" viewBox="0 0 20 20"><path d="M14 5l-5 5 5 5-1 2-7-7 7-7z"/></svg>','<svg class="carousel-slider-nav-icon" viewBox="0 0 20 20"><path d="M6 15l5-5-5-5 1-2 7 7-7 7z"/></svg>']}),t.owlCarousel(i),"hero-banner-slider"===t.data("slide-type")&&(t.on("change.owl.carousel",(function(){let e=t.find(".carousel-slider-hero__cell__content"),i=e.data("animation");i&&e.removeClass("animated "+i).hide()})),t.on("changed.owl.carousel",(function(t){let e=jQuery(t.target).find(".carousel-slider-hero__cell__content").eq(t.item.index),s=e.data("animation");s&&setTimeout((function(){e.show().addClass("animated "+s)}),i.autoplaySpeed)}))),"product-carousel"===t.data("slide-type")?e()(this).find(".magnific-popup").magnificPopup({type:"ajax"}):"video-carousel"===t.data("slide-type")?e()(this).find(".magnific-popup").magnificPopup({type:"iframe"}):e()(this).find(".magnific-popup").magnificPopup({type:"image",gallery:{enabled:!0},zoom:{enabled:!0,duration:300,easing:"ease-in-out"}})}))})()})();assets/js/admin.js.LICENSE.txt000064400000000667151727276560012042 0ustar00/*!
 * Select2 4.0.13
 * https://select2.github.io
 *
 * Released under the MIT license
 * https://github.com/select2/select2/blob/master/LICENSE.md
 */

/**!
 * wp-color-picker-alpha
 *
 * Overwrite Automattic Iris for enabled Alpha Channel in wpColorPicker
 * Only run in input and is defined data alpha in true
 *
 * Version: 3.0.2
 * https://github.com/kallookoo/wp-color-picker-alpha
 * Licensed under the GPLv2 license or later.
 */
assets/js/admin-divi-modules.js000064400000002570151727276560012535 0ustar00(()=>{"use strict";var e={n:r=>{var t=r&&r.__esModule?()=>r.default:()=>r;return e.d(t,{a:t}),t},d:(r,t)=>{for(var i in t)e.o(t,i)&&!e.o(r,i)&&Object.defineProperty(r,i,{enumerable:!0,get:t[i]})},o:(e,r)=>Object.prototype.hasOwnProperty.call(e,r)};(()=>{const r=React;var t=e.n(r);const i=jQuery;var a,n,s,l=e.n(i);class o extends r.Component{render(){const e=this.props.slider_id;if(!e)return null;let r=new URL(window.csDivi.site_url);r.searchParams.append("carousel_slider_preview","1"),r.searchParams.append("carousel_slider_iframe","1"),r.searchParams.append("slider_id",e);let i=r.toString();return t().createElement("div",{className:"carousel-slider-iframe-container"},t().createElement("div",{className:"carousel-slider-iframe-overlay"}),t().createElement("iframe",{className:"carousel-slider-iframe",scrolling:"no",src:i,height:"0",width:"500"}))}}a=o,s="carousel_slider_divi_module",(n=function(e){var r=function(e,r){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var i=t.call(e,r||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(e)}(e,"string");return"symbol"==typeof r?r:r+""}(n="slug"))in a?Object.defineProperty(a,n,{value:s,enumerable:!0,configurable:!0,writable:!0}):a[n]=s,l()(window).on("et_builder_api_ready",((e,r)=>{r.registerModules([o])}))})()})();assets/js/frontend.js.LICENSE.txt000064400000000201151727276560012551 0ustar00/*! Magnific Popup - v1.2.0 - 2024-06-08
* http://dimsemenov.com/plugins/magnific-popup/
* Copyright (c) 2024 Dmytro Semenov; */
assets/js/admin-add-new-carousel.js000064400000033356151727276570013275 0ustar00(()=>{var e={113:(e,t,a)=>{"use strict";a.d(t,{a:()=>o});const o=(e,t={},a=[])=>{let o=document.createElement(e);return Object.keys(t).length&&Object.entries(t).forEach((([e,t])=>{o.setAttribute(e,t)})),a.length&&o.append(...a),o}},926:()=>{class e extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"});const t=document.createElement("style");t.textContent=e.getStyle(),this.shadowRoot.append(t,this.getElement())}getElement(){const e=document.createElement("button");return e.classList.add("shapla-cross"),this.hasAttribute("size")&&e.classList.add(`is-${this.getAttribute("size")}`),e}attributeChangedCallback(e,t,a){const o=this.shadowRoot.querySelector("button");"size"===e&&this.hasAttribute("size")&&o.classList.add(`is-${this.getAttribute("size")}`)}static get observedAttributes(){return["size"]}static getStyle(){return'.shapla-cross {\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  background-color: var(--delete-icon-background, hsla(0, 0%, 4%, .2));\n  border: none;\n  border-radius: 290486px;\n  cursor: pointer;\n  display: inline-block;\n  flex-grow: 0;\n  flex-shrink: 0;\n  font-size: 0;\n  height: var(--delete-icon-size, 20px);\n  outline: none;\n  pointer-events: auto;\n  position: relative;\n  -webkit-user-select: none;\n  user-select: none;\n  vertical-align: top;\n  width: var(--delete-icon-size, 20px)\n}\n\n.shapla-cross:after, .shapla-cross:before {\n  background-color: var(--delete-icon-color, #fff);\n  content: "";\n  display: block;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translateX(-50%) translateY(-50%) rotate(45deg);\n  transform-origin: center center\n}\n\n.shapla-cross:before {\n  height: 2px;\n  width: 50%\n}\n\n.shapla-cross:after {\n  height: 50%;\n  width: 2px\n}\n\n.shapla-cross:focus, .shapla-cross:hover {\n  background-color: var(--delete-icon-background-dark, hsla(0, 0%, 4%, .3))\n}\n\n.shapla-cross:active {\n  box-shadow: 0 3px 4px 0 rgba(0, 0, 0, .14), 0 3px 3px -2px rgba(0, 0, 0, .2), 0 1px 8px 0 rgba(0, 0, 0, .12)\n}\n\n.shapla-cross.is-small {\n  --delete-icon-size: 16px\n}\n\n.shapla-cross.is-medium {\n  --delete-icon-size: 24px\n}\n\n.shapla-cross.is-large {\n  --delete-icon-size: 32px\n}\n\n.shapla-cross.is-error {\n  --delete-icon-background: var(--shapla-error, #dc3545);\n  --delete-icon-background-dark: var(--shapla-error-variant, #d32535);\n  --delete-icon-color: var(--shapla-on-error, #fff)\n}'}}customElements.define("shapla-cross",e)}},t={};function a(o){var s=t[o];if(void 0!==s)return s.exports;var n=t[o]={exports:{}};return e[o](n,n.exports,a),n.exports}a.d=(e,t)=>{for(var o in t)a.o(t,o)&&!a.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";a(926);var e=a(113);class t extends HTMLElement{el(t,a={},o=[]){return(0,e.a)(t,a,o)}triggerCustomEvent(e){this.dispatchEvent(new CustomEvent(e))}}const o=t;class s extends o{constructor(){super(),this.attachShadow({mode:"open"});const e=document.createElement("style");e.textContent=s.getStyle(),this.shadowRoot.append(e,...this.getWrapperTemplate())}attributeChangedCallback(e,t,a){const o=this.shadowRoot.querySelector(".shapla-modal");if("open"===e&&this.hasAttribute("open")?o.classList.add("is-active"):o.classList.remove("is-active"),"type"===e){const e=this.shadowRoot.querySelector(".shapla-modal-content");"box"===a&&(e.classList.contains("shapla-modal-box")||e.classList.add("shapla-modal-box"))}}static get observedAttributes(){return["open","type"]}connectedCallback(){const e=this.getAttribute("type");if("card"===e){this.renderCardTemplate();const e=this.shadowRoot.querySelector(".shapla-modal-card__footer");e.querySelector("slot").assignedNodes().length<1&&e.classList.add("no-content")}"confirm"===e&&this.updateConfirmDom();const t=this.shadowRoot.querySelector(".shapla-modal-close.is-fixed"),a=this.shadowRoot.querySelector(".shapla-modal-content");"confirm"===e?(t.remove(),a.classList.add("shapla-modal-confirm"),a.innerHTML="",a.append(...this.getConfirmTemplate())):"box"===e&&a.classList.add("shapla-modal-box");const o=this.shadowRoot.querySelector(".shapla-modal-background"),s=this.getAttribute("backdrop-theme");-1!==["dark","light"].indexOf(s)&&o.classList.add(`is-${s}`),this.updateContentSize(),this.closeOnEscape(),this.closeOnBackdropClick(),this.closeOnCrossClick()}renderCardTemplate(){const e=this.shadowRoot.querySelector(".shapla-modal-close.is-fixed"),t=this.shadowRoot.querySelector(".shapla-modal-content");e.remove(),t.classList.add("shapla-modal-card"),t.innerHTML="",t.append(...this.getCartTemplate());const a=this.getAttribute("heading");a&&(this.shadowRoot.querySelector(".shapla-modal-card__title").innerHTML=a)}updateContentSize(){const e=this.getAttribute("content-size");-1!==["small","medium","large","full","custom"].indexOf(e)&&this.shadowRoot.querySelector(".shapla-modal-content").classList.add(`is-${e}`)}updateConfirmDom(){const e=this.getAttribute("icon")??"primary",t=this.getAttribute("heading"),a=this.getAttribute("message")??"Are you sure?",o=this.getAttribute("confirm-button")??"Ok",s=this.getAttribute("cancel-button")??"Cancel",n=this.shadowRoot.querySelector(".button--confirm"),l=this.shadowRoot.querySelector(".button--cancel");o&&(n.innerHTML=o),s&&(l.innerHTML=s);const r=this.shadowRoot.querySelector(".shapla-modal-confirm");-1!==["primary","success","error"].indexOf(e)&&r.querySelector(".shapla-modal-confirm__icon")?.classList.add(`is-${e}`),this.hasAttribute("content-size")||(this.setAttribute("content-size","small"),this.updateContentSize()),this.hasAttribute("disabled-backdrop-click")||this.setAttribute("disabled-backdrop-click",""),t.length&&(r.querySelector(".shapla-modal-confirm__title").innerHTML=t),a.length&&(r.querySelector(".shapla-modal-confirm__message").innerHTML=a),this.closeOnCrossClick()}closeOnCrossClick(){(this.shadowRoot.querySelectorAll(".shapla-modal-close, .button--cancel")||[]).forEach((e=>{e.addEventListener("click",(()=>this.triggerCloseEvent()))}))}closeOnBackdropClick(){const e=this.shadowRoot.querySelector(".shapla-modal-background");this.hasAttribute("disabled-backdrop-click")||"confirm"!==this.getAttribute("type")&&e.addEventListener("click",(()=>this.triggerCloseEvent()))}closeOnEscape(){document.addEventListener("keydown",(e=>{27===(e||window.event).keyCode&&this.hasAttribute("open")&&this.triggerCloseEvent()}))}triggerCloseEvent(){this.triggerCustomEvent("close")}getWrapperTemplate(){return[this.el("div",{class:"shapla-modal"},[this.el("div",{class:"shapla-modal-background"}),this.el("shapla-cross",{class:"shapla-modal-close is-fixed",size:"large"}),this.el("div",{class:"shapla-modal-content"},[this.el("slot")])])]}getCartTemplate(){return[this.el("header",{class:"shapla-modal-card__header"},[this.el("div",{class:"shapla-modal-card__title"},[this.el("slot",{name:"heading"})]),this.el("shapla-cross",{class:"shapla-modal-close",size:"medium"})]),this.el("section",{class:"shapla-modal-card__body"},[this.el("slot")]),this.el("footer",{class:"shapla-modal-card__footer is-pulled-right"},[this.el("slot",{name:"footer"})])]}getConfirmTemplate(){return[this.el("div",{class:"shapla-modal-confirm__content"},[this.el("div",{class:"shapla-modal-confirm__icon"},[this.el("div",{class:"shapla-modal-confirm__icon-content"},["!"])]),this.el("h3",{class:"shapla-modal-confirm__title"}),this.el("div",{class:"shapla-modal-confirm__message"})]),this.el("div",{class:"shapla-modal-confirm__actions"},[this.el("slot",{name:"actions"},[this.el("button",{class:"shapla-button button--cancel"}),this.el("button",{class:"shapla-button is-primary button--confirm"})])])]}static getStyle(){return".shapla-modal,.shapla-modal-background{bottom:0;left:0;position:absolute;right:0;top:0}\n    .shapla-modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;\n    position:fixed;z-index:var(--modal-z-index,100000)}\n    .shapla-modal.is-active{display:flex}\n    .shapla-modal-background{background-color:var(--modal-backdrop-color,rgba(0,0,0,.5))}\n    .shapla-modal-background.is-light{--modal-backdrop-color:var(--modal-backdrop-color-light,hsla(0,0%,100%,.5))}\n    .shapla-modal .shapla-delete-icon.is-fixed,.shapla-modal .shapla-modal-close.is-fixed{\n    position:fixed;right:var(--modal-close-right,1.25rem);top:var(--modal-close-top,1.25rem)}\n    .shapla-modal-content{margin:0 var(--modal-content-margin,20px);\n    max-height:calc(100vh - var(--modal-content-spacing, 160px));overflow:auto;position:relative;\n    width:var(--modal-content-width,calc(100% - var(--modal-content-margin, 20px)*2))}\n    .shapla-modal-content.is-small{--modal-content-width:var(--modal-content-width-small,320px)}\n    .shapla-modal-content.is-full{height:calc(100vh - var(--modal-content-margin, 20px)*2);\n    width:calc(100vw - var(--modal-content-margin, 20px)*2)}\n    @media print,screen and (min-width:768px){\n    .shapla-modal-content{--modal-content-spacing:40px;margin:0 auto}\n    .shapla-modal-content:not(.is-small):not(.is-full):not(.is-large){\n    --modal-content-width:var(--modal-content-width-medium,640px)}}\n    @media screen and (min-width:1024px){\n    .shapla-modal-content.is-large{--modal-content-width:var(--modal-content-width-large,960px)}}\n    .shapla-modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden}\n    .shapla-modal-card__footer,.shapla-modal-card__header{align-items:center;background-color:#fff;display:flex;\n    flex-shrink:0;justify-content:flex-start;padding:1rem;position:relative}\n    .shapla-modal-card__footer>*+*,.shapla-modal-card__header>*+*{margin-left:.5rem}\n    .shapla-modal-card__header{border-bottom:1px solid rgba(0,0,0,.12);border-top-left-radius:4px;\n    border-top-right-radius:4px}\n    .shapla-modal-card__title{flex-grow:1;flex-shrink:0;font-size:1.5rem;font-weight:400;line-height:1;margin:0}\n    .shapla-modal-card__footer{border-bottom-left-radius:4px;border-bottom-right-radius:4px;\n    border-top:1px solid rgba(0,0,0,.12)}\n    .shapla-modal-card__footer.is-pulled-right{justify-content:flex-end}\n    .shapla-modal-card__footer.no-content{border-top:none;padding:2px}\n    .shapla-modal-card__body{background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:1rem}\n    .shapla-modal-box,.shapla-modal-confirm{background-color:#fff;border-radius:4px;\n    box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2);padding:1rem}\n    .shapla-modal-confirm__content{padding:1rem;text-align:center}\n    .shapla-modal-confirm__icon{border:.25em solid var(--shapla-primary,#0d6efd);border-radius:50%;\n    color:var(--shapla-primary,#0d6efd);cursor:default;display:flex;height:5em;justify-content:center;\n    margin:1.25em auto 1.875em;-webkit-user-select:none;user-select:none;width:5em}\n    .shapla-modal-confirm__icon.is-success{border-color:var(--shapla-success,#198754);color:var(--shapla-success,#198754)}\n    .shapla-modal-confirm__icon.is-error{border-color:var(--shapla-error,#dc3545);color:var(--shapla-error,#dc3545)}\n    .shapla-modal-confirm__icon-content{align-items:center;display:flex;font-size:3.75em}\n    .shapla-modal-confirm__title{font-size:1.875em;margin:0 0 .4em;text-align:center}\n    .shapla-modal-confirm__actions{display:flex;justify-content:center;padding:1rem}\n    .shapla-modal-confirm__actions>*+*{margin-left:.5rem}"}}customElements.define("shapla-dialog",s);const n=(e,t,a)=>{t.length>2&&a.length&&e.removeAttribute("disabled")},l=document.querySelectorAll("[href*='post-new.php?post_type=carousels']");if(l){const t={title:"",type:""},a=(0,e.a)("button",{class:"shapla-button is-primary",disabled:""},["Next"]),o=(0,e.a)("button",{class:"shapla-button"},["Cancel"]),s=(0,e.a)("shapla-dialog",{type:"card","content-size":"large",heading:"Add New Carousel"},[(0,e.a)("div",{slot:"footer",class:"cs-flex cs-space-x-1"},[o,a])]);s.addEventListener("close",(()=>{s.removeAttribute("open")})),o.addEventListener("click",(()=>{s.removeAttribute("open")})),document.querySelector("body")?.append(s);const r=(0,e.a)("div",{class:"shapla-columns"},[(0,e.a)("div",{class:"shapla-column is-12-tablet"},[(0,e.a)("input",{type:"text",name:"slider_title",size:"30",value:"",id:"title",spellcheck:"true",autocomplete:"Off",placeholder:"Add Title",class:"widefat cs-py-2"})])]);s.append(r);const i=(0,e.a)("div",{class:"shapla-columns is-multiline"});s.append(i);let c=[];window.CarouselSliderL10n.sliderTypes.forEach((t=>{c.push((t=>{let a=(0,e.a)("span",{class:"option-slider-type__icon"});a.innerHTML=t.icon;let o={type:"radio",name:"slider_type",id:`_slide_type__${t.slug}`,class:"screen-reader-text",value:t.slug};return t.enabled||(o.disabled=""),(0,e.a)("div",{class:"shapla-column is-6-tablet is-4-desktop is-3-fullhd"},[(0,e.a)("input",o),(0,e.a)("label",{class:"option-slider-type",for:`_slide_type__${t.slug}`},[(0,e.a)("span",{class:"option-slider-type__content"},[a,(0,e.a)("span",{class:"option-slider-type__label"},[t.label]),t.pro?(0,e.a)("span",{class:"option-slider-type__pro"},["Pro"]):""])])])})(t))})),i.append(...c),l.forEach((e=>{e.addEventListener("click",(e=>{e.preventDefault(),s.setAttribute("open","")}))})),s.querySelectorAll('input[name="slider_title"]').forEach((e=>{e.addEventListener("input",(e=>{t.title=e.target.value,n(a,t.title,t.type)}))})),s.querySelectorAll('input[name="slider_type"]').forEach((e=>{e.addEventListener("change",(e=>{t.type=e.target.value,n(a,t.title,t.type)}))})),a.addEventListener("click",(e=>{a.hasAttribute("disabled")||(a.classList.add("is-loading"),fetch(window.CarouselSliderL10n.restRoot+"/carousels",{method:"POST",headers:{"Content-Type":"application/json","X-WP-Nonce":window.CarouselSliderL10n.restNonce},body:JSON.stringify(t)}).then((e=>e.json())).then((e=>{if(e.data.edit_link){let t=document.createElement("a");t.href=e.data.edit_link,t.click()}})).catch((e=>{console.error("Error:",e)})).finally((()=>{a.classList.remove("is-loading")})))}))}})()})();assets/css/admin-divi-modules.css000064400000000247151727276570013065 0ustar00.carousel-slider-iframe{width:100%}.carousel-slider-iframe-container{position:relative}.carousel-slider-iframe-overlay{bottom:0;left:0;position:absolute;right:0;top:0}assets/css/admin-add-new-carousel.css000064400000025647151727276570013631 0ustar00.option-slider-type{border:2px solid rgba(0,0,0,.12);display:inline-flex;height:100%;position:relative;width:100%}input:checked~.option-slider-type{border-color:#2271b1}input:disabled~.option-slider-type{cursor:not-allowed;opacity:.38}.option-slider-type__icon{align-items:center;color:rgba(0,0,0,.38);display:inline-flex;justify-content:center}.option-slider-type__icon,.option-slider-type__icon>*{font-size:32px;height:32px;width:32px}.option-slider-type__icon svg{fill:currentColor}.option-slider-type__content{align-items:center;background-color:#e8ecef;display:flex;flex-direction:column;margin:.25rem;padding:.25rem;width:100%}.option-slider-type__pro{background-color:#cbd6df;line-height:1rem;padding:.125rem .25rem;position:absolute;right:.5rem;top:.5rem}.cs-flex{display:flex}.cs-inline-flex{display:inline-flex}.cs-flex-wrap{flex-wrap:wrap}.cs-items-center{align-items:center}.cs-justify-center{justify-content:center}.cs-justify-between{justify-content:space-between}.cs-mt-4{margin-top:1rem}.cs-mb-4,.cs-my-4{margin-bottom:1rem}.cs-my-4{margin-top:1rem}.cs-p-2{padding:.5rem!important}.cs-py-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.cs-space-x-1>*+*{margin-left:.25rem!important}.cs-bg-gray-200{background-color:#e5e7eb}.cs-text-red-600{color:#dc2626}.cs-w-8{width:2rem}.cs-h-8{height:2rem}#menu-posts-carousels a[href="edit.php?post_type=carousels&page=go_carousel_slider_pro"],#menu-posts-carousels a[href="edit.php?post_type=carousels&page=go_carousel_slider_pro"]:hover,.carousel-slider-plugins-gopro{color:#93003c;font-weight:700}.carousel-slider-plugins-gopro{text-shadow:1px 1px 1px #eee}@keyframes shaplaButtonSpinAround{0%{transform:rotate(0deg)}to{transform:rotate(359deg)}}.shapla-button{--shapla-button-color:#f1f1f1;--shapla-button-color-dark:#ddd;--shapla-button-on-color:var(--shapla-text-primary,rgba(0,0,0,.87));align-items:center;-webkit-appearance:none;appearance:none;background-color:var(--shapla-button-color);border:1px solid transparent;border-radius:4px;box-shadow:none;color:var(--shapla-button-on-color);cursor:pointer;display:inline-flex;font-size:1rem;height:2.5em;justify-content:center;line-height:1.5;padding:calc(.5em - 1px) 1em;position:relative;text-align:center;-webkit-text-decoration:none;text-decoration:none;-webkit-user-select:none;user-select:none;vertical-align:top;white-space:nowrap}.shapla-button:active,.shapla-button:focus{outline:none}.shapla-button:focus{box-shadow:0 0 0 1px transparent,0 0 0 3px var(--shapla-button-color-alpha,rgba(0,0,0,.25))}.shapla-button strong{color:currentColor}.shapla-button svg{fill:currentColor}.shapla-button[disabled],fieldset[disabled] .shapla-button{cursor:not-allowed;opacity:.5}.shapla-button.is-fullwidth{display:flex;width:100%}.shapla-button.is-small{border-radius:2px;font-size:.75rem}.shapla-button.is-normal{font-size:1rem}.shapla-button.is-medium{font-size:1.25rem}.shapla-button.is-large{font-size:1.5rem}.shapla-button.is-rounded{border-radius:290486px;padding-left:1.25em;padding-right:1.25em}.shapla-button.is-fab{border-radius:50%;height:2.5em;min-width:2.5em;width:2.5em}.shapla-button.is-loading{color:transparent!important;pointer-events:none}.shapla-button.is-loading.is-outline:after{border-color:var(--shapla-button-color)}.shapla-button.is-loading:after{animation:shaplaButtonSpinAround .5s linear infinite;border:2px solid var(--shapla-button-on-color,#dbdbdb);border-radius:9999px;border-right-color:transparent!important;border-top-color:transparent!important;content:"";display:block;height:1em;left:calc(50% - .5em);position:absolute!important;top:calc(50% - .5em);width:1em}.shapla-button.is-primary{--shapla-button-color:var(--shapla-primary,#0d6efd);--shapla-button-color-dark:var(--shapla-primary-variant,#0261ed);--shapla-button-color-alpha:var(--shapla-primary-alpha,rgba(13,110,253,.25));--shapla-button-on-color:var(--shapla-on-primary,#fff)}.shapla-button.is-secondary{--shapla-button-color:var(--shapla-secondary,#757575);--shapla-button-color-dark:var(--shapla-secondary-variant,#686868);--shapla-button-color-alpha:var(--shapla-secondary-alpha,hsla(0,0%,46%,.25));--shapla-button-on-color:var(--shapla-on-secondary,#fff)}.shapla-button.is-success{--shapla-button-color:var(--shapla-success,#198754);--shapla-button-color-dark:var(--shapla-success-variant,#157147);--shapla-button-color-alpha:var(--shapla-success-alpha,rgba(25,135,84,.25));--shapla-button-on-color:var(--shapla-on-success,#fff)}.shapla-button.is-warning{--shapla-button-color:var(--shapla-warning,#ffc107);--shapla-button-color-dark:var(--shapla-warning-variant,#edb100);--shapla-button-color-alpha:var(--shapla-warning-alpha,rgba(255,193,7,.25));--shapla-button-on-color:var(--shapla-on-warning,#000)}.shapla-button.is-error{--shapla-button-color:var(--shapla-error,#dc3545);--shapla-button-color-dark:var(--shapla-error-variant,#d32535);--shapla-button-color-alpha:var(--shapla-error-alpha,rgba(220,53,69,.25));--shapla-button-on-color:var(--shapla-on-error,#fff)}.shapla-button:not(:disabled):active,.shapla-button:not(:disabled):hover{background-color:var(--shapla-button-color-dark);border-color:transparent;color:var(--shapla-button-on-color)}.shapla-button.is-outline{background-color:transparent;border-color:var(--shapla-button-color);color:var(--shapla-button-color)}.shapla-button.is-outline:not(:disabled):hover{background-color:var(--shapla-button-color);border-color:var(--shapla-button-color);color:var(--shapla-button-on-color)}.shapla-button.is-outline:not(.is-primary):not(.is-secondary):not(.is-success):not(.is-error):not(.is-warning){background-color:transparent;border-color:var(--shapla-button-color);color:var(--shapla-button-on-color)}.shapla-button.is-outline:not(.is-primary):not(.is-secondary):not(.is-success):not(.is-error):not(.is-warning):not(:disabled):hover{background-color:transparent;border-color:var(--shapla-button-color-dark);color:var(--shapla-button-on-color)}.shapla-button.has-shadow{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.shapla-button.has-shadow:not(:disabled):hover{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.shapla-button.has-shadow:not(:disabled):focus{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2)}.shapla-column{display:block;flex:1 1 0}.shapla-column[class*=is-]{flex:none}.shapla-columns.is-mobile>.shapla-column.is-1{width:8.3333333333%}.shapla-columns.is-mobile>.shapla-column.is-2{width:16.6666666667%}.shapla-columns.is-mobile>.shapla-column.is-3{width:25%}.shapla-columns.is-mobile>.shapla-column.is-4{width:33.3333333333%}.shapla-columns.is-mobile>.shapla-column.is-5{width:41.6666666667%}.shapla-columns.is-mobile>.shapla-column.is-6{width:50%}.shapla-columns.is-mobile>.shapla-column.is-7{width:58.3333333333%}.shapla-columns.is-mobile>.shapla-column.is-8{width:66.6666666667%}.shapla-columns.is-mobile>.shapla-column.is-9{width:75%}.shapla-columns.is-mobile>.shapla-column.is-10{width:83.3333333333%}.shapla-columns.is-mobile>.shapla-column.is-11{width:91.6666666667%}.shapla-columns.is-mobile>.shapla-column.is-12{width:100%}@media screen and (max-width:767px){.shapla-column.is-1-mobile{width:8.3333333333%}.shapla-column.is-2-mobile{width:16.6666666667%}.shapla-column.is-3-mobile{width:25%}.shapla-column.is-4-mobile{width:33.3333333333%}.shapla-column.is-5-mobile{width:41.6666666667%}.shapla-column.is-6-mobile{width:50%}.shapla-column.is-7-mobile{width:58.3333333333%}.shapla-column.is-8-mobile{width:66.6666666667%}.shapla-column.is-9-mobile{width:75%}.shapla-column.is-10-mobile{width:83.3333333333%}.shapla-column.is-11-mobile{width:91.6666666667%}.shapla-column.is-12-mobile{width:100%}}@media print,screen and (min-width:768px){.shapla-column.is-1,.shapla-column.is-1-tablet{width:8.3333333333%}.shapla-column.is-2,.shapla-column.is-2-tablet{width:16.6666666667%}.shapla-column.is-3,.shapla-column.is-3-tablet{width:25%}.shapla-column.is-4,.shapla-column.is-4-tablet{width:33.3333333333%}.shapla-column.is-5,.shapla-column.is-5-tablet{width:41.6666666667%}.shapla-column.is-6,.shapla-column.is-6-tablet{width:50%}.shapla-column.is-7,.shapla-column.is-7-tablet{width:58.3333333333%}.shapla-column.is-8,.shapla-column.is-8-tablet{width:66.6666666667%}.shapla-column.is-9,.shapla-column.is-9-tablet{width:75%}.shapla-column.is-10,.shapla-column.is-10-tablet{width:83.3333333333%}.shapla-column.is-11,.shapla-column.is-11-tablet{width:91.6666666667%}.shapla-column.is-12,.shapla-column.is-12-tablet{width:100%}}@media screen and (min-width:1024px){.shapla-column.is-1-desktop{width:8.3333333333%}.shapla-column.is-2-desktop{width:16.6666666667%}.shapla-column.is-3-desktop{width:25%}.shapla-column.is-4-desktop{width:33.3333333333%}.shapla-column.is-5-desktop{width:41.6666666667%}.shapla-column.is-6-desktop{width:50%}.shapla-column.is-7-desktop{width:58.3333333333%}.shapla-column.is-8-desktop{width:66.6666666667%}.shapla-column.is-9-desktop{width:75%}.shapla-column.is-10-desktop{width:83.3333333333%}.shapla-column.is-11-desktop{width:91.6666666667%}.shapla-column.is-12-desktop{width:100%}}@media screen and (min-width:1280px){.shapla-column.is-1-widescreen{width:8.3333333333%}.shapla-column.is-2-widescreen{width:16.6666666667%}.shapla-column.is-3-widescreen{width:25%}.shapla-column.is-4-widescreen{width:33.3333333333%}.shapla-column.is-5-widescreen{width:41.6666666667%}.shapla-column.is-6-widescreen{width:50%}.shapla-column.is-7-widescreen{width:58.3333333333%}.shapla-column.is-8-widescreen{width:66.6666666667%}.shapla-column.is-9-widescreen{width:75%}.shapla-column.is-10-widescreen{width:83.3333333333%}.shapla-column.is-11-widescreen{width:91.6666666667%}.shapla-column.is-12-widescreen{width:100%}}@media screen and (min-width:1400px){.shapla-column.is-1-fullhd{width:8.3333333333%}.shapla-column.is-2-fullhd{width:16.6666666667%}.shapla-column.is-3-fullhd{width:25%}.shapla-column.is-4-fullhd{width:33.3333333333%}.shapla-column.is-5-fullhd{width:41.6666666667%}.shapla-column.is-6-fullhd{width:50%}.shapla-column.is-7-fullhd{width:58.3333333333%}.shapla-column.is-8-fullhd{width:66.6666666667%}.shapla-column.is-9-fullhd{width:75%}.shapla-column.is-10-fullhd{width:83.3333333333%}.shapla-column.is-11-fullhd{width:91.6666666667%}.shapla-column.is-12-fullhd{width:100%}}.shapla-columns.is-centered{justify-content:center}.shapla-columns.is-mobile{display:flex}.shapla-columns.is-multiline{flex-wrap:wrap}.shapla-columns.is-vcentered{align-items:center}@media print,screen and (min-width:768px){.shapla-columns:not(.is-desktop){display:flex}}@media screen and (min-width:1024px){.shapla-columns.is-desktop{display:flex}}.shapla-columns{--shapla-column-gap:0.75rem;margin:calc(var(--shapla-column-gap, .75rem)*-1)}.shapla-columns:not(:last-child){margin-bottom:calc(1.5rem - var(--shapla-column-gap, .75rem))}.shapla-columns.is-gapless{--shapla-column-gap:0}.shapla-columns .shapla-column{padding:var(--shapla-column-gap,.75rem)}.shapla-modal,.shapla-modal *,.shapla-modal :after,.shapla-modal :before,shapla-dialog,shapla-dialog *,shapla-dialog :after,shapla-dialog :before{box-sizing:border-box}assets/css/admin-gutenberg-block.css000064400000000765151727276570013543 0ustar00.carousel-slider-iframe{width:100%!important}.carousel-slider-iframe-container{position:relative}.carousel-slider-iframe-overlay{bottom:0;left:0;position:absolute;right:0;top:0}.carousel-slider-editor-controls{padding-right:1rem;width:100%}.carousel-slider-editor-controls__logo{float:left;margin-bottom:10px;margin-right:15px;max-height:50px;max-width:50px!important}.carousel-slider-editor-controls__input{padding-bottom:1rem}.carousel-slider-inspector-controls{padding-left:1rem;padding-right:1rem}assets/css/frontend-v2.css000064400000076231151727276570011550 0ustar00@font-face{font-family:swiper-icons;font-style:normal;font-weight:400;src:url("data:application/font-woff;charset=utf-8;base64, d09GRgABAAAAAAZgABAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAGRAAAABoAAAAci6qHkUdERUYAAAWgAAAAIwAAACQAYABXR1BPUwAABhQAAAAuAAAANuAY7+xHU1VCAAAFxAAAAFAAAABm2fPczU9TLzIAAAHcAAAASgAAAGBP9V5RY21hcAAAAkQAAACIAAABYt6F0cBjdnQgAAACzAAAAAQAAAAEABEBRGdhc3AAAAWYAAAACAAAAAj//wADZ2x5ZgAAAywAAADMAAAD2MHtryVoZWFkAAABbAAAADAAAAA2E2+eoWhoZWEAAAGcAAAAHwAAACQC9gDzaG10eAAAAigAAAAZAAAArgJkABFsb2NhAAAC0AAAAFoAAABaFQAUGG1heHAAAAG8AAAAHwAAACAAcABAbmFtZQAAA/gAAAE5AAACXvFdBwlwb3N0AAAFNAAAAGIAAACE5s74hXjaY2BkYGAAYpf5Hu/j+W2+MnAzMYDAzaX6QjD6/4//Bxj5GA8AuRwMYGkAPywL13jaY2BkYGA88P8Agx4j+/8fQDYfA1AEBWgDAIB2BOoAeNpjYGRgYNBh4GdgYgABEMnIABJzYNADCQAACWgAsQB42mNgYfzCOIGBlYGB0YcxjYGBwR1Kf2WQZGhhYGBiYGVmgAFGBiQQkOaawtDAoMBQxXjg/wEGPcYDDA4wNUA2CCgwsAAAO4EL6gAAeNpj2M0gyAACqxgGNWBkZ2D4/wMA+xkDdgAAAHjaY2BgYGaAYBkGRgYQiAHyGMF8FgYHIM3DwMHABGQrMOgyWDLEM1T9/w8UBfEMgLzE////P/5//f/V/xv+r4eaAAeMbAxwIUYmIMHEgKYAYjUcsDAwsLKxc3BycfPw8jEQA/gZBASFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTQZBgMAAMR+E+gAEQFEAAAAKgAqACoANAA+AEgAUgBcAGYAcAB6AIQAjgCYAKIArAC2AMAAygDUAN4A6ADyAPwBBgEQARoBJAEuATgBQgFMAVYBYAFqAXQBfgGIAZIBnAGmAbIBzgHsAAB42u2NMQ6CUAyGW568x9AneYYgm4MJbhKFaExIOAVX8ApewSt4Bic4AfeAid3VOBixDxfPYEza5O+Xfi04YADggiUIULCuEJK8VhO4bSvpdnktHI5QCYtdi2sl8ZnXaHlqUrNKzdKcT8cjlq+rwZSvIVczNiezsfnP/uznmfPFBNODM2K7MTQ45YEAZqGP81AmGGcF3iPqOop0r1SPTaTbVkfUe4HXj97wYE+yNwWYxwWu4v1ugWHgo3S1XdZEVqWM7ET0cfnLGxWfkgR42o2PvWrDMBSFj/IHLaF0zKjRgdiVMwScNRAoWUoH78Y2icB/yIY09An6AH2Bdu/UB+yxopYshQiEvnvu0dURgDt8QeC8PDw7Fpji3fEA4z/PEJ6YOB5hKh4dj3EvXhxPqH/SKUY3rJ7srZ4FZnh1PMAtPhwP6fl2PMJMPDgeQ4rY8YT6Gzao0eAEA409DuggmTnFnOcSCiEiLMgxCiTI6Cq5DZUd3Qmp10vO0LaLTd2cjN4fOumlc7lUYbSQcZFkutRG7g6JKZKy0RmdLY680CDnEJ+UMkpFFe1RN7nxdVpXrC4aTtnaurOnYercZg2YVmLN/d/gczfEimrE/fs/bOuq29Zmn8tloORaXgZgGa78yO9/cnXm2BpaGvq25Dv9S4E9+5SIc9PqupJKhYFSSl47+Qcr1mYNAAAAeNptw0cKwkAAAMDZJA8Q7OUJvkLsPfZ6zFVERPy8qHh2YER+3i/BP83vIBLLySsoKimrqKqpa2hp6+jq6RsYGhmbmJqZSy0sraxtbO3sHRydnEMU4uR6yx7JJXveP7WrDycAAAAAAAH//wACeNpjYGRgYOABYhkgZgJCZgZNBkYGLQZtIJsFLMYAAAw3ALgAeNolizEKgDAQBCchRbC2sFER0YD6qVQiBCv/H9ezGI6Z5XBAw8CBK/m5iQQVauVbXLnOrMZv2oLdKFa8Pjuru2hJzGabmOSLzNMzvutpB3N42mNgZGBg4GKQYzBhYMxJLMlj4GBgAYow/P/PAJJhLM6sSoWKfWCAAwDAjgbRAAB42mNgYGBkAIIbCZo5IPrmUn0hGA0AO8EFTQAA") format("woff")}:root{--swiper-theme-color:#007aff}:host{display:block;margin-left:auto;margin-right:auto;position:relative;z-index:1}.swiper{display:block;list-style:none;margin-left:auto;margin-right:auto;overflow:hidden;padding:0;position:relative;z-index:1}.swiper-vertical>.swiper-wrapper{flex-direction:column}.swiper-wrapper{box-sizing:content-box;display:flex;height:100%;position:relative;transition-property:transform;transition-timing-function:var(--swiper-wrapper-transition-timing-function,initial);width:100%;z-index:1}.swiper-android .swiper-slide,.swiper-ios .swiper-slide,.swiper-wrapper{transform:translateZ(0)}.swiper-horizontal{touch-action:pan-y}.swiper-vertical{touch-action:pan-x}.swiper-slide{display:block;flex-shrink:0;height:100%;position:relative;transition-property:transform;width:100%}.swiper-slide-invisible-blank{visibility:hidden}.swiper-autoheight,.swiper-autoheight .swiper-slide{height:auto}.swiper-autoheight .swiper-wrapper{align-items:flex-start;transition-property:transform,height}.swiper-backface-hidden .swiper-slide{backface-visibility:hidden;transform:translateZ(0)}.swiper-3d.swiper-css-mode .swiper-wrapper{perspective:1200px}.swiper-3d .swiper-wrapper{transform-style:preserve-3d}.swiper-3d{perspective:1200px}.swiper-3d .swiper-cube-shadow,.swiper-3d .swiper-slide{transform-style:preserve-3d}.swiper-css-mode>.swiper-wrapper{overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.swiper-css-mode>.swiper-wrapper::-webkit-scrollbar{display:none}.swiper-css-mode>.swiper-wrapper>.swiper-slide{scroll-snap-align:start start}.swiper-css-mode.swiper-horizontal>.swiper-wrapper{scroll-snap-type:x mandatory}.swiper-css-mode.swiper-vertical>.swiper-wrapper{scroll-snap-type:y mandatory}.swiper-css-mode.swiper-free-mode>.swiper-wrapper{scroll-snap-type:none}.swiper-css-mode.swiper-free-mode>.swiper-wrapper>.swiper-slide{scroll-snap-align:none}.swiper-css-mode.swiper-centered>.swiper-wrapper:before{content:"";flex-shrink:0;order:9999}.swiper-css-mode.swiper-centered>.swiper-wrapper>.swiper-slide{scroll-snap-align:center center;scroll-snap-stop:always}.swiper-css-mode.swiper-centered.swiper-horizontal>.swiper-wrapper>.swiper-slide:first-child{margin-inline-start:var(--swiper-centered-offset-before)}.swiper-css-mode.swiper-centered.swiper-horizontal>.swiper-wrapper:before{height:100%;min-height:1px;width:var(--swiper-centered-offset-after)}.swiper-css-mode.swiper-centered.swiper-vertical>.swiper-wrapper>.swiper-slide:first-child{margin-block-start:var(--swiper-centered-offset-before)}.swiper-css-mode.swiper-centered.swiper-vertical>.swiper-wrapper:before{height:var(--swiper-centered-offset-after);min-width:1px;width:100%}.swiper-3d .swiper-slide-shadow,.swiper-3d .swiper-slide-shadow-bottom,.swiper-3d .swiper-slide-shadow-left,.swiper-3d .swiper-slide-shadow-right,.swiper-3d .swiper-slide-shadow-top{height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%;z-index:10}.swiper-3d .swiper-slide-shadow{background:rgba(0,0,0,.15)}.swiper-3d .swiper-slide-shadow-left{background-image:linear-gradient(270deg,rgba(0,0,0,.5),transparent)}.swiper-3d .swiper-slide-shadow-right{background-image:linear-gradient(90deg,rgba(0,0,0,.5),transparent)}.swiper-3d .swiper-slide-shadow-top{background-image:linear-gradient(0deg,rgba(0,0,0,.5),transparent)}.swiper-3d .swiper-slide-shadow-bottom{background-image:linear-gradient(180deg,rgba(0,0,0,.5),transparent)}.swiper-lazy-preloader{border:4px solid var(--swiper-preloader-color,var(--swiper-theme-color));border-radius:50%;border-top:4px solid transparent;box-sizing:border-box;height:42px;left:50%;margin-left:-21px;margin-top:-21px;position:absolute;top:50%;transform-origin:50%;width:42px;z-index:10}.swiper-watch-progress .swiper-slide-visible .swiper-lazy-preloader,.swiper:not(.swiper-watch-progress) .swiper-lazy-preloader{animation:swiper-preloader-spin 1s linear infinite}.swiper-lazy-preloader-white{--swiper-preloader-color:#fff}.swiper-lazy-preloader-black{--swiper-preloader-color:#000}@keyframes swiper-preloader-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}:root{--swiper-navigation-size:44px}.swiper-button-next,.swiper-button-prev{align-items:center;color:var(--swiper-navigation-color,var(--swiper-theme-color));cursor:pointer;display:flex;height:var(--swiper-navigation-size);justify-content:center;margin-top:calc(0px - var(--swiper-navigation-size)/2);position:absolute;top:var(--swiper-navigation-top-offset,50%);width:calc(var(--swiper-navigation-size)/44*27);z-index:10}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{cursor:auto;opacity:.35;pointer-events:none}.swiper-button-next.swiper-button-hidden,.swiper-button-prev.swiper-button-hidden{cursor:auto;opacity:0;pointer-events:none}.swiper-navigation-disabled .swiper-button-next,.swiper-navigation-disabled .swiper-button-prev{display:none!important}.swiper-button-next svg,.swiper-button-prev svg{height:100%;object-fit:contain;transform-origin:center;width:100%}.swiper-rtl .swiper-button-next svg,.swiper-rtl .swiper-button-prev svg{transform:rotate(180deg)}.swiper-button-prev,.swiper-rtl .swiper-button-next{left:var(--swiper-navigation-sides-offset,10px);right:auto}.swiper-button-lock{display:none}.swiper-button-next:after,.swiper-button-prev:after{font-family:swiper-icons;font-size:var(--swiper-navigation-size);font-variant:normal;letter-spacing:0;line-height:1;text-transform:none!important}.swiper-button-prev:after,.swiper-rtl .swiper-button-next:after{content:"prev"}.swiper-button-next,.swiper-rtl .swiper-button-prev{left:auto;right:var(--swiper-navigation-sides-offset,10px)}.swiper-button-next:after,.swiper-rtl .swiper-button-prev:after{content:"next"}.swiper-pagination{position:absolute;text-align:center;transform:translateZ(0);transition:opacity .3s;z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-pagination-disabled>.swiper-pagination,.swiper-pagination.swiper-pagination-disabled{display:none!important}.swiper-horizontal>.swiper-pagination-bullets,.swiper-pagination-bullets.swiper-pagination-horizontal,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:var(--swiper-pagination-bottom,8px);left:0;top:var(--swiper-pagination-top,auto);width:100%}.swiper-pagination-bullets-dynamic{font-size:0;overflow:hidden}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{position:relative;transform:scale(.33)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active,.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main{transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev{transform:scale(.33)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next{transform:scale(.33)}.swiper-pagination-bullet{background:var(--swiper-pagination-bullet-inactive-color,#000);border-radius:var(--swiper-pagination-bullet-border-radius,50%);display:inline-block;height:var(--swiper-pagination-bullet-height,var(--swiper-pagination-bullet-size,8px));opacity:var(--swiper-pagination-bullet-inactive-opacity,.2);width:var(--swiper-pagination-bullet-width,var(--swiper-pagination-bullet-size,8px))}button.swiper-pagination-bullet{-webkit-appearance:none;appearance:none;border:none;box-shadow:none;margin:0;padding:0}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-bullet:only-child{display:none!important}.swiper-pagination-bullet-active{background:var(--swiper-pagination-color,var(--swiper-theme-color));opacity:var(--swiper-pagination-bullet-opacity,1)}.swiper-pagination-vertical.swiper-pagination-bullets,.swiper-vertical>.swiper-pagination-bullets{left:var(--swiper-pagination-left,auto);right:var(--swiper-pagination-right,8px);top:50%;transform:translate3d(0,-50%,0)}.swiper-pagination-vertical.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{display:block;margin:var(--swiper-pagination-bullet-vertical-gap,6px) 0}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{top:50%;transform:translateY(-50%);width:8px}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{display:inline-block;transition:transform .2s,top .2s}.swiper-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 var(--swiper-pagination-bullet-horizontal-gap,4px)}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{left:50%;transform:translateX(-50%);white-space:nowrap}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:transform .2s,left .2s}.swiper-horizontal.swiper-rtl>.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:transform .2s,right .2s}.swiper-pagination-fraction{color:var(--swiper-pagination-fraction-color,inherit)}.swiper-pagination-progressbar{background:var(--swiper-pagination-progressbar-bg-color,rgba(0,0,0,.25));position:absolute}.swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:var(--swiper-pagination-color,var(--swiper-theme-color));height:100%;left:0;position:absolute;top:0;transform:scale(0);transform-origin:left top;width:100%}.swiper-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{transform-origin:right top}.swiper-horizontal>.swiper-pagination-progressbar,.swiper-pagination-progressbar.swiper-pagination-horizontal,.swiper-pagination-progressbar.swiper-pagination-vertical.swiper-pagination-progressbar-opposite,.swiper-vertical>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite{height:var(--swiper-pagination-progressbar-size,4px);left:0;top:0;width:100%}.swiper-horizontal>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-horizontal.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-vertical,.swiper-vertical>.swiper-pagination-progressbar{height:100%;left:0;top:0;width:var(--swiper-pagination-progressbar-size,4px)}.swiper-pagination-lock{display:none}.swiper-scrollbar{background:var(--swiper-scrollbar-bg-color,rgba(0,0,0,.1));border-radius:var(--swiper-scrollbar-border-radius,10px);position:relative;touch-action:none}.swiper-scrollbar-disabled>.swiper-scrollbar,.swiper-scrollbar.swiper-scrollbar-disabled{display:none!important}.swiper-horizontal>.swiper-scrollbar,.swiper-scrollbar.swiper-scrollbar-horizontal{bottom:var(--swiper-scrollbar-bottom,4px);height:var(--swiper-scrollbar-size,4px);left:var(--swiper-scrollbar-sides-offset,1%);position:absolute;top:var(--swiper-scrollbar-top,auto);width:calc(100% - var(--swiper-scrollbar-sides-offset, 1%)*2);z-index:50}.swiper-scrollbar.swiper-scrollbar-vertical,.swiper-vertical>.swiper-scrollbar{height:calc(100% - var(--swiper-scrollbar-sides-offset, 1%)*2);left:var(--swiper-scrollbar-left,auto);position:absolute;right:var(--swiper-scrollbar-right,4px);top:var(--swiper-scrollbar-sides-offset,1%);width:var(--swiper-scrollbar-size,4px);z-index:50}.swiper-scrollbar-drag{background:var(--swiper-scrollbar-drag-bg-color,rgba(0,0,0,.5));border-radius:var(--swiper-scrollbar-border-radius,10px);height:100%;left:0;position:relative;top:0;width:100%}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-scrollbar-lock{display:none}.swiper-fade.swiper-free-mode .swiper-slide{transition-timing-function:ease-out}.swiper-fade .swiper-slide{pointer-events:none;transition-property:opacity}.swiper-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-fade .swiper-slide-active,.swiper-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper.swiper-cube{overflow:visible}.swiper-cube .swiper-slide{backface-visibility:hidden;height:100%;pointer-events:none;transform-origin:0 0;visibility:hidden;width:100%;z-index:1}.swiper-cube .swiper-slide .swiper-slide{pointer-events:none}.swiper-cube.swiper-rtl .swiper-slide{transform-origin:100% 0}.swiper-cube .swiper-slide-active,.swiper-cube .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-cube .swiper-slide-active,.swiper-cube .swiper-slide-next,.swiper-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-cube .swiper-cube-shadow{bottom:0;height:100%;left:0;opacity:.6;position:absolute;width:100%;z-index:0}.swiper-cube .swiper-cube-shadow:before{background:#000;bottom:0;content:"";filter:blur(50px);left:0;position:absolute;right:0;top:0}.swiper-cube .swiper-slide-next+.swiper-slide{pointer-events:auto;visibility:visible}.swiper-cube .swiper-slide-shadow-cube.swiper-slide-shadow-bottom,.swiper-cube .swiper-slide-shadow-cube.swiper-slide-shadow-left,.swiper-cube .swiper-slide-shadow-cube.swiper-slide-shadow-right,.swiper-cube .swiper-slide-shadow-cube.swiper-slide-shadow-top{backface-visibility:hidden;z-index:0}.swiper.swiper-flip{overflow:visible}.swiper-flip .swiper-slide{backface-visibility:hidden;pointer-events:none;z-index:1}.swiper-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-flip .swiper-slide-active,.swiper-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-flip .swiper-slide-shadow-flip.swiper-slide-shadow-bottom,.swiper-flip .swiper-slide-shadow-flip.swiper-slide-shadow-left,.swiper-flip .swiper-slide-shadow-flip.swiper-slide-shadow-right,.swiper-flip .swiper-slide-shadow-flip.swiper-slide-shadow-top{backface-visibility:hidden;z-index:0}.swiper.swiper-cards{overflow:visible}.swiper-cards .swiper-slide{backface-visibility:hidden;overflow:hidden;transform-origin:center bottom}.swiper-creative .swiper-slide{backface-visibility:hidden;overflow:hidden;transition-property:transform,opacity,height}.cs-hero-button{-webkit-appearance:none;-webkit-font-smoothing:inherit;border-radius:0;box-sizing:border-box;display:inline-block;font-size:1rem;line-height:1;padding:.75em 1em;text-align:center;transition:all .2s ease-in-out}.cs-hero-button,.cs-hero-button:hover{-webkit-text-decoration:none;text-decoration:none}.cs-hero-button--normal{filter:alpha(opacity=90);opacity:.9}.cs-hero-button--stroke{background:transparent;border:1px solid transparent}.cs-hero-button--medium{font-size:1.2rem;padding:.9em 1.2em}.cs-hero-button--large{font-size:1.5rem;padding:.9em 1.6em}.carousel-slider-hero__cell__background{background-position:50%;background-repeat:no-repeat;background-size:cover;min-height:100%;min-width:100%;transition-duration:10s;transition-property:transform}.carousel-slider-hero__cell__background.carousel-slider-hero-ken-out{transform:scale(1.3)}.carousel-slider .active .carousel-slider-hero__cell__background,.carousel-slider .swiper-slide-active .carousel-slider-hero__cell__background,.carousel-slider .swiper-slide-duplicate-active .carousel-slider-hero__cell__background{animation-duration:20s;animation-timing-function:linear}.carousel-slider .active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-in,.carousel-slider .swiper-slide-active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-in,.carousel-slider .swiper-slide-duplicate-active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-in{animation-name:ken-burns-in;transform:scale(1.3)}.carousel-slider .active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-out,.carousel-slider .swiper-slide-active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-out,.carousel-slider .swiper-slide-duplicate-active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-out{animation-name:ken-burns-out;transform:scale(1)}.carousel-slider-hero__cell{align-items:center;display:flex;height:var(--cell-height,400px);justify-content:center;overflow:hidden;position:relative}.carousel-slider-hero__cell:focus{outline:0}.carousel-slider-hero__cell__inner{background-position:50%;background-repeat:no-repeat;bottom:0;left:0;padding:50px;position:absolute;right:0;top:0}.carousel-slider-hero__cell__inner,.carousel-slider-hero__cell__inner:hover{color:#fff;display:flex}.carousel-slider-hero__cell__background_overlay{bottom:0;left:0;position:absolute;right:0;top:0;z-index:0}.carousel-slider-hero__cell__content{max-width:1140px;position:relative;width:100%;z-index:1}.carousel-slider-hero__cell__content.hidden{display:none}.carousel-slider-hero__cell__heading{color:var(--cs-heading-color,#fff);font-size:var(--cs-heading-font-size,40px);font-weight:700;line-height:1;margin-bottom:var(--cs-heading-gutter,30px)}.carousel-slider-hero__cell__description{color:var(--cs-description-color,#fff);font-size:var(--cs-description-font-size,20px);line-height:1.4;margin-bottom:var(--cs-description-gutter,30px)}.carousel-slider-hero__cell__button__one{margin-right:5px}.carousel-slider-hero__cell__button__two{margin-left:5px}.carousel-slider-hero__cell__button__one,.carousel-slider-hero__cell__button__two{display:inline-flex}.button.cs-hero-button{border-color:var(--cs-button-bg-color,#00d1b2);border-radius:var(--cs-button-border-radius,3px);border-style:solid;border-width:var(--cs-button-border-width,0)}.button.cs-hero-button,.button.cs-hero-button:hover{background-color:var(--cs-button-bg-color,#00d1b2);color:var(--cs-button-color,#fff)}.button.cs-hero-button.cs-hero-button-stroke,.button.cs-hero-button:hover{border-color:var(--cs-button-bg-color,#00d1b2)}.button.cs-hero-button.cs-hero-button-stroke{background-color:transparent;color:var(--cs-button-bg-color,#00d1b2)}.button.cs-hero-button.cs-hero-button-stroke:hover{background-color:var(--cs-button-bg-color,#00d1b2);color:var(--cs-button-color,#fff)}.carousel-slider-hero__cell__inner.carousel-slider--v-position-top{align-items:flex-start}.carousel-slider-hero__cell__inner.carousel-slider--v-position-bottom{align-items:flex-end}.carousel-slider-hero__cell__inner.carousel-slider--v-position-middle{align-items:center}.carousel-slider-hero__cell__inner.carousel-slider--h-position-left{justify-content:flex-start}.carousel-slider-hero__cell__inner.carousel-slider--h-position-right{justify-content:flex-end}.carousel-slider-hero__cell__inner.carousel-slider--h-position-center{justify-content:center}.carousel-slider-hero__cell__inner.carousel-slider--text-left{text-align:left}.carousel-slider-hero__cell__inner.carousel-slider--text-right{text-align:right}.carousel-slider-hero__cell__inner.carousel-slider--text-center{text-align:center}@media(max-width:767px){.carousel-slider-hero__cell__inner{padding:30px}.carousel-slider-hero__cell__heading{font-size:24px;line-height:1;margin-bottom:15px}.carousel-slider-hero__cell__description{font-size:14px;line-height:1.4;margin-bottom:15px}}.carousel-slider .carousel-slider__item{position:relative}.carousel-slider .carousel-slider__item img{display:block;height:auto;margin-left:auto;margin-right:auto;max-width:100%}.carousel-slider .carousel-slider__caption{position:relative}.carousel-slider .carousel-slider__caption .title{color:#474747;font-size:16px;font-weight:500;margin:10px 0 0;overflow:hidden;text-align:center;text-overflow:ellipsis}.carousel-slider .carousel-slider__caption .caption{font-size:14px;font-weight:300;margin:10px 0 0;text-align:center}.carousel-slider .carousel-slider__caption .caption:empty,.carousel-slider .carousel-slider__caption .title:empty{display:none}.carousel-slider[data-slide-type=post-carousel] .owl-stage{display:flex;flex-wrap:wrap}.carousel-slider[data-slide-type=post-carousel] .owl-item{display:flex;height:auto}.carousel-slider__post{border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.1),0 0 0 1px rgba(0,0,0,.1);margin:2px;position:relative;width:100%}.carousel-slider__post-content{display:flex;flex-direction:column;height:100%;justify-content:space-between}.carousel-slider__post-image{background-color:#f1f1f1;background-position:50%;background-size:cover;border-top-left-radius:4px;border-top-right-radius:4px;display:block;line-height:0;margin:0 auto;overflow:hidden;padding-top:66.6666%;position:relative;text-align:center;width:100%}.carousel-slider__post-title{display:block;margin:1rem;min-height:3.75em}.carousel-slider__post-title h1{font-size:1.25rem;margin:0}.carousel-slider__post-excerpt{font-size:1rem;line-height:1.6;margin:1rem 1rem 2rem;text-align:left}.carousel-slider__post-meta{align-items:flex-end;display:flex;font-size:.75rem;justify-content:space-between;margin:auto 1rem 1rem}.carousel-slider__post-author,.carousel-slider__post-publication-meta{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.carousel-slider__post-author{font-style:normal;line-height:1.6}.carousel-slider__post-author-link{display:inline-block;max-width:175px;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}.carousel-slider__post-category{text-transform:uppercase}.carousel-slider[data-slide-type=product-carousel] .owl-stage{display:flex;flex-wrap:wrap}.carousel-slider[data-slide-type=product-carousel] .owl-item{display:flex;height:auto}.carousel-slider__product{box-shadow:0 1px 2px rgba(0,0,0,.1),0 0 0 1px rgba(0,0,0,.1);margin:2px;position:relative;text-align:center;width:100%}.carousel-slider .woocommerce-loop-category__title,.carousel-slider .woocommerce-loop-product__title{color:var(--cs-product-text,#333);font-size:1.25rem;margin:1rem;padding:0}.carousel-slider .woocommerce-loop-product__link{display:block;margin:0;overflow:hidden;-webkit-text-decoration:none!important;text-decoration:none!important}.carousel-slider .price{color:var(--cs-product-text,#333);display:inline-block;font-size:.875rem;font-weight:400;margin:0 .5rem 0 1rem}.carousel-slider .price del{background-color:transparent;color:inherit;display:inline-block;opacity:.5}.carousel-slider .price ins{background-color:transparent;color:inherit;font-weight:700}.carousel-slider .onsale{background-color:var(--cs-product-primary,#96588a);color:var(--cs-product-on-primary,#f1f1f1);left:1rem;position:absolute;top:1rem}.carousel-slider .star-rating span:before{color:var(--cs-product-primary,#96588a)}.carousel-slider a.add_to_cart_button,.carousel-slider a.add_to_cart_read_more,.carousel-slider a.added_to_cart,.carousel-slider a.quick_view{background-color:var(--cs-product-primary,#96588a);color:var(--cs-product-on-primary,#f1f1f1);margin-bottom:.5rem;position:relative}.carousel-slider a.add_to_cart_button:hover,.carousel-slider a.add_to_cart_read_more:hover,.carousel-slider a.added_to_cart:hover,.carousel-slider a.quick_view:hover{background-color:var(--cs-product-primary,#96588a);color:var(--cs-product-on-primary,#f1f1f1);-webkit-text-decoration:none;text-decoration:none}.mfp-content .product{background-color:#fff;display:table;margin:0 auto;padding:15px}.mfp-content .product .images{display:inline-block;float:left;max-width:600px}.mfp-content .product .images img{display:block}.mfp-content .product .onsale{left:24px;position:absolute;top:24px}.mfp-content .product .summary{display:inline-block;margin-left:15px;width:300px}.mfp-content .product .description,.mfp-content .product .product_title{margin:0 0 1em}.mfp-content .product .price{display:inline-block;float:left;font-size:.857em;font-weight:400;margin:.5em 1em}.mfp-content .product .price del{background-color:transparent;color:inherit;display:inline-block;opacity:.5}.mfp-content .product .price ins{background-color:transparent;color:inherit;font-weight:700}.mfp-content .product a.add_to_cart_button,.mfp-content .product a.added_to_cart{background-image:none;border:0;border-radius:3px;box-shadow:none;-webkit-box-shadow:none;cursor:pointer;display:inline-block;font-weight:400;left:auto;line-height:1;margin:0;overflow:visible;padding:.5em 1em;position:relative;-webkit-text-decoration:none;text-decoration:none;text-shadow:none;white-space:nowrap}.mfp-content .product a.add_to_cart_button:hover,.mfp-content .product a.added_to_cart:hover{background-image:none;-webkit-text-decoration:none;text-decoration:none}.mfp-content .product a.add_to_cart_button.loading{opacity:.25;padding-right:2.618em}.mfp-content .product a.add_to_cart_button.loading:after{content:"";font-family:WooCommerce;vertical-align:top;-webkit-font-smoothing:antialiased;animation:spin 2s linear infinite;font-weight:400;position:absolute;right:1em;top:.618em}.mfp-content .product a.add_to_cart_button.added:after{content:"";font-family:WooCommerce;margin-left:.53em;vertical-align:bottom}.carousel-slider .star-rating,.mfp-content .star-rating{display:inline-block;float:right;font-family:star;font-size:1em;height:1em;line-height:1;margin:.5em 1em;overflow:hidden;position:relative;width:5.4em}.carousel-slider .star-rating:before,.mfp-content .star-rating:before{content:"sssss";float:left;left:0;position:absolute;top:0}.carousel-slider .star-rating span,.mfp-content .star-rating span{float:left;left:0;overflow:hidden;padding-top:1.5em;position:absolute;top:0}.carousel-slider .star-rating span:before,.mfp-content .star-rating span:before{content:"SSSSS";left:0;position:absolute;top:0}.mfp-ajax-holder .mfp-content,.mfp-inline-holder .mfp-content{margin-bottom:40px;margin-top:40px;max-width:945px}@media(max-width:600px){.mfp-content .product .images{margin-bottom:30px}.mfp-content .product .summary{display:block;margin:0;width:100%}}@media(min-width:601px){.mfp-content .product .images{display:inline-block;width:49%}.mfp-content .product .summary{display:inline-block;margin:0 0 0 1%;width:49%}}.carousel-slider .carousel-slider-video-wrapper{background:#000;height:100%;position:relative}.carousel-slider .carousel-slider-video-play-icon{-webkit-backface-visibility:hidden;background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' fill='%23f1f1f1'%3E%3Cpath d='m12.1 6.7 23 13.5-23 13.5V6.8z'/%3E%3Cpath d='M19.7 40c-11 0-20-9-20-20s9-20 20-20 20 9 20 20-9 20-20 20m0-38c-9.9 0-18 8.1-18 18s8.1 18 18 18 18-8.1 18-18-8.1-18-18-18'/%3E%3C/svg%3E") no-repeat;cursor:pointer;height:40px;left:50%;margin-left:-20px;margin-top:-20px;position:absolute;top:50%;transition:transform .1s ease;width:40px;z-index:2}.carousel-slider .carousel-slider-video-overlay{background-color:rgba(0,0,0,.5);height:100%;left:0;position:absolute;top:0;width:100%;z-index:1}.carousel-slider .carousel-slider-video-play-icon:hover{transform:scale(1.3)}.carousel-slider .animated{animation-duration:1s;animation-fill-mode:both}.carousel-slider .owl-animated-in{z-index:0}.carousel-slider .owl-animated-out{z-index:1}.carousel-slider .fadeOut{animation-name:fadeOut}.carousel-slider .fadeInDown{animation-name:fadeInDown}.carousel-slider .fadeInUp{animation-name:fadeInUp}.carousel-slider .fadeInRight{animation-name:fadeInRight}.carousel-slider .fadeInLeft{animation-name:fadeInLeft}.carousel-slider .zoomIn{animation-name:zoomIn}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeInDown{0%{opacity:0;transform:translate3d(0,-100%,0)}to{opacity:1;transform:none}}@keyframes fadeInUp{0%{opacity:0;transform:translate3d(0,100%,0)}to{opacity:1;transform:none}}@keyframes fadeInRight{0%{opacity:0;transform:translate3d(100%,0,0)}to{opacity:1;transform:none}}@keyframes fadeInLeft{0%{opacity:0;transform:translate3d(-100%,0,0)}to{opacity:1;transform:none}}@keyframes zoomIn{0%{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}.carousel-slider-outer .swiper-slide{height:auto}.carousel-slider-outer.swiper-vertical>.swiper-wrapper{max-height:100vh}.carousel-slider-outer .carousel-slider__post{height:calc(100% - 3px);width:calc(100% - 3px)}.carousel-slider-outer .swiper-button-next:hover,.carousel-slider-outer .swiper-button-prev:hover{--swiper-navigation-color:var(--carousel-slider-active-nav-color)}.carousel-slider-outer.navigation-visibility-hover .swiper-button-next,.carousel-slider-outer.navigation-visibility-hover .swiper-button-prev{opacity:0;transition:opacity .3s ease-in-out}.carousel-slider-outer.navigation-visibility-hover:hover .swiper-button-next,.carousel-slider-outer.navigation-visibility-hover:hover .swiper-button-prev{opacity:1}.carousel-slider-outer.pagination-visibility-hover .swiper-pagination{opacity:0;transition:opacity .3s ease-in-out}.carousel-slider-outer.pagination-visibility-hover:hover .swiper-pagination{opacity:1}.carousel-slider-outer.pagination-shape-square .swiper-pagination-bullet{border-radius:0!important}.carousel-slider-outer.pagination-align-left .swiper-pagination-horizontal{left:0!important;transform:none}.carousel-slider-outer.pagination-align-left .swiper-pagination{text-align:left}.carousel-slider-outer.pagination-align-right .swiper-pagination-horizontal{left:auto!important;right:0!important;transform:none}.carousel-slider-outer.pagination-align-right .swiper-pagination{text-align:right}.dialog--loading{text-align:center}.dialog--video-carousel{background-color:#000;max-height:100%;overflow:hidden}.dialog--video-carousel .cs-iframe{display:flex;height:auto;width:100%}.dialog--image-carousel,.dialog--image-carousel img{max-height:100%}assets/css/frontend.css000064400000064315151727276600011215 0ustar00.mfp-bg{background:#0b0b0b;opacity:.8;overflow:hidden;z-index:1042}.mfp-bg,.mfp-wrap{height:100%;left:0;position:fixed;top:0;width:100%}.mfp-wrap{-webkit-backface-visibility:hidden;outline:none!important;z-index:1043}.mfp-container{box-sizing:border-box;height:100%;left:0;padding:0 8px;position:absolute;text-align:center;top:0;width:100%}.mfp-container:before{content:"";display:inline-block;height:100%;vertical-align:middle}.mfp-align-top .mfp-container:before{display:none}.mfp-content{display:inline-block;margin:0 auto;position:relative;text-align:left;vertical-align:middle;z-index:1045}.mfp-ajax-holder .mfp-content,.mfp-inline-holder .mfp-content{cursor:auto;width:100%}.mfp-ajax-cur{cursor:progress}.mfp-zoom-out-cur,.mfp-zoom-out-cur .mfp-image-holder .mfp-close{cursor:zoom-out}.mfp-zoom{cursor:pointer;cursor:zoom-in}.mfp-auto-cursor .mfp-content{cursor:auto}.mfp-arrow,.mfp-close,.mfp-counter,.mfp-preloader{-webkit-user-select:none;user-select:none}.mfp-loading.mfp-figure{display:none}.mfp-hide{display:none!important}.mfp-preloader{color:#ccc;left:8px;margin-top:-.8em;position:absolute;right:8px;text-align:center;top:50%;width:auto;z-index:1044}.mfp-preloader a{color:#ccc}.mfp-preloader a:hover{color:#fff}.mfp-s-error .mfp-content,.mfp-s-ready .mfp-preloader{display:none}button.mfp-arrow,button.mfp-close{-webkit-appearance:none;background:transparent;border:0;box-shadow:none;cursor:pointer;display:block;outline:none;overflow:visible;padding:0;touch-action:manipulation;z-index:1046}button::-moz-focus-inner{border:0;padding:0}.mfp-close{color:#fff;font-family:Arial,Baskerville,monospace;font-size:28px;font-style:normal;height:44px;line-height:44px;opacity:.65;padding:0 0 18px 10px;position:absolute;right:0;text-align:center;-webkit-text-decoration:none;text-decoration:none;top:0;width:44px}.mfp-close:focus,.mfp-close:hover{opacity:1}.mfp-close:active{top:1px}.mfp-close-btn-in .mfp-close{color:#333}.mfp-iframe-holder .mfp-close,.mfp-image-holder .mfp-close{color:#fff;padding-right:6px;right:-6px;text-align:right;width:100%}.mfp-counter{color:#ccc;font-size:12px;line-height:18px;position:absolute;right:0;top:0;white-space:nowrap}.mfp-arrow{height:110px;margin:-55px 0 0;opacity:.65;padding:0;position:absolute;top:50%;width:90px;-webkit-tap-highlight-color:rgba(0,0,0,0)}.mfp-arrow:active{margin-top:-54px}.mfp-arrow:focus,.mfp-arrow:hover{opacity:1}.mfp-arrow:after,.mfp-arrow:before{border:inset transparent;content:"";display:block;height:0;left:0;margin-left:35px;margin-top:35px;position:absolute;top:0;width:0}.mfp-arrow:after{border-bottom-width:13px;border-top-width:13px;top:8px}.mfp-arrow:before{border-bottom-width:21px;border-top-width:21px;opacity:.7}.mfp-arrow-left{left:0}.mfp-arrow-left:after{border-right:17px solid #fff;margin-left:31px}.mfp-arrow-left:before{border-right:27px solid #3f3f3f;margin-left:25px}.mfp-arrow-right{right:0}.mfp-arrow-right:after{border-left:17px solid #fff;margin-left:39px}.mfp-arrow-right:before{border-left:27px solid #3f3f3f}.mfp-iframe-holder{padding-bottom:40px;padding-top:40px}.mfp-iframe-holder .mfp-content{line-height:0;max-width:900px;width:100%}.mfp-iframe-holder .mfp-close{top:-40px}.mfp-iframe-scaler{height:0;overflow:hidden;padding-top:56.25%;width:100%}.mfp-iframe-scaler iframe{background:#000;box-shadow:0 0 8px rgba(0,0,0,.6);display:block;height:100%;left:0;position:absolute;top:0;width:100%}img.mfp-img{box-sizing:border-box;display:block;height:auto;margin:0 auto;max-width:100%;padding:40px 0;width:auto}.mfp-figure,img.mfp-img{line-height:0}.mfp-figure:after{background:#444;bottom:40px;box-shadow:0 0 8px rgba(0,0,0,.6);content:"";display:block;height:auto;left:0;position:absolute;right:0;top:40px;width:auto;z-index:-1}.mfp-figure small{color:#bdbdbd;display:block;font-size:12px;line-height:14px}.mfp-figure figure{margin:0}.mfp-bottom-bar{cursor:auto;left:0;margin-top:-36px;position:absolute;top:100%;width:100%}.mfp-title{color:#f3f3f3;line-height:18px;text-align:left;word-wrap:break-word;padding-right:36px}.mfp-image-holder .mfp-content{max-width:100%}.mfp-gallery .mfp-image-holder .mfp-figure{cursor:pointer}@media screen and (max-height:300px),screen and (max-width:800px) and (orientation:landscape){.mfp-img-mobile .mfp-image-holder{padding-left:0;padding-right:0}.mfp-img-mobile img.mfp-img{padding:0}.mfp-img-mobile .mfp-figure:after{bottom:0;top:0}.mfp-img-mobile .mfp-figure small{display:inline;margin-left:5px}.mfp-img-mobile .mfp-bottom-bar{background:rgba(0,0,0,.6);bottom:0;box-sizing:border-box;margin:0;padding:3px 5px;position:fixed;top:auto}.mfp-img-mobile .mfp-bottom-bar:empty{padding:0}.mfp-img-mobile .mfp-counter{right:5px;top:3px}.mfp-img-mobile .mfp-close{background:rgba(0,0,0,.6);height:35px;line-height:35px;padding:0;position:fixed;right:0;text-align:center;top:0;width:35px}}@media (max-width:900px){.mfp-arrow{transform:scale(.75)}.mfp-arrow-left{transform-origin:0}.mfp-arrow-right{transform-origin:100%}.mfp-container{padding-left:6px;padding-right:6px}}.carousel-slider{display:none;width:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);position:relative;z-index:1}.carousel-slider .owl-stage{backface-visibility:hidden;position:relative;touch-action:manipulation}.carousel-slider .owl-stage:after{clear:both;content:".";display:block;height:0;line-height:0;visibility:hidden}.carousel-slider .owl-stage-outer{overflow:hidden;position:relative;transform:translateZ(0)}.carousel-slider .owl-carousel .owl-item,.carousel-slider .owl-carousel .owl-wrapper{backface-visibility:hidden;transform:translateZ(0)}.carousel-slider .owl-item{backface-visibility:hidden;float:left;min-height:1px;position:relative;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-touch-callout:none}.carousel-slider .owl-item img{display:block;width:100%}.carousel-slider .owl-dots.disabled,.carousel-slider .owl-nav.disabled{display:none}.carousel-slider .owl-dot,.carousel-slider .owl-nav .owl-next,.carousel-slider .owl-nav .owl-prev{cursor:pointer;-webkit-user-select:none;user-select:none}.carousel-slider .owl-nav button.owl-next,.carousel-slider .owl-nav button.owl-prev,.carousel-slider button.owl-dot{background:none;border:none;font:inherit;padding:0!important}.carousel-slider.owl-loaded{display:block}.carousel-slider.owl-loading{display:block;opacity:0}.carousel-slider.owl-hidden{opacity:0}.carousel-slider.owl-refresh .owl-item{visibility:hidden}.carousel-slider.owl-drag .owl-item{touch-action:pan-y;-webkit-user-select:none;user-select:none}.carousel-slider.owl-grab{cursor:move;cursor:grab}.carousel-slider.owl-rtl{direction:rtl}.carousel-slider.owl-rtl .owl-item{float:right}.no-js .carousel-slider{display:block}.carousel-slider .animated{animation-duration:1s;animation-fill-mode:both}.carousel-slider .owl-animated-in{z-index:0}.carousel-slider .owl-animated-out{z-index:1}.carousel-slider .fadeOut{animation-name:fadeOut}.carousel-slider .fadeInDown{animation-name:fadeInDown}.carousel-slider .fadeInUp{animation-name:fadeInUp}.carousel-slider .fadeInRight{animation-name:fadeInRight}.carousel-slider .fadeInLeft{animation-name:fadeInLeft}.carousel-slider .zoomIn{animation-name:zoomIn}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeInDown{0%{opacity:0;transform:translate3d(0,-100%,0)}to{opacity:1;transform:none}}@keyframes fadeInUp{0%{opacity:0;transform:translate3d(0,100%,0)}to{opacity:1;transform:none}}@keyframes fadeInRight{0%{opacity:0;transform:translate3d(100%,0,0)}to{opacity:1;transform:none}}@keyframes fadeInLeft{0%{opacity:0;transform:translate3d(-100%,0,0)}to{opacity:1;transform:none}}@keyframes zoomIn{0%{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}.owl-height{transition:height .5s ease-in-out}.carousel-slider .owl-item img.owl-lazy{background:url(data:image/gif;base64,R0lGODlhIAAgAPMAAP///5aWlufn58zMzODg4NXV1aysrLm5ue7u7vPz8+Li4qKiopeXlwAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ/V/nmOM82XiHRLYKhKP1oZmADdEAAAh+QQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY/CZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB+A4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6+Ho7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq+B6QDtuetcaBPnW6+O7wDHpIiK9SaVK5GgV543tzjgGcghAgAh+QQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK++G+w48edZPK+M6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE+G+cD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm+FNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk+aV+oJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0/VNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc+XiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30/iI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE/jiuL04RGEBgwWhShRgQExHBAAh+QQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR+ipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY+Yip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd+MFCN6HAAIKgNggY0KtEBAAh+QQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1+vsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d+jYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg+ygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0+bm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h+Kr0SJ8MFihpNbx+4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX+BP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA==) no-repeat 50%;min-height:32px;min-width:32px}.carousel-slider .owl-nav .owl-next,.carousel-slider .owl-nav .owl-prev{color:var(--carousel-slider-nav-color,#9e9e9e);display:inline-block;height:var(--carousel-slider-arrow-size,48px);margin:0;opacity:0;padding:0;position:absolute;top:50%;transform:translateY(-50%);transition:all .3s ease-in-out;width:var(--carousel-slider-arrow-size,48px)}.carousel-slider .owl-nav .owl-next:hover,.carousel-slider .owl-nav .owl-prev:hover{color:var(--carousel-slider-active-nav-color,#4caf50)}.carousel-slider .owl-nav .owl-next svg,.carousel-slider .owl-nav .owl-prev svg{fill:currentColor}.carousel-slider .owl-nav .owl-prev{left:0}.carousel-slider .owl-nav .owl-next{right:0}.carousel-slider.arrows-visibility-always .owl-next,.carousel-slider.arrows-visibility-always .owl-prev,.carousel-slider:hover .owl-nav .owl-next,.carousel-slider:hover .owl-nav .owl-prev{opacity:1}.carousel-slider.arrows-outside .owl-nav .owl-prev{left:calc(var(--carousel-slider-arrow-size, 48px)*-1)}.carousel-slider.arrows-outside .owl-nav .owl-next{right:calc(var(--carousel-slider-arrow-size, 48px)*-1)}.carousel-slider .owl-dots{text-align:center;-webkit-tap-highlight-color:rgba(0,0,0,0);margin-top:10px}.carousel-slider .owl-dots .owl-dot{display:inline-block;zoom:1;*display:inline}.carousel-slider .owl-dots .owl-dot span{-webkit-backface-visibility:visible;background-color:var(--carousel-slider-nav-color,#9e9e9e);display:block;height:var(--carousel-slider-bullet-size,10px);margin:4px 8px;transition:opacity .2s ease;width:var(--carousel-slider-bullet-size,10px)}.carousel-slider .owl-dots .owl-dot.active span,.carousel-slider .owl-dots .owl-dot:hover span{background-color:var(--carousel-slider-active-nav-color,#4caf50)}.carousel-slider.dots-center .owl-dots{text-align:center}.carousel-slider.dots-left .owl-dots{text-align:left}.carousel-slider.dots-left .owl-dots:first-child span{margin-left:0}.carousel-slider.dots-right .owl-dots{text-align:right}.carousel-slider.dots-right .owl-dots:last-child span{margin-right:0}.carousel-slider.dots-visibility-hover .owl-dots{opacity:0}.carousel-slider.dots-visibility-hover:hover .owl-dots{opacity:1}.carousel-slider.dots-circle .owl-dots .owl-dot span{border-radius:9999px}.cs-hero-button{-webkit-appearance:none;-webkit-font-smoothing:inherit;border-radius:0;box-sizing:border-box;display:inline-block;font-size:1rem;line-height:1;padding:.75em 1em;text-align:center;transition:all .2s ease-in-out}.cs-hero-button,.cs-hero-button:hover{-webkit-text-decoration:none;text-decoration:none}.cs-hero-button--normal{filter:alpha(opacity=90);opacity:.9}.cs-hero-button--stroke{background:transparent;border:1px solid transparent}.cs-hero-button--medium{font-size:1.2rem;padding:.9em 1.2em}.cs-hero-button--large{font-size:1.5rem;padding:.9em 1.6em}.carousel-slider-hero__cell__background{background-position:50%;background-repeat:no-repeat;background-size:cover;min-height:100%;min-width:100%;transition-duration:10s;transition-property:transform}.carousel-slider-hero__cell__background.carousel-slider-hero-ken-out{transform:scale(1.3)}.carousel-slider .active .carousel-slider-hero__cell__background,.carousel-slider .swiper-slide-active .carousel-slider-hero__cell__background,.carousel-slider .swiper-slide-duplicate-active .carousel-slider-hero__cell__background{animation-duration:20s;animation-timing-function:linear}.carousel-slider .active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-in,.carousel-slider .swiper-slide-active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-in,.carousel-slider .swiper-slide-duplicate-active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-in{animation-name:ken-burns-in;transform:scale(1.3)}.carousel-slider .active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-out,.carousel-slider .swiper-slide-active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-out,.carousel-slider .swiper-slide-duplicate-active .carousel-slider-hero__cell__background.carousel-slider-hero-ken-out{animation-name:ken-burns-out;transform:scale(1)}.carousel-slider-hero__cell{align-items:center;display:flex;height:var(--cell-height,400px);justify-content:center;overflow:hidden;position:relative}.carousel-slider-hero__cell:focus{outline:0}.carousel-slider-hero__cell__inner{background-position:50%;background-repeat:no-repeat;bottom:0;left:0;padding:50px;position:absolute;right:0;top:0}.carousel-slider-hero__cell__inner,.carousel-slider-hero__cell__inner:hover{color:#fff;display:flex}.carousel-slider-hero__cell__background_overlay{bottom:0;left:0;position:absolute;right:0;top:0;z-index:0}.carousel-slider-hero__cell__content{max-width:1140px;position:relative;width:100%;z-index:1}.carousel-slider-hero__cell__content.hidden{display:none}.carousel-slider-hero__cell__heading{color:var(--cs-heading-color,#fff);font-size:var(--cs-heading-font-size,40px);font-weight:700;line-height:1;margin-bottom:var(--cs-heading-gutter,30px)}.carousel-slider-hero__cell__description{color:var(--cs-description-color,#fff);font-size:var(--cs-description-font-size,20px);line-height:1.4;margin-bottom:var(--cs-description-gutter,30px)}.carousel-slider-hero__cell__button__one{margin-right:5px}.carousel-slider-hero__cell__button__two{margin-left:5px}.carousel-slider-hero__cell__button__one,.carousel-slider-hero__cell__button__two{display:inline-flex}.button.cs-hero-button{border-color:var(--cs-button-bg-color,#00d1b2);border-radius:var(--cs-button-border-radius,3px);border-style:solid;border-width:var(--cs-button-border-width,0)}.button.cs-hero-button,.button.cs-hero-button:hover{background-color:var(--cs-button-bg-color,#00d1b2);color:var(--cs-button-color,#fff)}.button.cs-hero-button.cs-hero-button-stroke,.button.cs-hero-button:hover{border-color:var(--cs-button-bg-color,#00d1b2)}.button.cs-hero-button.cs-hero-button-stroke{background-color:transparent;color:var(--cs-button-bg-color,#00d1b2)}.button.cs-hero-button.cs-hero-button-stroke:hover{background-color:var(--cs-button-bg-color,#00d1b2);color:var(--cs-button-color,#fff)}.carousel-slider-hero__cell__inner.carousel-slider--v-position-top{align-items:flex-start}.carousel-slider-hero__cell__inner.carousel-slider--v-position-bottom{align-items:flex-end}.carousel-slider-hero__cell__inner.carousel-slider--v-position-middle{align-items:center}.carousel-slider-hero__cell__inner.carousel-slider--h-position-left{justify-content:flex-start}.carousel-slider-hero__cell__inner.carousel-slider--h-position-right{justify-content:flex-end}.carousel-slider-hero__cell__inner.carousel-slider--h-position-center{justify-content:center}.carousel-slider-hero__cell__inner.carousel-slider--text-left{text-align:left}.carousel-slider-hero__cell__inner.carousel-slider--text-right{text-align:right}.carousel-slider-hero__cell__inner.carousel-slider--text-center{text-align:center}@media(max-width:767px){.carousel-slider-hero__cell__inner{padding:30px}.carousel-slider-hero__cell__heading{font-size:24px;line-height:1;margin-bottom:15px}.carousel-slider-hero__cell__description{font-size:14px;line-height:1.4;margin-bottom:15px}}.carousel-slider .carousel-slider__item{position:relative}.carousel-slider .carousel-slider__item img{display:block;height:auto;margin-left:auto;margin-right:auto;max-width:100%}.carousel-slider .carousel-slider__caption{position:relative}.carousel-slider .carousel-slider__caption .title{color:#474747;font-size:16px;font-weight:500;margin:10px 0 0;overflow:hidden;text-align:center;text-overflow:ellipsis}.carousel-slider .carousel-slider__caption .caption{font-size:14px;font-weight:300;margin:10px 0 0;text-align:center}.carousel-slider .carousel-slider__caption .caption:empty,.carousel-slider .carousel-slider__caption .title:empty{display:none}.carousel-slider[data-slide-type=post-carousel] .owl-stage{display:flex;flex-wrap:wrap}.carousel-slider[data-slide-type=post-carousel] .owl-item{display:flex;height:auto}.carousel-slider__post{border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.1),0 0 0 1px rgba(0,0,0,.1);margin:2px;position:relative;width:100%}.carousel-slider__post-content{display:flex;flex-direction:column;height:100%;justify-content:space-between}.carousel-slider__post-image{background-color:#f1f1f1;background-position:50%;background-size:cover;border-top-left-radius:4px;border-top-right-radius:4px;display:block;line-height:0;margin:0 auto;overflow:hidden;padding-top:66.6666%;position:relative;text-align:center;width:100%}.carousel-slider__post-title{display:block;margin:1rem;min-height:3.75em}.carousel-slider__post-title h1{font-size:1.25rem;margin:0}.carousel-slider__post-excerpt{font-size:1rem;line-height:1.6;margin:1rem 1rem 2rem;text-align:left}.carousel-slider__post-meta{align-items:flex-end;display:flex;font-size:.75rem;justify-content:space-between;margin:auto 1rem 1rem}.carousel-slider__post-author,.carousel-slider__post-publication-meta{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.carousel-slider__post-author{font-style:normal;line-height:1.6}.carousel-slider__post-author-link{display:inline-block;max-width:175px;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}.carousel-slider__post-category{text-transform:uppercase}.carousel-slider[data-slide-type=product-carousel] .owl-stage{display:flex;flex-wrap:wrap}.carousel-slider[data-slide-type=product-carousel] .owl-item{display:flex;height:auto}.carousel-slider__product{box-shadow:0 1px 2px rgba(0,0,0,.1),0 0 0 1px rgba(0,0,0,.1);margin:2px;position:relative;text-align:center;width:100%}.carousel-slider .woocommerce-loop-category__title,.carousel-slider .woocommerce-loop-product__title{color:var(--cs-product-text,#333);font-size:1.25rem;margin:1rem;padding:0}.carousel-slider .woocommerce-loop-product__link{display:block;margin:0;overflow:hidden;-webkit-text-decoration:none!important;text-decoration:none!important}.carousel-slider .price{color:var(--cs-product-text,#333);display:inline-block;font-size:.875rem;font-weight:400;margin:0 .5rem 0 1rem}.carousel-slider .price del{background-color:transparent;color:inherit;display:inline-block;opacity:.5}.carousel-slider .price ins{background-color:transparent;color:inherit;font-weight:700}.carousel-slider .onsale{background-color:var(--cs-product-primary,#96588a);color:var(--cs-product-on-primary,#f1f1f1);left:1rem;position:absolute;top:1rem}.carousel-slider .star-rating span:before{color:var(--cs-product-primary,#96588a)}.carousel-slider a.add_to_cart_button,.carousel-slider a.add_to_cart_read_more,.carousel-slider a.added_to_cart,.carousel-slider a.quick_view{background-color:var(--cs-product-primary,#96588a);color:var(--cs-product-on-primary,#f1f1f1);margin-bottom:.5rem;position:relative}.carousel-slider a.add_to_cart_button:hover,.carousel-slider a.add_to_cart_read_more:hover,.carousel-slider a.added_to_cart:hover,.carousel-slider a.quick_view:hover{background-color:var(--cs-product-primary,#96588a);color:var(--cs-product-on-primary,#f1f1f1);-webkit-text-decoration:none;text-decoration:none}.mfp-content .product{background-color:#fff;display:table;margin:0 auto;padding:15px}.mfp-content .product .images{display:inline-block;float:left;max-width:600px}.mfp-content .product .images img{display:block}.mfp-content .product .onsale{left:24px;position:absolute;top:24px}.mfp-content .product .summary{display:inline-block;margin-left:15px;width:300px}.mfp-content .product .description,.mfp-content .product .product_title{margin:0 0 1em}.mfp-content .product .price{display:inline-block;float:left;font-size:.857em;font-weight:400;margin:.5em 1em}.mfp-content .product .price del{background-color:transparent;color:inherit;display:inline-block;opacity:.5}.mfp-content .product .price ins{background-color:transparent;color:inherit;font-weight:700}.mfp-content .product a.add_to_cart_button,.mfp-content .product a.added_to_cart{background-image:none;border:0;border-radius:3px;box-shadow:none;-webkit-box-shadow:none;cursor:pointer;display:inline-block;font-weight:400;left:auto;line-height:1;margin:0;overflow:visible;padding:.5em 1em;position:relative;-webkit-text-decoration:none;text-decoration:none;text-shadow:none;white-space:nowrap}.mfp-content .product a.add_to_cart_button:hover,.mfp-content .product a.added_to_cart:hover{background-image:none;-webkit-text-decoration:none;text-decoration:none}.mfp-content .product a.add_to_cart_button.loading{opacity:.25;padding-right:2.618em}.mfp-content .product a.add_to_cart_button.loading:after{content:"";font-family:WooCommerce;vertical-align:top;-webkit-font-smoothing:antialiased;animation:spin 2s linear infinite;font-weight:400;position:absolute;right:1em;top:.618em}.mfp-content .product a.add_to_cart_button.added:after{content:"";font-family:WooCommerce;margin-left:.53em;vertical-align:bottom}.carousel-slider .star-rating,.mfp-content .star-rating{display:inline-block;float:right;font-family:star;font-size:1em;height:1em;line-height:1;margin:.5em 1em;overflow:hidden;position:relative;width:5.4em}.carousel-slider .star-rating:before,.mfp-content .star-rating:before{content:"sssss";float:left;left:0;position:absolute;top:0}.carousel-slider .star-rating span,.mfp-content .star-rating span{float:left;left:0;overflow:hidden;padding-top:1.5em;position:absolute;top:0}.carousel-slider .star-rating span:before,.mfp-content .star-rating span:before{content:"SSSSS";left:0;position:absolute;top:0}.mfp-ajax-holder .mfp-content,.mfp-inline-holder .mfp-content{margin-bottom:40px;margin-top:40px;max-width:945px}@media(max-width:600px){.mfp-content .product .images{margin-bottom:30px}.mfp-content .product .summary{display:block;margin:0;width:100%}}@media(min-width:601px){.mfp-content .product .images{display:inline-block;width:49%}.mfp-content .product .summary{display:inline-block;margin:0 0 0 1%;width:49%}}.carousel-slider .carousel-slider-video-wrapper{background:#000;height:100%;position:relative}.carousel-slider .carousel-slider-video-play-icon{-webkit-backface-visibility:hidden;background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' fill='%23f1f1f1'%3E%3Cpath d='m12.1 6.7 23 13.5-23 13.5V6.8z'/%3E%3Cpath d='M19.7 40c-11 0-20-9-20-20s9-20 20-20 20 9 20 20-9 20-20 20m0-38c-9.9 0-18 8.1-18 18s8.1 18 18 18 18-8.1 18-18-8.1-18-18-18'/%3E%3C/svg%3E") no-repeat;cursor:pointer;height:40px;left:50%;margin-left:-20px;margin-top:-20px;position:absolute;top:50%;transition:transform .1s ease;width:40px;z-index:2}.carousel-slider .carousel-slider-video-overlay{background-color:rgba(0,0,0,.5);height:100%;left:0;position:absolute;top:0;width:100%;z-index:1}.carousel-slider .carousel-slider-video-play-icon:hover{transform:scale(1.3)}.mfp-counter{display:none}assets/css/admin.css000064400000134641151727276600010466 0ustar00.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;overflow:hidden;padding-left:8px;padding-right:20px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir=rtl] .select2-selection--single .select2-selection__rendered{padding-left:20px;padding-right:8px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{border:none;box-sizing:border-box;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:#fff;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;left:-100000px;position:absolute;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{box-sizing:border-box;padding:4px;width:100%}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{background-color:#fff;border:0;display:block;filter:alpha(opacity=0);height:auto;left:0;margin:0;min-height:100%;min-width:100%;opacity:0;padding:0;position:fixed;top:0;width:auto;z-index:99}.select2-hidden-accessible{border:0!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:700}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;right:1px;top:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent;border-style:solid;border-width:5px 4px 0;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir=rtl] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir=rtl] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888;border-width:0 4px 5px}.select2-container--default .select2-selection--multiple{background-color:#fff;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:700;margin-right:10px;margin-top:5px;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:700;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir=rtl] .select2-selection--multiple .select2-search--inline,.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:1px solid #000;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple,.select2-container--default.select2-container--open.select2-container--above .select2-selection--single{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple,.select2-container--default.select2-container--open.select2-container--below .select2-selection--single{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{-webkit-appearance:textfield;background:transparent;border:none;box-shadow:none;outline:0}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:#fff}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;background-image:linear-gradient(180deg,#fff 50%,#eee);background-repeat:repeat-x;border:1px solid #aaa;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFFFFFFF",endColorstr="#FFEEEEEE",GradientType=0);outline:0}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:700;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;background-image:linear-gradient(180deg,#eee 50%,#ccc);background-repeat:repeat-x;border:none;border-bottom-right-radius:4px;border-left:1px solid #aaa;border-top-right-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFEEEEEE",endColorstr="#FFCCCCCC",GradientType=0);height:26px;position:absolute;right:1px;top:1px;width:20px}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent;border-style:solid;border-width:5px 4px 0;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir=rtl] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir=rtl] .select2-selection--single .select2-selection__arrow{border:none;border-radius:0;border-bottom-left-radius:4px;border-right:1px solid #aaa;border-top-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888;border-width:0 4px 5px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{background-image:linear-gradient(180deg,#fff 0,#eee 50%);background-repeat:repeat-x;border-top:none;border-top-left-radius:0;border-top-right-radius:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFFFFFFF",endColorstr="#FFEEEEEE",GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{background-image:linear-gradient(180deg,#eee 50%,#fff);background-repeat:repeat-x;border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFEEEEEE",endColorstr="#FFFFFFFF",GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:#fff;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:700;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir=rtl] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir=rtl] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{box-shadow:none;outline:0}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}:root{--shapla-primary:#2271b1;--shapla-primary-variant:#135e96;--shapla-on-primary:#fff}@keyframes shaplaButtonSpinAround{0%{transform:rotate(0deg)}to{transform:rotate(359deg)}}.shapla-button{--shapla-button-color:#f1f1f1;--shapla-button-color-dark:#ddd;--shapla-button-on-color:var(--shapla-text-primary,rgba(0,0,0,.87));align-items:center;-webkit-appearance:none;appearance:none;background-color:var(--shapla-button-color);border:1px solid transparent;border-radius:4px;box-shadow:none;color:var(--shapla-button-on-color);cursor:pointer;display:inline-flex;font-size:1rem;height:2.5em;justify-content:center;line-height:1.5;padding:calc(.5em - 1px) 1em;position:relative;text-align:center;-webkit-text-decoration:none;text-decoration:none;-webkit-user-select:none;user-select:none;vertical-align:top;white-space:nowrap}.shapla-button:active,.shapla-button:focus{outline:none}.shapla-button:focus{box-shadow:0 0 0 1px transparent,0 0 0 3px var(--shapla-button-color-alpha,rgba(0,0,0,.25))}.shapla-button strong{color:currentColor}.shapla-button svg{fill:currentColor}.shapla-button[disabled],fieldset[disabled] .shapla-button{cursor:not-allowed;opacity:.5}.shapla-button.is-fullwidth{display:flex;width:100%}.shapla-button.is-small{border-radius:2px;font-size:.75rem}.shapla-button.is-normal{font-size:1rem}.shapla-button.is-medium{font-size:1.25rem}.shapla-button.is-large{font-size:1.5rem}.shapla-button.is-rounded{border-radius:290486px;padding-left:1.25em;padding-right:1.25em}.shapla-button.is-fab{border-radius:50%;height:2.5em;min-width:2.5em;width:2.5em}.shapla-button.is-loading{color:transparent!important;pointer-events:none}.shapla-button.is-loading.is-outline:after{border-color:var(--shapla-button-color)}.shapla-button.is-loading:after{animation:shaplaButtonSpinAround .5s linear infinite;border:2px solid var(--shapla-button-on-color,#dbdbdb);border-radius:9999px;border-right-color:transparent!important;border-top-color:transparent!important;content:"";display:block;height:1em;left:calc(50% - .5em);position:absolute!important;top:calc(50% - .5em);width:1em}.shapla-button.is-primary{--shapla-button-color:var(--shapla-primary,#0d6efd);--shapla-button-color-dark:var(--shapla-primary-variant,#0261ed);--shapla-button-color-alpha:var(--shapla-primary-alpha,rgba(13,110,253,.25));--shapla-button-on-color:var(--shapla-on-primary,#fff)}.shapla-button.is-secondary{--shapla-button-color:var(--shapla-secondary,#757575);--shapla-button-color-dark:var(--shapla-secondary-variant,#686868);--shapla-button-color-alpha:var(--shapla-secondary-alpha,hsla(0,0%,46%,.25));--shapla-button-on-color:var(--shapla-on-secondary,#fff)}.shapla-button.is-success{--shapla-button-color:var(--shapla-success,#198754);--shapla-button-color-dark:var(--shapla-success-variant,#157147);--shapla-button-color-alpha:var(--shapla-success-alpha,rgba(25,135,84,.25));--shapla-button-on-color:var(--shapla-on-success,#fff)}.shapla-button.is-warning{--shapla-button-color:var(--shapla-warning,#ffc107);--shapla-button-color-dark:var(--shapla-warning-variant,#edb100);--shapla-button-color-alpha:var(--shapla-warning-alpha,rgba(255,193,7,.25));--shapla-button-on-color:var(--shapla-on-warning,#000)}.shapla-button.is-error{--shapla-button-color:var(--shapla-error,#dc3545);--shapla-button-color-dark:var(--shapla-error-variant,#d32535);--shapla-button-color-alpha:var(--shapla-error-alpha,rgba(220,53,69,.25));--shapla-button-on-color:var(--shapla-on-error,#fff)}.shapla-button:not(:disabled):active,.shapla-button:not(:disabled):hover{background-color:var(--shapla-button-color-dark);border-color:transparent;color:var(--shapla-button-on-color)}.shapla-button.is-outline{background-color:transparent;border-color:var(--shapla-button-color);color:var(--shapla-button-color)}.shapla-button.is-outline:not(:disabled):hover{background-color:var(--shapla-button-color);border-color:var(--shapla-button-color);color:var(--shapla-button-on-color)}.shapla-button.is-outline:not(.is-primary):not(.is-secondary):not(.is-success):not(.is-error):not(.is-warning){background-color:transparent;border-color:var(--shapla-button-color);color:var(--shapla-button-on-color)}.shapla-button.is-outline:not(.is-primary):not(.is-secondary):not(.is-success):not(.is-error):not(.is-warning):not(:disabled):hover{background-color:transparent;border-color:var(--shapla-button-color-dark);color:var(--shapla-button-on-color)}.shapla-button.has-shadow{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.shapla-button.has-shadow:not(:disabled):hover{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.shapla-button.has-shadow:not(:disabled):focus{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2)}.shapla-column{display:block;flex:1 1 0}.shapla-column[class*=is-]{flex:none}.shapla-columns.is-mobile>.shapla-column.is-1{width:8.3333333333%}.shapla-columns.is-mobile>.shapla-column.is-2{width:16.6666666667%}.shapla-columns.is-mobile>.shapla-column.is-3{width:25%}.shapla-columns.is-mobile>.shapla-column.is-4{width:33.3333333333%}.shapla-columns.is-mobile>.shapla-column.is-5{width:41.6666666667%}.shapla-columns.is-mobile>.shapla-column.is-6{width:50%}.shapla-columns.is-mobile>.shapla-column.is-7{width:58.3333333333%}.shapla-columns.is-mobile>.shapla-column.is-8{width:66.6666666667%}.shapla-columns.is-mobile>.shapla-column.is-9{width:75%}.shapla-columns.is-mobile>.shapla-column.is-10{width:83.3333333333%}.shapla-columns.is-mobile>.shapla-column.is-11{width:91.6666666667%}.shapla-columns.is-mobile>.shapla-column.is-12{width:100%}@media screen and (max-width:767px){.shapla-column.is-1-mobile{width:8.3333333333%}.shapla-column.is-2-mobile{width:16.6666666667%}.shapla-column.is-3-mobile{width:25%}.shapla-column.is-4-mobile{width:33.3333333333%}.shapla-column.is-5-mobile{width:41.6666666667%}.shapla-column.is-6-mobile{width:50%}.shapla-column.is-7-mobile{width:58.3333333333%}.shapla-column.is-8-mobile{width:66.6666666667%}.shapla-column.is-9-mobile{width:75%}.shapla-column.is-10-mobile{width:83.3333333333%}.shapla-column.is-11-mobile{width:91.6666666667%}.shapla-column.is-12-mobile{width:100%}}@media print,screen and (min-width:768px){.shapla-column.is-1,.shapla-column.is-1-tablet{width:8.3333333333%}.shapla-column.is-2,.shapla-column.is-2-tablet{width:16.6666666667%}.shapla-column.is-3,.shapla-column.is-3-tablet{width:25%}.shapla-column.is-4,.shapla-column.is-4-tablet{width:33.3333333333%}.shapla-column.is-5,.shapla-column.is-5-tablet{width:41.6666666667%}.shapla-column.is-6,.shapla-column.is-6-tablet{width:50%}.shapla-column.is-7,.shapla-column.is-7-tablet{width:58.3333333333%}.shapla-column.is-8,.shapla-column.is-8-tablet{width:66.6666666667%}.shapla-column.is-9,.shapla-column.is-9-tablet{width:75%}.shapla-column.is-10,.shapla-column.is-10-tablet{width:83.3333333333%}.shapla-column.is-11,.shapla-column.is-11-tablet{width:91.6666666667%}.shapla-column.is-12,.shapla-column.is-12-tablet{width:100%}}@media screen and (min-width:1024px){.shapla-column.is-1-desktop{width:8.3333333333%}.shapla-column.is-2-desktop{width:16.6666666667%}.shapla-column.is-3-desktop{width:25%}.shapla-column.is-4-desktop{width:33.3333333333%}.shapla-column.is-5-desktop{width:41.6666666667%}.shapla-column.is-6-desktop{width:50%}.shapla-column.is-7-desktop{width:58.3333333333%}.shapla-column.is-8-desktop{width:66.6666666667%}.shapla-column.is-9-desktop{width:75%}.shapla-column.is-10-desktop{width:83.3333333333%}.shapla-column.is-11-desktop{width:91.6666666667%}.shapla-column.is-12-desktop{width:100%}}@media screen and (min-width:1280px){.shapla-column.is-1-widescreen{width:8.3333333333%}.shapla-column.is-2-widescreen{width:16.6666666667%}.shapla-column.is-3-widescreen{width:25%}.shapla-column.is-4-widescreen{width:33.3333333333%}.shapla-column.is-5-widescreen{width:41.6666666667%}.shapla-column.is-6-widescreen{width:50%}.shapla-column.is-7-widescreen{width:58.3333333333%}.shapla-column.is-8-widescreen{width:66.6666666667%}.shapla-column.is-9-widescreen{width:75%}.shapla-column.is-10-widescreen{width:83.3333333333%}.shapla-column.is-11-widescreen{width:91.6666666667%}.shapla-column.is-12-widescreen{width:100%}}@media screen and (min-width:1400px){.shapla-column.is-1-fullhd{width:8.3333333333%}.shapla-column.is-2-fullhd{width:16.6666666667%}.shapla-column.is-3-fullhd{width:25%}.shapla-column.is-4-fullhd{width:33.3333333333%}.shapla-column.is-5-fullhd{width:41.6666666667%}.shapla-column.is-6-fullhd{width:50%}.shapla-column.is-7-fullhd{width:58.3333333333%}.shapla-column.is-8-fullhd{width:66.6666666667%}.shapla-column.is-9-fullhd{width:75%}.shapla-column.is-10-fullhd{width:83.3333333333%}.shapla-column.is-11-fullhd{width:91.6666666667%}.shapla-column.is-12-fullhd{width:100%}}.shapla-columns.is-centered{justify-content:center}.shapla-columns.is-mobile{display:flex}.shapla-columns.is-multiline{flex-wrap:wrap}.shapla-columns.is-vcentered{align-items:center}@media print,screen and (min-width:768px){.shapla-columns:not(.is-desktop){display:flex}}@media screen and (min-width:1024px){.shapla-columns.is-desktop{display:flex}}.shapla-columns{--shapla-column-gap:0.75rem;margin:calc(var(--shapla-column-gap, .75rem)*-1)}.shapla-columns:not(:last-child){margin-bottom:calc(1.5rem - var(--shapla-column-gap, .75rem))}.shapla-columns.is-gapless{--shapla-column-gap:0}.shapla-columns .shapla-column{padding:var(--shapla-column-gap,.75rem)}.shapla-delete-icon{-webkit-appearance:none;appearance:none;background-color:var(--delete-icon-background,rgba(var(--shapla-text-rgb,var(--shapla-black-rgb,0,0,0)),.2));border:none;border-radius:290486px;cursor:pointer;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:var(--delete-icon-size,20px);outline:none;pointer-events:auto;position:relative;-webkit-user-select:none;user-select:none;vertical-align:top;width:var(--delete-icon-size,20px)}.shapla-delete-icon:after,.shapla-delete-icon:before{background-color:var(--delete-icon-color,rgba(var(--shapla-text-rgb,var(--shapla-black-rgb,0,0,0)),.87));content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.shapla-delete-icon:before{height:2px;width:50%}.shapla-delete-icon:after{height:50%;width:2px}.shapla-delete-icon:focus,.shapla-delete-icon:hover{background-color:var(--delete-icon-background-dark,rgba(var(--shapla-text-rgb,var(--shapla-black-rgb,0,0,0)),.3))}.shapla-delete-icon:active{box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.shapla-delete-icon.is-small{--delete-icon-size:16px}.shapla-delete-icon.is-medium{--delete-icon-size:24px}.shapla-delete-icon.is-large{--delete-icon-size:32px}.shapla-delete-icon.is-error{--delete-icon-background:var(--shapla-error,#dc3545);--delete-icon-background-dark:var(--shapla-error-variant,#d32535);--delete-icon-color:var(--shapla-on-error,#fff)}.shapla-modal,.shapla-modal-background{bottom:0;left:0;position:absolute;right:0;top:0}.shapla-modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:var(--modal-z-index,100000)}.shapla-modal.is-active{display:flex}.shapla-modal-background{background-color:var(--modal-backdrop-color,rgba(0,0,0,.5))}.shapla-modal-background.is-light{--modal-backdrop-color:var(--modal-backdrop-color-light,hsla(0,0%,100%,.5))}.shapla-modal .shapla-delete-icon.is-fixed,.shapla-modal .shapla-modal-close.is-fixed{position:fixed;right:var(--modal-close-right,1.25rem);top:var(--modal-close-top,1.25rem)}.shapla-modal-content{margin:0 var(--modal-content-margin,20px);max-height:calc(100vh - var(--modal-content-spacing, 160px));overflow:auto;position:relative;width:var(--modal-content-width,calc(100% - var(--modal-content-margin, 20px)*2))}.shapla-modal-content.is-small{--modal-content-width:var(--modal-content-width-small,320px)}.shapla-modal-content.is-full{height:calc(100vh - var(--modal-content-margin, 20px)*2);width:calc(100vw - var(--modal-content-margin, 20px)*2)}@media print,screen and (min-width:768px){.shapla-modal-content{margin:0 auto;--modal-content-spacing:40px}.shapla-modal-content:not(.is-small):not(.is-full):not(.is-large){--modal-content-width:var(--modal-content-width-medium,640px)}}@media screen and (min-width:1024px){.shapla-modal-content.is-large{--modal-content-width:var(--modal-content-width-large,960px)}}.shapla-modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden}.shapla-modal-card__footer,.shapla-modal-card__header{align-items:center;background-color:var(--shapla-surface,#fff);display:flex;flex-shrink:0;justify-content:flex-start;padding:1rem;position:relative}.shapla-modal-card__footer>*+*,.shapla-modal-card__header>*+*{margin-left:.5rem}.shapla-modal-card__header{border-bottom:1px solid rgba(0,0,0,.12);border-top-left-radius:4px;border-top-right-radius:4px}.shapla-modal-card__title{flex-grow:1;flex-shrink:0;font-size:1.5rem;font-weight:400;line-height:1;margin:0}.shapla-modal-card__footer{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-top:1px solid rgba(0,0,0,.12)}.shapla-modal-card__footer.is-pulled-right{justify-content:flex-end}.shapla-modal-card__footer.no-content{border-top:none;padding:2px}.shapla-modal-card__body{background-color:var(--shapla-surface,#fff);flex-grow:1;flex-shrink:1;overflow:auto;padding:1rem}.shapla-modal-box,.shapla-modal-confirm{background-color:var(--shapla-surface,#fff);border-radius:4px;box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2);padding:1rem}.shapla-modal-confirm__content{padding:1rem;text-align:center}.shapla-modal-confirm__icon{border:.25em solid var(--shapla-primary,#0d6efd);border-radius:50%;color:var(--shapla-primary,#0d6efd);cursor:default;display:flex;height:5em;justify-content:center;margin:1.25em auto 1.875em;-webkit-user-select:none;user-select:none;width:5em}.shapla-modal-confirm__icon.is-success{border-color:var(--shapla-success,#198754);color:var(--shapla-success,#198754)}.shapla-modal-confirm__icon.is-error{border-color:var(--shapla-error,#dc3545);color:var(--shapla-error,#dc3545)}.shapla-modal-confirm__icon-content{align-items:center;display:flex;font-size:3.75em}.shapla-modal-confirm__title{font-size:1.875em;margin:0 0 .4em;text-align:center}.shapla-modal-confirm__actions{display:flex;justify-content:center;padding:1rem}.shapla-modal-confirm__actions>*+*{margin-left:.5rem}div[id*=_carousel_slider] .widget-top{background:#dff!important;border:1px solid #2196f3!important}div[id*=_carousel_slider] .widget-top:hover{background:#fdd!important;border:1px solid #f44336!important}.overflowHidden{overflow:hidden}.overflowVisible{overflow:visible}.sp-input-group{margin-bottom:10px}.sp-input-group:after{clear:both;content:"";display:table}.sp-input-label label{font-weight:600;margin-right:30px}.sp-input-field,.sp-input-label{float:left;width:100%}.sp-input-desc{color:#999;font-size:.9em;line-height:1.3em;margin:10px 30px 10px 0}.sp-input-text,.sp-input-textarea{padding:8px 8px 8px 16px;width:100%}.sp-input-text{height:35px!important}.sp-input-text option{padding:8px 4px}.spacing-text{width:62px}@media only screen and (min-width:600px){.sp-input-label{width:40%}.sp-input-field{width:60%}}@media only screen and (min-width:783px){.sp-input-label{width:30%}.sp-input-field{width:70%}.sp-input-text,.sp-input-textarea:not(cols){width:25em}}@media only screen and (min-width:851px){.sp-input-field,.sp-input-label{width:100%}.sp-input-label{margin-bottom:.5rem}}@media only screen and (min-width:1200px){.sp-input-label{width:40%}.sp-input-field{width:60%}}@media only screen and (min-width:1600px){.sp-input-label{width:30%}.sp-input-field{width:70%}}.carousel_slider_images:after,.carousel_slider_images:before{content:"";display:table}.carousel_slider_images:after{clear:both}.carousel_slider_gallery_btn{background-color:#f1f1f1;border:1px solid #616161;color:#616161;padding:5px 15px;-webkit-text-decoration:none;text-decoration:none}.carousel_slider_gallery_btn:hover{background-color:#fff;color:#616161}.carousel_slider_gallery_list{box-sizing:border-box;list-style:none;margin:15px 0 0;padding:0}.carousel_slider_gallery_list:after,.carousel_slider_gallery_list:before{content:"";display:table}.carousel_slider_gallery_list:after{clear:both}.carousel_slider_gallery_list li{float:left;margin:0;padding:0}.carousel_slider_gallery_list li>img{box-shadow:0 2px 4px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);display:block;margin-bottom:10px;margin-right:10px}#field-_post_categories,#field-_post_date_after,#field-_post_date_before,#field-_post_in,#field-_post_tags,#field-_product_categories,#field-_product_in,#field-_product_query,#field-_product_tags{display:none}#carousel-slider-autoplay-settings p,#carousel-slider-navigation-settings p,#carousel-slider-responsive-settings p{overflow:hidden}#carousel-slider-autoplay-settings input.small-text,#carousel-slider-autoplay-settings select.small-text,#carousel-slider-navigation-settings input.small-text,#carousel-slider-navigation-settings select.small-text,#carousel-slider-responsive-settings input.small-text,#carousel-slider-responsive-settings select.small-text{float:right}.tab-background .slide_bg_wrapper{display:flex;padding:1rem 0}@media only screen and (max-width:1280px){.tab-background .slide_bg_wrapper{flex-wrap:wrap}}.tab-background .slide_thumb{border:1px solid #e0e0e0;float:left;margin-right:1rem;padding:5px;position:relative}.tab-background .slide_thumb>div{background-color:#f1f1f1;background-position:0 0;background-repeat:no-repeat;background-size:100% auto;height:180px;width:320px}.tab-background .slide_thumb>span{background-color:rgba(0,0,0,.5);color:#fff;cursor:pointer;display:inline-block;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:14px;padding:3px;position:absolute;right:0;top:0;transition:all .3s ease-in-out}.tab-background .slide_thumb>span.hidden{display:none!important}.tab-background .slide_image_settings_line{display:block;margin:.5rem 0}.tab-background .slide_image_settings_line>span{display:inline-block;width:150px}.shapla-toggle{margin:1em 0!important}.shapla-toggle-title{cursor:pointer;display:block;outline:0;padding:15px 10px;position:relative}.shapla-toggle-title:after{content:"";font:400 20px/1 dashicons;margin-left:-1px;padding-right:3px;position:absolute;right:15px;vertical-align:top}.shapla-toggle-title.ui-state-active:after{content:""}.shapla-toggle-content{background-color:#f1f1f1;padding:20px}.shapla-toggle--normal .shapla-toggle-title{background:#9e9e9e;color:#fff;font-weight:600}.shapla-toggle--stroke .shapla-toggle-title{border:1px solid #363f48;font-weight:600}.shapla-toggle--stroke .shapla-toggle-title:after{color:#363f48}.shapla-toggle--stroke .shapla-toggle-content{background-color:#fff;border:1px solid #363f48;border-top:none;padding:20px}.shapla-nav{list-style:none!important;margin:0;padding:0}.shapla-nav:after,.shapla-nav:before{content:" ";display:table}.shapla-nav:after{clear:both}.shapla-nav li{float:left;margin:0 1px -1px 0!important;outline:0;position:relative;z-index:1}.shapla-nav a{display:block;line-height:1;outline:0;padding:15px 10px;-webkit-text-decoration:none;text-decoration:none}.shapla-tab{margin:0 0 2em;padding:21px 20px 20px}.shapla-tab,.shapla-tab *,.shapla-tab :after,.shapla-tab :before{box-sizing:border-box}.shapla-tab p:first-of-type{margin-top:0}.shapla-tab p:last-of-type{margin-bottom:0}.shapla-tabs--normal .shapla-nav{--shapla-primary:#d1d5db;--shapla-on-primary:#000}.shapla-tabs--normal .shapla-nav a{background:var(--shapla-primary);border:1px solid var(--shapla-primary);color:var(--shapla-on-primary)}.shapla-tabs--normal .shapla-nav .ui-tabs-active a{background:#fff;border-color:var(--shapla-primary);color:var(--shapla-on-primary);outline:0}.shapla-tabs--normal .shapla-nav .ui-tabs-active a:focus{box-shadow:none}.shapla-tabs--normal .shapla-tab{background:#fff}.shapla-tabs--normal .shapla-tab .sp-input-group{margin-bottom:1rem}.shapla-tabs--stroke .shapla-nav li{margin:0 -1px 0 0!important}.shapla-tabs--stroke .shapla-nav a{border:1px solid #323232;color:#323232}.shapla-tabs--stroke .shapla-nav .ui-tabs-active a{border-bottom-color:#fff}.shapla-tabs--stroke .shapla-tab{border:1px solid #323232;margin-top:-1px}.media-url-form-field{background-color:#f1f1f1;border:1px solid rgba(0,0,0,.12);display:flex}.media-url-form-field__content{display:flex;flex-direction:column;flex-grow:1;padding:.5rem}.media-url-form-field__item{display:flex;margin-bottom:.5rem}.media-url-form-field__item .name{display:inline-flex;width:20%}.media-url-form-field__item input,.media-url-form-field__item textarea{width:75%}.media-url-form-field__actions{display:flex;flex-direction:column;padding:.5rem}.media-url-form-field__actions.flex-direction-row{flex-direction:row}.media-url-form-field__actions.flex-direction-row>*+*{margin-left:.25rem}.media-url-form-field__actions>span{align-items:center;border:1px solid rgba(0,0,0,.12);border-radius:4px;cursor:pointer;display:inline-flex;height:calc(48px - .5rem);justify-content:center;margin-bottom:.5rem;width:calc(48px - .5rem)}.media-url-form-field__actions>span:hover{border-color:rgba(0,0,0,.2);border-radius:50%}.carousel_slider_url_images_list{list-style:none;margin:15px 0 0;padding:0}.carousel_slider_url_images_list li{display:inline-block;float:left;margin:0 5px 5px 0}.carousel-slider-video-carousel-urls-container{box-sizing:border-box;padding-top:6px}.carousel-slider-video-carousel-urls-container *,.carousel-slider-video-carousel-urls-container :after,.carousel-slider-video-carousel-urls-container :before{box-sizing:border-box}.carousel-slider-video-carousel-urls .sort_video_url_row{cursor:grab}.carousel-slider-video-carousel-urls input::placeholder{color:rgba(0,0,0,.38)}.carousel-slider-video-carousel-urls .cs-sortable-state-highlight{background-color:rgba(34,113,177,.25);min-height:6rem}.carousel_slider-fields--video-urls .media-url-form-field__item{flex-direction:column}.carousel_slider-fields--video-urls .media-url-form-field__item .name{font-weight:500;margin-bottom:.125rem;width:100%}.carousel_slider-fields--video-urls .media-url-form-field__item input,.carousel_slider-fields--video-urls .media-url-form-field__item textarea{padding:.25rem .5rem;width:100%}.carousel_slider_iframe{height:0;padding-bottom:56.25%;padding-top:25px;position:relative}.carousel_slider_iframe>iframe{height:100%;left:0;position:absolute;top:0;width:100%}.carousel_slider_columns{box-sizing:border-box;display:flex;flex-wrap:wrap}.carousel_slider_column{box-sizing:border-box;flex:0 0 100%;padding:1rem}@media screen and (min-width:601px){.carousel_slider_column{flex:0 0 50%}}@media screen and (min-width:1025px){.carousel_slider_column{flex:0 0 33.333333%}}@media screen and (min-width:1400px){.carousel_slider_column{flex:0 0 25%}}.switch-container{align-items:center;display:flex;flex-wrap:wrap}.switch-container .switch-label{display:inline-flex}.switch-container .switch-label-text{margin-left:.5rem}.switch-container .switch{background:#b4b9be;border:1px solid #b4b9be;border-radius:8px;cursor:pointer;display:inline-block;height:12px;position:relative;text-indent:-999999px;transition:background .35s ease;-webkit-user-select:none;user-select:none;vertical-align:middle;width:35px}.switch-container .switch:after,.switch-container .switch:before{border-radius:50%;content:"";display:block;height:20px;left:-3px;position:absolute;top:50%;transition:all .35s cubic-bezier(0,.95,.38,.98),background .15s ease;width:20px}.switch-container .switch:before{background:rgba(0,0,0,.2);transform:translate3d(0,-50%,0) scale(0)}.switch-container .switch:after{background:#999;border:1px solid rgba(0,0,0,.1);transform:translate3d(0,-50%,0)}.switch-container .switch:active:before{transform:translate3d(0,-50%,0) scale(3)}.switch-container input[type=checkbox],.switch-container input[type=checkbox]:checked:before{display:none!important}.switch-container input:checked+.switch:before{background:rgba(0,115,170,.075);transform:translate3d(100%,-50%,0) scale(1)}.switch-container input:checked+.switch:after{background:var(--shapla-primary,#0d6efd);transform:translate3d(100%,-50%,0)}.switch-container input:checked+.switch:active:before{background:rgba(0,115,170,.075);transform:translate3d(100%,-50%,0) scale(3)}.buttonset{display:inline-flex;flex-wrap:wrap;font-size:1rem}.buttonset input:first-child+.switch-label{border-bottom-left-radius:3px;border-top-left-radius:3px}.buttonset .switch-label:last-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.buttonset .switch-label{background:#fff;border:1px solid rgba(0,0,0,.12);border-right-width:0;color:#555;flex-grow:1;font-size:14px;margin:0;padding:.5rem .75rem;position:relative;text-align:center}.buttonset .switch-label:last-child{border-right:1px solid rgba(0,0,0,.2)!important}.buttonset .switch-input{display:none}.buttonset .switch-input:disabled+.switch-label{cursor:not-allowed;opacity:.6}.buttonset .switch-input:not(:disabled):checked+.switch-label{background-color:var(--shapla-primary,#0d6efd);color:var(--shapla-on-primary,#fff)}.buttonset .pro-only{background-color:#e0e0e0;border-radius:2px;color:#a5a5a5;font-size:8px;line-height:11px;opacity:1;padding:0 4px;position:absolute;right:0;text-transform:uppercase;top:0}.shapla-dimension{display:inline-block;font-size:12px;margin-bottom:6px;margin-right:10px;overflow:hidden;white-space:nowrap}.shapla-dimension .add-on{align-items:center;background-color:#fff;border:1px solid rgba(0,0,0,.1)!important;border-right:none!important;box-sizing:border-box;color:rgba(0,0,0,.5);display:flex;float:left;font-weight:400;height:2.83em;justify-content:center;line-height:calc(2.83em - 2px);min-width:16px;padding:0;text-align:center;width:2.83em}.shapla-dimension .add-on i{font-size:13px;text-rendering:auto;-webkit-font-smoothing:antialiased;height:32px;line-height:32px}.shapla-dimension .add-on svg{height:1.5em;width:1.5em;fill:currentColor}.shapla-dimension .add-on.cs-tooltip:after{display:none!important}.shapla-dimension input[type=text]{background:rgba(0,0,0,.05)!important;border:1px solid rgba(0,0,0,.05)!important;border-radius:0;box-shadow:none!important;box-sizing:border-box;color:#333;float:left;font-size:13px;height:34px;line-height:32px;margin:0;padding:0 .75em;text-align:center;width:68px}@media screen and (max-width:782px){.shapla-dimension .add-on{height:3.33em;width:3.33em}}.option-slider-type{border:2px solid rgba(0,0,0,.12);display:inline-flex;height:100%;position:relative;width:100%}input:checked~.option-slider-type{border-color:#2271b1}input:disabled~.option-slider-type{cursor:not-allowed;opacity:.38}.option-slider-type__icon{align-items:center;color:rgba(0,0,0,.38);display:inline-flex;justify-content:center}.option-slider-type__icon,.option-slider-type__icon>*{font-size:32px;height:32px;width:32px}.option-slider-type__icon svg{fill:currentColor}.option-slider-type__content{align-items:center;background-color:#e8ecef;display:flex;flex-direction:column;margin:.25rem;padding:.25rem;width:100%}.option-slider-type__pro{background-color:#cbd6df;line-height:1rem;padding:.125rem .25rem;position:absolute;right:.5rem;top:.5rem}.cs-flex{display:flex}.cs-inline-flex{display:inline-flex}.cs-flex-wrap{flex-wrap:wrap}.cs-items-center{align-items:center}.cs-justify-center{justify-content:center}.cs-justify-between{justify-content:space-between}.cs-mt-4{margin-top:1rem}.cs-mb-4,.cs-my-4{margin-bottom:1rem}.cs-my-4{margin-top:1rem}.cs-p-2{padding:.5rem!important}.cs-py-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.cs-space-x-1>*+*{margin-left:.25rem!important}.cs-bg-gray-200{background-color:#e5e7eb}.cs-text-red-600{color:#dc2626}.cs-w-8{width:2rem}.cs-h-8{height:2rem}.feedback-dialog__footer{align-items:center;width:100%}.feedback-dialog__form-caption{color:#495157;font-size:15px;font-weight:700;line-height:1.4}.feedback-dialog__form-body{padding-top:30px}.feedback-dialog__form-control{line-height:1;margin-bottom:15px;overflow:hidden}.feedback-dialog__form-input{box-shadow:none!important;float:left;margin:0 15px 0 0!important}.feedback-dialog__form-label{color:#6d7882;display:block;font-size:13px}.feedback-dialog .carousel-slider-feedback-alert,.feedback-dialog .carousel-slider-feedback-text{background-color:#fff;box-shadow:none;display:none;font-size:13px;margin:10px 0 0 30px;padding:5px;width:85%}.feedback-dialog .carousel-slider-feedback-alert{color:#b01b1b;padding:0}.feedback-dialog input:checked~label+.carousel-slider-feedback-alert,.feedback-dialog input:checked~label+.carousel-slider-feedback-text{display:block}.feedback-dialog .button--carousel-slider-feedback{font-size:16px}.feedback-dialog .button--skip-feedback{color:rgba(0,0,0,.38);-webkit-text-decoration:none;text-decoration:none}#menu-posts-carousels a[href="edit.php?post_type=carousels&page=go_carousel_slider_pro"],#menu-posts-carousels a[href="edit.php?post_type=carousels&page=go_carousel_slider_pro"]:hover,.carousel-slider-plugins-gopro{color:#93003c;font-weight:700}.carousel-slider-plugins-gopro{text-shadow:1px 1px 1px #eee}.shapla-modal,.shapla-modal *,.shapla-modal :after,.shapla-modal :before,shapla-dialog,shapla-dialog *,shapla-dialog :after,shapla-dialog :before{box-sizing:border-box}.input-copy-to-clipboard{background:rgba(0,0,0,.05)!important;border:1px solid rgba(0,0,0,.12)!important;margin-top:.5rem;padding:.75rem 1rem;-webkit-user-select:all;user-select:all;white-space:nowrap}.cs_plugin_upgrade_notice{border-top:1px solid #dba617;margin-top:1rem;padding:1rem 0}.cs_plugin_upgrade_notice__title{font-size:1.125em}.cs_plugin_upgrade_notice__description{padding-top:1rem}.post-type-carousels #minor-publishing-actions{padding-bottom:10px!important}.post-type-carousels #misc-publishing-actions{display:none!important}.carousel-slider-slider-type-container,.carousel-slider-slider-type-container *,.carousel-slider-slider-type-container :after,.carousel-slider-slider-type-container :before,.shapla-columns,.shapla-columns *,.shapla-columns :after,.shapla-columns :before{box-sizing:border-box}.cs-setting-section{border:1px solid rgba(0,0,0,.12)}.cs-setting-section:not(:last-child){margin-bottom:50px}.cs-setting-section__title{background-color:#f5f5f5;color:rgba(0,0,0,.87);font-size:20px!important;margin-bottom:20px!important;padding:.5rem!important}.cs-setting-section__content{padding:.5rem!important}#carousel-slider-settings .postbox-header,#carousel-slider-usages .postbox-header{display:none}#carousel-slider-settings .inside{margin:0;padding:0}#carousel-slider-settings .shapla-nav{background-color:#f1f1f1}#carousel-slider-settings .shapla-nav li{margin:0!important}#carousel-slider-settings .shapla-nav li.ui-tabs-active a{border-bottom-color:#fff}.admin-data-sharing-container{background-color:#ddd;border-radius:4px;display:inline-flex;flex-direction:column;margin-top:1rem;padding:.25rem}.admin-data-sharing-header{background:#fff;border-radius:4px;margin-bottom:.25rem;padding:.5rem}.admin-data-sharing-code{max-height:400px;max-width:600px;overflow:auto}.carousel_slider_preview_iframe_container{box-sizing:border-box;width:100%}.carousel_slider_preview_iframe_container *,.carousel_slider_preview_iframe_container :after,.carousel_slider_preview_iframe_container :before{box-sizing:border-box}.carousel_slider_preview_iframe_container iframe{width:100%}#carousel-slider-live-preview{display:none}.button-cs-preview{align-items:center;bottom:2rem;display:inline-flex!important;font-size:1.125rem!important;height:3rem;justify-content:center;padding:1rem 2rem!important;position:fixed;right:2rem;width:215px;z-index:1001}.button-cs-preview__label{display:inline-flex;margin-left:.5rem}.button-cs-preview.hidden{display:none!important}.shapla-tooltip{background-color:rgba(0,0,0,.92);background-image:linear-gradient(180deg,transparent,#000);box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12);color:#fff;display:none}.shapla-tooltip.is-theme-light{background-color:hsla(0,0%,96%,.92);background-image:linear-gradient(180deg,#f1f1f1,#f5f5f5);color:#323232}.shapla-tooltip__inner{border-radius:3px;font-size:12px;font-weight:400;max-width:200px;padding:4px 8px;word-wrap:break-word}.shapla-tooltip.is-active{display:block}.shapla-tooltip__arrow,.shapla-tooltip__arrow:before{background-color:inherit;height:.4rem;position:absolute;width:.8rem}.shapla-tooltip__arrow{visibility:hidden}.shapla-tooltip__arrow:before{content:"";transform:rotate(45deg);visibility:visible}.shapla-tooltip[data-popper-placement^=top]>.shapla-tooltip__arrow{bottom:0}.shapla-tooltip[data-popper-placement^=bottom]>.shapla-tooltip__arrow{top:0}.shapla-tooltip[data-popper-placement^=left]>.shapla-tooltip__arrow{right:0}.shapla-tooltip[data-popper-placement^=right]>.shapla-tooltip__arrow{left:0}[data-tooltip-target]{display:inline-block;float:right;height:1.5em;position:relative;width:1.5em}[data-tooltip-target]:after{font-family:Dashicons;speak:none;font-weight:400;text-transform:none;-webkit-font-smoothing:antialiased;content:"";cursor:help;height:100%;text-align:center;width:100%}assets/static-images/placeholder.svg000064400000002053151727276600013620 0ustar00<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
	<rect height="258" width="258" y="-1" x="-1" fill="#fff"/>
	<path d="m68.2 64.1l119.8 0c2.2 0 4 1.8 4 4l0 101.8c0.1 0.3 0.1 0.6 0 0.8l0 17.1c0 2.2-1.8 4-4 4l-119.8 0c-2.2 0-4-1.8-4-4l0-13.8c-0.3-0.6-0.3-1.3 0-1.8l0-104.1c0.1-2.2 1.9-4 4-4l0 0zm68.4 85.5l20.3-16.4c0.8-0.7 2-0.6 2.7 0.2l28.4 31.8 0-97 -119.8 0 0 99.6 40.5-44.8c0.4-0.4 0.9-0.7 1.5-0.7 0.6 0 1.1 0.2 1.5 0.6l24.9 26.7 0 0zm51.4 21.5l-30.1-33.7 -20.3 16.4c-0.8 0.7-2 0.6-2.7-0.2l-24.6-26.3 -42 46.4 0 14.2 119.7 0 0-16.8 0 0zm-28.1-90.6c-8.6 0-15.6 7-15.6 15.6 0 8.6 7 15.6 15.6 15.6 8.6 0 15.6-7 15.6-15.6 0.1-8.7-6.9-15.6-15.6-15.6l0 0zm0 3.9c-6.4 0-11.7 5.2-11.7 11.7 0 6.4 5.2 11.7 11.7 11.7 6.4 0 11.7-5.2 11.7-11.7 0-6.5-5.2-11.7-11.7-11.7z"/>
	<path d="m136.6 149.8l20.3-16.4c0.8-0.7 2-0.6 2.7 0.2l28.4 31.8 0-97 -119.8 0 0 99.6 40.5-44.8c0.4-0.4 0.9-0.7 1.5-0.7 0.6 0 1.1 0.2 1.5 0.6l24.9 26.7 0 0zm23.3-69.1c8.6 0 15.6 7 15.6 15.6 0 8.6-7 15.6-15.6 15.6 -8.6 0-15.6-7-15.6-15.6 0-8.7 7-15.6 15.6-15.6z" fill="#7aced7"/>
</svg>
assets/static-images/logo.svg000064400000017061151727276610012304 0ustar00<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="256" height="256" viewBox="0 0 500 500" version="1.1" xmlns="http://www.w3.org/2000/svg">
	<g id="text-carousel-slider" aria-label="Carousel Slider">
		<path
			d="m 73.957977,374.45746 q 0,-9.24683 2.838135,-13.41248 2.838135,-4.16565 8.422852,-4.16565 3.112793,0 5.859375,1.41907 v 3.479 q -2.792359,-1.51062 -5.630494,-1.51062 -7.736206,0 -7.736206,14.19068 0,7.69043 1.968384,10.94055 1.968384,3.25012 5.767822,3.25012 2.929688,0 5.859375,-1.78528 v 3.75367 q -2.746582,1.41906 -6.088256,1.41906 -5.722046,0 -8.514405,-4.02832 -2.746582,-4.02832 -2.746582,-13.5498 z"/>
		<path
			d="m 106.77963,366.72125 q 4.71497,0 6.45447,1.87683 1.7395,1.87683 1.7395,7.00379 v 15.97595 h -3.34167 l -0.0916,-3.52478 h -0.13732 q -2.19727,3.98254 -6.95801,3.98254 -3.06702,0 -4.94385,-1.9226 -1.876831,-1.96839 -1.876831,-5.35584 0,-4.2572 2.883911,-6.54602 2.88391,-2.33459 8.60596,-2.33459 h 2.24304 v -1.19019 q 0,-2.65503 -1.05286,-3.75366 -1.00708,-1.09863 -3.52478,-1.09863 -1.55639,0 -3.93677,0.59509 -2.38037,0.54931 -4.028315,1.28174 v -3.34168 q 1.647945,-0.73242 3.982545,-1.19018 2.33459,-0.45777 3.98254,-0.45777 z m 4.57764,11.94763 h -2.24304 q -7.96509,0 -7.96509,5.85938 0,2.10571 1.05286,3.25012 1.09863,1.09863 2.92968,1.09863 2.79236,0 4.48609,-2.24304 1.7395,-2.24304 1.7395,-6.31714 z"/>
		<path
			d="m 126.96701,367.17902 v 4.66919 h 0.13733 q 2.88391,-5.12696 8.05664,-5.12696 1.7395,0 3.25012,0.45777 v 3.29589 q -1.64795,-0.50354 -3.25012,-0.50354 -3.43323,0 -5.72205,2.83814 -2.28881,2.83813 -2.28881,7.50732 v 11.26099 h -3.70789 v -24.3988 z"/>
		<path
			d="m 144.0416,379.40131 q 0,-12.68006 9.38415,-12.68006 9.38416,0 9.38416,12.68006 0,12.63427 -9.38416,12.63427 -9.38415,0 -9.38415,-12.63427 z m 5.17272,7.27844 q 1.3733,2.10571 4.21143,2.10571 2.83814,0 4.16565,-2.10571 1.37329,-2.15149 1.37329,-7.27844 0,-5.17273 -1.37329,-7.27845 -1.32751,-2.15149 -4.16565,-2.15149 -2.83813,0 -4.21143,2.15149 -1.32751,2.10572 -1.32751,7.27845 0,5.12695 1.32751,7.27844 z"/>
		<path
			d="m 168.21152,383.10919 v -15.93017 h 3.57055 v 15.1062 q 0,3.89099 0.86975,5.17273 0.86976,1.23596 3.2959,1.23596 2.28882,0 3.84522,-2.56348 1.55639,-2.60925 1.55639,-7.14111 v -11.8103 h 3.70789 v 24.3988 h -3.479 l -0.0916,-3.52478 h -0.0916 q -0.86975,1.87683 -2.60925,2.92969 -1.7395,1.05285 -3.79944,1.05285 -3.61633,0 -5.21851,-2.01416 -1.55639,-2.01416 -1.55639,-6.91223 z"/>
		<path
			d="m 200.52963,369.83405 q -4.48608,0 -4.48608,3.43322 0,1.60218 0.9613,2.56348 1.00708,0.9613 3.52478,1.64795 4.98963,1.41907 6.5918,2.97546 1.60217,1.5564 1.60217,4.80652 0,3.20435 -2.19726,4.98963 -2.19727,1.78527 -6.22559,1.78527 -4.02832,0 -7.73621,-1.87683 v -3.75366 q 3.66211,2.47192 7.27845,2.47192 5.17273,0 5.17273,-3.66211 0,-1.7395 -1.00708,-2.65502 -1.00708,-0.96131 -3.93677,-1.78528 -4.30298,-1.23596 -6.04248,-2.88391 -1.69373,-1.69373 -1.69373,-4.62342 0,-3.06701 2.01416,-4.80652 2.05994,-1.7395 5.95093,-1.7395 3.93677,0 7.50732,1.64795 v 3.47901 q -3.70788,-2.01416 -7.27844,-2.01416 z"/>
		<path
			d="m 218.47397,380.59149 q 0.1831,4.34876 1.78528,6.27136 1.60217,1.92261 4.66919,1.92261 2.83813,0 6.31713,-1.69372 v 3.75366 q -3.479,1.19018 -6.59179,1.19018 -10.0708,0 -10.0708,-12.68005 0,-6.5918 2.33459,-9.61304 2.38037,-3.02124 7.04956,-3.02124 4.2572,0 6.31714,2.92969 2.10571,2.88391 2.10571,9.47571 0,0.50354 -0.0916,1.46484 z m 0,-3.11279 h 10.2539 q -0.0458,-7.50733 -4.76074,-7.50733 -2.65503,0 -3.98254,1.69373 -1.32752,1.64795 -1.51062,5.8136 z"/>
		<path
			d="m 248.64059,384.52826 q 0,3.11279 0.45777,3.70789 0.50354,0.59509 3.02124,0.59509 1.51062,0 3.479,-0.27466 v 3.25012 q -2.19726,0.22888 -3.98254,0.22888 -4.21143,0 -5.53894,-1.32751 -1.28174,-1.37329 -1.28174,-5.72205 v -24.44458 h -6.04248 v -3.20434 h 9.88769 z"/>
		<path
			d="m 294.50851,360.26678 q -2.19726,0 -3.61633,1.41907 -1.41907,1.41907 -1.41907,3.61634 0,2.33459 1.00708,3.89099 1.00708,1.51062 3.34168,2.56347 5.2185,2.3346 7.18689,4.8523 1.96838,2.47192 1.96838,6.50024 0,4.44031 -2.42615,6.68335 -2.42614,2.24304 -6.958,2.24304 -4.25721,0 -7.73621,-2.60925 v -4.44031 q 3.75366,3.66211 7.96509,3.66211 5.31006,0 5.31006,-5.53894 0,-2.56347 -1.23596,-4.2572 -1.23597,-1.69373 -4.0741,-2.97546 -4.39453,-1.96839 -6.31714,-4.48609 -1.87683,-2.5177 -1.87683,-6.08825 0,-3.75367 2.38037,-6.08826 2.38037,-2.3346 6.27136,-2.3346 2.47193,0 4.0741,0.36621 1.60217,0.36622 3.66211,1.51062 v 4.21143 q -3.61633,-2.70081 -7.50733,-2.70081 z"/>
		<path
			d="m 318.95309,384.52826 q 0,3.11279 0.45777,3.70789 0.50354,0.59509 3.02124,0.59509 1.51062,0 3.479,-0.27466 v 3.25012 q -2.19726,0.22888 -3.98254,0.22888 -4.21143,0 -5.53894,-1.32751 -1.28174,-1.37329 -1.28174,-5.72205 v -24.44458 h -6.04248 v -3.20434 h 9.88769 z"/>
		<path
			d="m 344.03854,367.17902 v 21.19445 h 5.08118 v 3.20435 h -15.47241 v -3.20435 h 6.54602 v -17.99011 h -5.12695 v -3.20434 z m -4.80651,-5.6305 v -5.63049 h 4.80651 v 5.63049 z"/>
		<path
			d="m 369.35287,357.3371 h 3.66211 v 34.24072 h -3.43322 l -0.0916,-3.52478 h -0.0916 q -2.5177,3.98254 -6.45447,3.98254 -3.70788,0 -5.95092,-3.15857 -2.24305,-3.15857 -2.24305,-9.52148 0,-12.63428 8.19397,-12.63428 4.25721,0 6.27137,3.98255 h 0.13732 z m -10.89477,22.01843 q 0,4.62341 1.46484,6.91223 1.46485,2.24304 3.98255,2.24304 2.38037,0 3.89099,-2.28882 1.55639,-2.33459 1.55639,-6.63757 v -0.45776 q 0,-4.2572 -1.55639,-6.54602 -1.51062,-2.3346 -3.89099,-2.3346 -5.44739,0 -5.44739,9.1095 z"/>
		<path
			d="m 382.53647,380.59149 q 0.1831,4.34876 1.78528,6.27136 1.60217,1.92261 4.66919,1.92261 2.83813,0 6.31713,-1.69372 v 3.75366 q -3.479,1.19018 -6.59179,1.19018 -10.0708,0 -10.0708,-12.68005 0,-6.5918 2.33459,-9.61304 2.38037,-3.02124 7.04956,-3.02124 4.2572,0 6.31714,2.92969 2.10571,2.88391 2.10571,9.47571 0,0.50354 -0.0915,1.46484 z m 0,-3.11279 h 10.2539 q -0.0458,-7.50733 -4.76074,-7.50733 -2.65503,0 -3.98254,1.69373 -1.32752,1.64795 -1.51062,5.8136 z"/>
		<path
			d="m 408.21701,367.17902 v 4.66919 h 0.13733 q 2.88391,-5.12696 8.05664,-5.12696 1.7395,0 3.25012,0.45777 v 3.29589 q -1.64795,-0.50354 -3.25012,-0.50354 -3.43323,0 -5.72205,2.83814 -2.28881,2.83813 -2.28881,7.50732 v 11.26099 h -3.70789 v -24.3988 z"/>
	</g>
	<g id="carousel">
		<rect
			y="642.17731"
			x="79.433174"
			height="200"
			width="100"
			style="display:inline;fill:#f44336;fill-opacity:1"
			transform="translate(0,-552.36217)"/>
		<rect
			y="642.17725"
			x="199.45549"
			height="200"
			width="100"
			style="display:inline;fill:#4caf50;fill-opacity:1"
			transform="translate(0,-552.36217)"/>
		<rect
			y="642.17731"
			x="319.45554"
			height="200"
			width="100"
			style="display:inline;fill:#2196f3;fill-opacity:1"
			transform="translate(0,-552.36217)"/>
	</g>
	<g id="pagination">
		<g transform="translate(13.72272,-547.51881)">
			<rect
				y="852.39502"
				x="199.99997"
				height="10"
				width="10"
				style="fill:#000000;fill-opacity:1"/>
			<rect
				y="852.36774"
				x="214.99846"
				height="10"
				width="10"
				style="fill:#000000;fill-opacity:1"/>
			<rect
				y="852.37762"
				x="230.01768"
				height="10"
				width="10"
				style="fill:#000000;fill-opacity:1"/>
			<rect
				y="852.3526"
				x="245.05391"
				height="10"
				width="10"
				style="fill:#000000;fill-opacity:1"/>
			<rect
				y="852.32104"
				x="260.0347"
				height="10"
				width="10"
				style="fill:#000000;fill-opacity:1"/>
		</g>
	</g>
	<g id="navigation">
		<path
			d="M 6,15 11,10 6,5 7,3 14,10 7,17 Z"
			id="right-arrow"
			transform="matrix(2.5,0,0,2.5,419.44451,169.81504)"/>
		<path
			d="m 14,5 -5,5 5,5 -1,2 -7,-7 7,-7 z"
			id="left-arrow"
			transform="matrix(2.5,0,0,2.5,29.352314,169.81504)"/>
	</g>
</svg>