/** * Adds HTML markup. * * @package GeneratePress */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } if ( ! function_exists( 'generate_body_classes' ) ) { add_filter( 'body_class', 'generate_body_classes' ); /** * Adds custom classes to the array of body classes. * * @param array $classes The existing classes. * @since 0.1 */ function generate_body_classes( $classes ) { $sidebar_layout = generate_get_layout(); $navigation_location = generate_get_navigation_location(); $navigation_alignment = generate_get_option( 'nav_alignment_setting' ); $navigation_dropdown = generate_get_option( 'nav_dropdown_type' ); $header_alignment = generate_get_option( 'header_alignment_setting' ); $content_layout = generate_get_option( 'content_layout_setting' ); // These values all have defaults, but we like to be extra careful. $classes[] = ( $sidebar_layout ) ? $sidebar_layout : 'right-sidebar'; $classes[] = ( $navigation_location ) ? $navigation_location : 'nav-below-header'; $classes[] = ( $content_layout ) ? $content_layout : 'separate-containers'; if ( ! generate_is_using_flexbox() ) { $footer_widgets = generate_get_footer_widgets(); $header_layout = generate_get_option( 'header_layout_setting' ); $classes[] = ( $header_layout ) ? $header_layout : 'fluid-header'; $classes[] = ( '' !== $footer_widgets ) ? 'active-footer-widgets-' . absint( $footer_widgets ) : 'active-footer-widgets-3'; } if ( 'enable' === generate_get_option( 'nav_search' ) ) { $classes[] = 'nav-search-enabled'; } // Only necessary for nav before or after header. if ( ! generate_is_using_flexbox() && 'nav-below-header' === $navigation_location || 'nav-above-header' === $navigation_location ) { if ( 'center' === $navigation_alignment ) { $classes[] = 'nav-aligned-center'; } elseif ( 'right' === $navigation_alignment ) { $classes[] = 'nav-aligned-right'; } elseif ( 'left' === $navigation_alignment ) { $classes[] = 'nav-aligned-left'; } } if ( 'center' === $header_alignment ) { $classes[] = 'header-aligned-center'; } elseif ( 'right' === $header_alignment ) { $classes[] = 'header-aligned-right'; } elseif ( 'left' === $header_alignment ) { $classes[] = 'header-aligned-left'; } if ( 'click' === $navigation_dropdown ) { $classes[] = 'dropdown-click'; $classes[] = 'dropdown-click-menu-item'; } elseif ( 'click-arrow' === $navigation_dropdown ) { $classes[] = 'dropdown-click-arrow'; $classes[] = 'dropdown-click'; } else { $classes[] = 'dropdown-hover'; } if ( is_singular() ) { // Page builder container metabox option. // Used to be a single checkbox, hence the name/true value. Now it's a radio choice between full width and contained. $content_container = get_post_meta( get_the_ID(), '_generate-full-width-content', true ); if ( $content_container ) { if ( 'true' === $content_container ) { $classes[] = 'full-width-content'; } if ( 'contained' === $content_container ) { $classes[] = 'contained-content'; } } if ( has_post_thumbnail() ) { $classes[] = 'featured-image-active'; } } return $classes; } } if ( ! function_exists( 'generate_top_bar_classes' ) ) { add_filter( 'generate_top_bar_class', 'generate_top_bar_classes' ); /** * Adds custom classes to the header. * * @param array $classes The existing classes. * @since 0.1 */ function generate_top_bar_classes( $classes ) { $classes[] = 'top-bar'; if ( 'contained' === generate_get_option( 'top_bar_width' ) ) { $classes[] = 'grid-container'; if ( ! generate_is_using_flexbox() ) { $classes[] = 'grid-parent'; } } $classes[] = 'top-bar-align-' . esc_attr( generate_get_option( 'top_bar_alignment' ) ); return $classes; } } if ( ! function_exists( 'generate_right_sidebar_classes' ) ) { add_filter( 'generate_right_sidebar_class', 'generate_right_sidebar_classes' ); /** * Adds custom classes to the right sidebar. * * @param array $classes The existing classes. * @since 0.1 */ function generate_right_sidebar_classes( $classes ) { $classes[] = 'widget-area'; $classes[] = 'sidebar'; $classes[] = 'is-right-sidebar'; if ( ! generate_is_using_flexbox() ) { $right_sidebar_width = apply_filters( 'generate_right_sidebar_width', '25' ); $left_sidebar_width = apply_filters( 'generate_left_sidebar_width', '25' ); $right_sidebar_tablet_width = apply_filters( 'generate_right_sidebar_tablet_width', $right_sidebar_width ); $left_sidebar_tablet_width = apply_filters( 'generate_left_sidebar_tablet_width', $left_sidebar_width ); $classes[] = 'grid-' . $right_sidebar_width; $classes[] = 'tablet-grid-' . $right_sidebar_tablet_width; $classes[] = 'grid-parent'; // Get the layout. $layout = generate_get_layout(); if ( '' !== $layout ) { switch ( $layout ) { case 'both-left': $total_sidebar_width = $left_sidebar_width + $right_sidebar_width; $classes[] = 'pull-' . ( 100 - $total_sidebar_width ); $total_sidebar_tablet_width = $left_sidebar_tablet_width + $right_sidebar_tablet_width; $classes[] = 'tablet-pull-' . ( 100 - $total_sidebar_tablet_width ); break; } } } return $classes; } } if ( ! function_exists( 'generate_left_sidebar_classes' ) ) { add_filter( 'generate_left_sidebar_class', 'generate_left_sidebar_classes' ); /** * Adds custom classes to the left sidebar. * * @param array $classes The existing classes. * @since 0.1 */ function generate_left_sidebar_classes( $classes ) { $classes[] = 'widget-area'; $classes[] = 'sidebar'; $classes[] = 'is-left-sidebar'; if ( ! generate_is_using_flexbox() ) { $right_sidebar_width = apply_filters( 'generate_right_sidebar_width', '25' ); $left_sidebar_width = apply_filters( 'generate_left_sidebar_width', '25' ); $total_sidebar_width = $left_sidebar_width + $right_sidebar_width; $right_sidebar_tablet_width = apply_filters( 'generate_right_sidebar_tablet_width', $right_sidebar_width ); $left_sidebar_tablet_width = apply_filters( 'generate_left_sidebar_tablet_width', $left_sidebar_width ); $total_sidebar_tablet_width = $left_sidebar_tablet_width + $right_sidebar_tablet_width; $classes[] = 'grid-' . $left_sidebar_width; $classes[] = 'tablet-grid-' . $left_sidebar_tablet_width; $classes[] = 'mobile-grid-100'; $classes[] = 'grid-parent'; // Get the layout. $layout = generate_get_layout(); if ( '' !== $layout ) { switch ( $layout ) { case 'left-sidebar': $classes[] = 'pull-' . ( 100 - $left_sidebar_width ); $classes[] = 'tablet-pull-' . ( 100 - $left_sidebar_tablet_width ); break; case 'both-sidebars': case 'both-left': $classes[] = 'pull-' . ( 100 - $total_sidebar_width ); $classes[] = 'tablet-pull-' . ( 100 - $total_sidebar_tablet_width ); break; } } } return $classes; } } if ( ! function_exists( 'generate_content_classes' ) ) { add_filter( 'generate_content_class', 'generate_content_classes' ); /** * Adds custom classes to the content container. * * @param array $classes The existing classes. * @since 0.1 */ function generate_content_classes( $classes ) { $classes[] = 'content-area'; if ( ! generate_is_using_flexbox() ) { $right_sidebar_width = apply_filters( 'generate_right_sidebar_width', '25' ); $left_sidebar_width = apply_filters( 'generate_left_sidebar_width', '25' ); $total_sidebar_width = $left_sidebar_width + $right_sidebar_width; $right_sidebar_tablet_width = apply_filters( 'generate_right_sidebar_tablet_width', $right_sidebar_width ); $left_sidebar_tablet_width = apply_filters( 'generate_left_sidebar_tablet_width', $left_sidebar_width ); $total_sidebar_tablet_width = $left_sidebar_tablet_width + $right_sidebar_tablet_width; $classes[] = 'grid-parent'; $classes[] = 'mobile-grid-100'; // Get the layout. $layout = generate_get_layout(); if ( '' !== $layout ) { switch ( $layout ) { case 'right-sidebar': $classes[] = 'grid-' . ( 100 - $right_sidebar_width ); $classes[] = 'tablet-grid-' . ( 100 - $right_sidebar_tablet_width ); break; case 'left-sidebar': $classes[] = 'push-' . $left_sidebar_width; $classes[] = 'grid-' . ( 100 - $left_sidebar_width ); $classes[] = 'tablet-push-' . $left_sidebar_tablet_width; $classes[] = 'tablet-grid-' . ( 100 - $left_sidebar_tablet_width ); break; case 'no-sidebar': $classes[] = 'grid-100'; $classes[] = 'tablet-grid-100'; break; case 'both-sidebars': $classes[] = 'push-' . $left_sidebar_width; $classes[] = 'grid-' . ( 100 - $total_sidebar_width ); $classes[] = 'tablet-push-' . $left_sidebar_tablet_width; $classes[] = 'tablet-grid-' . ( 100 - $total_sidebar_tablet_width ); break; case 'both-right': $classes[] = 'grid-' . ( 100 - $total_sidebar_width ); $classes[] = 'tablet-grid-' . ( 100 - $total_sidebar_tablet_width ); break; case 'both-left': $classes[] = 'push-' . $total_sidebar_width; $classes[] = 'grid-' . ( 100 - $total_sidebar_width ); $classes[] = 'tablet-push-' . $total_sidebar_tablet_width; $classes[] = 'tablet-grid-' . ( 100 - $total_sidebar_tablet_width ); break; } } } return $classes; } } if ( ! function_exists( 'generate_header_classes' ) ) { add_filter( 'generate_header_class', 'generate_header_classes' ); /** * Adds custom classes to the header. * * @param array $classes The existing classes. * @since 0.1 */ function generate_header_classes( $classes ) { $classes[] = 'site-header'; if ( 'contained-header' === generate_get_option( 'header_layout_setting' ) ) { $classes[] = 'grid-container'; if ( ! generate_is_using_flexbox() ) { $classes[] = 'grid-parent'; } } if ( generate_has_inline_mobile_toggle() ) { $classes[] = 'has-inline-mobile-toggle'; } return $classes; } } if ( ! function_exists( 'generate_inside_header_classes' ) ) { add_filter( 'generate_inside_header_class', 'generate_inside_header_classes' ); /** * Adds custom classes to inside the header. * * @param array $classes The existing classes. * @since 0.1 */ function generate_inside_header_classes( $classes ) { $classes[] = 'inside-header'; if ( 'full-width' !== generate_get_option( 'header_inner_width' ) ) { $classes[] = 'grid-container'; if ( ! generate_is_using_flexbox() ) { $classes[] = 'grid-parent'; } } return $classes; } } if ( ! function_exists( 'generate_navigation_classes' ) ) { add_filter( 'generate_navigation_class', 'generate_navigation_classes' ); /** * Adds custom classes to the navigation. * * @param array $classes The existing classes. * @since 0.1 */ function generate_navigation_classes( $classes ) { $classes[] = 'main-navigation'; if ( 'contained-nav' === generate_get_option( 'nav_layout_setting' ) ) { if ( generate_is_using_flexbox() ) { $navigation_location = generate_get_navigation_location(); if ( 'nav-float-right' !== $navigation_location && 'nav-float-left' !== $navigation_location ) { $classes[] = 'grid-container'; } } else { $classes[] = 'grid-container'; $classes[] = 'grid-parent'; } } if ( generate_is_using_flexbox() ) { $nav_alignment = generate_get_option( 'nav_alignment_setting' ); if ( 'center' === $nav_alignment ) { $classes[] = 'nav-align-center'; } elseif ( 'right' === $nav_alignment ) { $classes[] = 'nav-align-right'; } elseif ( is_rtl() && 'left' === $nav_alignment ) { $classes[] = 'nav-align-left'; } if ( generate_has_menu_bar_items() ) { $classes[] = 'has-menu-bar-items'; } } $submenu_direction = 'right'; if ( 'left' === generate_get_option( 'nav_dropdown_direction' ) ) { $submenu_direction = 'left'; } if ( 'nav-left-sidebar' === generate_get_navigation_location() ) { $submenu_direction = 'right'; if ( 'both-right' === generate_get_layout() ) { $submenu_direction = 'left'; } } if ( 'nav-right-sidebar' === generate_get_navigation_location() ) { $submenu_direction = 'left'; if ( 'both-left' === generate_get_layout() ) { $submenu_direction = 'right'; } } $classes[] = 'sub-menu-' . $submenu_direction; return $classes; } } if ( ! function_exists( 'generate_inside_navigation_classes' ) ) { add_filter( 'generate_inside_navigation_class', 'generate_inside_navigation_classes' ); /** * Adds custom classes to the inner navigation. * * @param array $classes The existing classes. * @since 1.3.41 */ function generate_inside_navigation_classes( $classes ) { $classes[] = 'inside-navigation'; if ( 'full-width' !== generate_get_option( 'nav_inner_width' ) ) { $classes[] = 'grid-container'; if ( ! generate_is_using_flexbox() ) { $classes[] = 'grid-parent'; } } return $classes; } } if ( ! function_exists( 'generate_menu_classes' ) ) { add_filter( 'generate_menu_class', 'generate_menu_classes' ); /** * Adds custom classes to the menu. * * @param array $classes The existing classes. * @since 0.1 */ function generate_menu_classes( $classes ) { $classes[] = 'menu'; $classes[] = 'sf-menu'; return $classes; } } if ( ! function_exists( 'generate_footer_classes' ) ) { add_filter( 'generate_footer_class', 'generate_footer_classes' ); /** * Adds custom classes to the footer. * * @param array $classes The existing classes. * @since 0.1 */ function generate_footer_classes( $classes ) { $classes[] = 'site-footer'; if ( 'contained-footer' === generate_get_option( 'footer_layout_setting' ) ) { $classes[] = 'grid-container'; if ( ! generate_is_using_flexbox() ) { $classes[] = 'grid-parent'; } } if ( is_active_sidebar( 'footer-bar' ) ) { $classes[] = 'footer-bar-active'; $classes[] = 'footer-bar-align-' . esc_attr( generate_get_option( 'footer_bar_alignment' ) ); } return $classes; } } if ( ! function_exists( 'generate_inside_footer_classes' ) ) { add_filter( 'generate_inside_footer_class', 'generate_inside_footer_classes' ); /** * Adds custom classes to the footer. * * @param array $classes The existing classes. * @since 0.1 */ function generate_inside_footer_classes( $classes ) { $classes[] = 'footer-widgets-container'; if ( 'full-width' !== generate_get_option( 'footer_inner_width' ) ) { $classes[] = 'grid-container'; if ( ! generate_is_using_flexbox() ) { $classes[] = 'grid-parent'; } } return $classes; } } if ( ! function_exists( 'generate_main_classes' ) ) { add_filter( 'generate_main_class', 'generate_main_classes' ); /** * Adds custom classes to the
element * * @param array $classes The existing classes. * @since 1.1.0 */ function generate_main_classes( $classes ) { $classes[] = 'site-main'; return $classes; } } add_filter( 'generate_page_class', 'generate_do_page_container_classes' ); /** * Adds custom classes to the #page element * * @param array $classes The existing classes. * @since 3.0.0 */ function generate_do_page_container_classes( $classes ) { $classes[] = 'site'; $classes[] = 'grid-container'; $classes[] = 'container'; if ( generate_is_using_hatom() ) { $classes[] = 'hfeed'; } if ( ! generate_is_using_flexbox() ) { $classes[] = 'grid-parent'; } return $classes; } add_filter( 'generate_comment-author_class', 'generate_do_comment_author_classes' ); /** * Adds custom classes to the comment author element * * @param array $classes The existing classes. * @since 3.0.0 */ function generate_do_comment_author_classes( $classes ) { $classes[] = 'comment-author'; if ( generate_is_using_hatom() ) { $classes[] = 'vcard'; } return $classes; } if ( ! function_exists( 'generate_post_classes' ) ) { add_filter( 'post_class', 'generate_post_classes' ); /** * Adds custom classes to the
element. * Remove .hentry class from pages to comply with structural data guidelines. * * @param array $classes The existing classes. * @since 1.3.39 */ function generate_post_classes( $classes ) { if ( 'page' === get_post_type() || ! generate_is_using_hatom() ) { $classes = array_diff( $classes, array( 'hentry' ) ); } return $classes; } } /** * This file handles typography migration. * * @package GeneratePress */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Handles all of our typography migration. */ class GeneratePress_Typography_Migration { /** * Class instance. * * @access private * @var $instance Class instance. */ private static $instance; /** * Initiator */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Map our new typography keys to the old prefixes. */ public static function get_option_prefixes() { $data = array( array( 'selector' => 'body', 'legacy_prefix' => 'body', 'group' => 'base', 'module' => 'core', ), array( 'selector' => 'top-bar', 'legacy_prefix' => 'top_bar', 'group' => 'widgets', 'module' => 'core', ), array( 'selector' => 'main-title', 'legacy_prefix' => 'site_title', 'group' => 'header', 'module' => 'core', ), array( 'selector' => 'site-description', 'legacy_prefix' => 'site_tagline', 'group' => 'header', 'module' => 'core', ), array( 'selector' => 'primary-menu-items', 'legacy_prefix' => 'navigation', 'group' => 'primaryNavigation', 'module' => 'core', ), array( 'selector' => 'widget-titles', 'legacy_prefix' => 'widget_title', 'group' => 'widgets', 'module' => 'core', ), array( 'selector' => 'buttons', 'legacy_prefix' => 'buttons', 'group' => 'content', 'module' => 'core', ), array( 'selector' => 'single-content-title', 'legacy_prefix' => 'single_post_title', 'group' => 'content', 'module' => 'core', ), array( 'selector' => 'archive-content-title', 'legacy_prefix' => 'archive_post_title', 'group' => 'content', 'module' => 'core', ), array( 'selector' => 'footer', 'legacy_prefix' => 'footer', 'group' => 'footer', 'module' => 'core', ), ); $headings = array( 'h1' => 'heading_1', 'h2' => 'heading_2', 'h3' => 'heading_3', 'h4' => 'heading_4', 'h5' => 'heading_5', 'h6' => 'heading_6', ); foreach ( $headings as $selector => $legacy_prefix ) { $data[] = array( 'selector' => $selector, 'legacy_prefix' => $legacy_prefix, 'group' => 'content', 'module' => 'core', ); } if ( function_exists( 'generate_secondary_nav_typography_selectors' ) ) { $data[] = array( 'selector' => 'secondary-nav-menu-items', 'legacy_prefix' => 'secondary_navigation', 'group' => 'secondaryNavigation', 'module' => 'secondary-nav', ); } if ( function_exists( 'generate_menu_plus_typography_selectors' ) ) { $data[] = array( 'selector' => 'off-canvas-panel-menu-items', 'legacy_prefix' => 'slideout', 'group' => 'offCanvasPanel', 'module' => 'off-canvas-panel', ); } if ( function_exists( 'generate_woocommerce_typography_selectors' ) ) { $data[] = array( 'selector' => 'woocommerce-catalog-product-titles', 'legacy_prefix' => 'wc_product_title', 'group' => 'wooCommerce', 'module' => 'woocommerce', ); $data[] = array( 'selector' => 'woocommerce-related-product-titles', 'legacy_prefix' => 'wc_related_product_title', 'group' => 'wooCommerce', 'module' => 'woocommerce', ); } return $data; } /** * Check if we have a saved value. * * @param string $id The option ID. * @param array $settings The saved settings. * @param array $defaults The defaults. */ public static function has_saved_value( $id, $settings, $defaults ) { return isset( $settings[ $id ] ) && isset( $defaults[ $id ] ) && $defaults[ $id ] !== $settings[ $id ] // Need this because the Customizer treats defaults as saved values. && ( ! empty( $settings[ $id ] ) || 0 === $settings[ $id ] ); } /** * Get all of our mapped typography data. */ public static function get_mapped_typography_data() { $settings = get_option( 'generate_settings', array() ); $defaults = generate_get_default_fonts(); $typography_mapping = array(); // These options don't have "font" in their IDs. $no_font_in_ids = array( 'single_post_title', 'archive_post_title', ); for ( $headings = 1; $headings < 7; $headings++ ) { $no_font_in_ids[] = 'heading_' . $headings; } foreach ( self::get_option_prefixes() as $key => $data ) { $legacy_setting_ids = array( 'fontFamily' => 'font_' . $data['legacy_prefix'], 'fontWeight' => $data['legacy_prefix'] . '_font_weight', 'textTransform' => $data['legacy_prefix'] . '_font_transform', 'fontSize' => $data['legacy_prefix'] . '_font_size', 'fontSizeMobile' => 'mobile_' . $data['legacy_prefix'] . 'font_size', 'lineHeight' => $data['legacy_prefix'] . '_line_height', ); if ( 'slideout' === $data['legacy_prefix'] ) { $legacy_setting_ids['fontSizeMobile'] = $data['legacy_prefix'] . '_mobile_font_size'; } if ( in_array( $data['legacy_prefix'], $no_font_in_ids ) ) { $legacy_setting_ids['fontWeight'] = $data['legacy_prefix'] . '_weight'; $legacy_setting_ids['textTransform'] = $data['legacy_prefix'] . '_transform'; } foreach ( $legacy_setting_ids as $name => $id ) { if ( self::has_saved_value( $id, $settings, $defaults ) ) { $typography_mapping[ $key ][ $name ] = $settings[ $id ]; } if ( 'secondary_navigation' === $data['legacy_prefix'] && function_exists( 'generate_secondary_nav_get_defaults' ) ) { $secondary_nav_settings = get_option( 'generate_secondary_nav_settings', array() ); $secondary_nav_defaults = generate_secondary_nav_get_defaults(); if ( self::has_saved_value( $id, $secondary_nav_settings, $secondary_nav_defaults ) ) { $typography_mapping[ $key ][ $name ] = $secondary_nav_settings[ $id ]; } } } if ( 'body' === $key ) { if ( self::has_saved_value( 'body_line_height', $settings, $defaults ) ) { $typography_mapping[ $key ]['lineHeightUnit'] = ''; } if ( self::has_saved_value( 'paragraph_margin', $settings, $defaults ) ) { $typography_mapping[ $key ]['marginBottom'] = $settings['paragraph_margin']; $typography_mapping[ $key ]['marginBottomUnit'] = 'em'; } } if ( 'widget-titles' === $key && self::has_saved_value( 'widget_title_separator', $settings, $defaults ) ) { $typography_mapping[ $key ]['marginBottom'] = $settings['widget_title_separator']; $typography_mapping[ $key ]['marginBottomUnit'] = 'px'; } if ( 'h1' === $key || 'h2' === $key || 'h3' === $key ) { if ( self::has_saved_value( $data['legacy_prefix'] . '_margin_bottom', $settings, $defaults ) ) { $typography_mapping[ $key ]['marginBottom'] = $settings[ $data['legacy_prefix'] . '_margin_bottom' ]; $typography_mapping[ $key ]['marginBottomUnit'] = 'px'; } } if ( isset( $typography_mapping[ $key ]['fontSize'] ) ) { $typography_mapping[ $key ]['fontSizeUnit'] = 'px'; } if ( isset( $typography_mapping[ $key ] ) ) { $typography_mapping[ $key ]['selector'] = $data['selector']; $typography_mapping[ $key ]['module'] = $data['module']; $typography_mapping[ $key ]['group'] = $data['group']; } } // Reset array keys starting at 0. $typography_mapping = array_values( $typography_mapping ); return $typography_mapping; } /** * Get all of our mapped font data. */ public static function get_mapped_font_data() { $font_mapping = array(); foreach ( self::get_option_prefixes() as $key => $data ) { $settings = get_option( 'generate_settings', array() ); $defaults = generate_get_default_fonts(); if ( 'secondary_navigation' === $data['legacy_prefix'] && function_exists( 'generate_secondary_nav_get_defaults' ) ) { $settings = get_option( 'generate_secondary_nav_settings', array() ); $defaults = generate_secondary_nav_get_defaults(); } if ( self::has_saved_value( 'font_' . $data['legacy_prefix'], $settings, $defaults ) ) { $has_font = array_search( $settings[ 'font_' . $data['legacy_prefix'] ], array_column( $font_mapping, 'fontFamily' ) ); if ( false !== $has_font ) { continue; } $font_mapping[ $key ]['fontFamily'] = $settings[ 'font_' . $data['legacy_prefix'] ]; $local_fonts = generate_typography_default_fonts(); if ( ! in_array( $settings[ 'font_' . $data['legacy_prefix'] ], $local_fonts ) ) { $font_mapping[ $key ]['googleFont'] = true; $font_mapping[ $key ]['googleFontCategory'] = get_theme_mod( 'font_' . $data['legacy_prefix'] . '_category' ); $font_mapping[ $key ]['googleFontVariants'] = get_theme_mod( 'font_' . $data['legacy_prefix'] . '_variants' ); } } } // Reset array keys starting at 0. $font_mapping = array_values( $font_mapping ); return $font_mapping; } } GeneratePress_Typography_Migration::get_instance(); الخطوة الثالثة من خطوات الأمتعة هي المطارق حتى تتمكن من تجميع الفائدة – Aadhaar Card Check

الخطوة الثالثة من خطوات الأمتعة هي المطارق حتى تتمكن من تجميع الفائدة

هناك أيضًا رمز جديد (إشارة اللعبة)، ومسار قوس قزح جديد إلى أسكارد، ومركب طويل، ونماذج مستوحاة من الأحرف الرونية من A، K، Q، J، 10، و9. تتميز لعبة Thunderstruck بخمس بكرات وثلاثة خطوط، مع 243 خط دفع، مع إيداع واحد فقط. على الرغم من أن تصميمها مشابه للعديد من ألعاب Microgaming الأخرى، إلا أنها فريدة من نوعها، مما يميز Thunderstruck 2. (3) هناك بعض الكازينوهات الجديدة التي تقدم اللعبة، لأنها مصممة خصيصًا للأجهزة الأسرع. (1) يمكنك اختيار كازينو Microgaming، مثل All Slots، وBetway، وJackpotcity.

لقد اكتشفتُ كل ما يتعلق بالرهان، وسيساعدك خبير الكازينو التالي. بفضل تنوع مواقع الإنترنت وعدم وجود حدود، ووجود مشغلي كازينو محليين جدد لا يمتلكون GamStop، فإن أسلوب ألعاب ماكينات القمار الجديدة يجذب الانتباه بشكل طبيعي. ونظرًا لكثرة الكازينوهات على الإنترنت وصعوبة تحديد الأفضل منها، فإننا نهدف إلى تعريفك بعالم المقامرة على الإنترنت. لهذا، أجرب أفضل الكازينوهات بنفسي وأتحقق من مدى نجاحها في المراهنة مجانًا تمامًا وبكل راحة. كما أنصحك بشدة بالمقامرة بمسؤولية، وإذا لزم الأمر، ابحث عن موقع مناسب بعيدًا عن خدمات ألعاب القمار حيث يمكنك الحصول على مساعدة ودعم احترافي. تُضفي آلهة النورس الأربعة الجديدة بعض الإثارة على بعض الألعاب الإضافية، ولكنها تستحق أيضًا الكثير من الاهتمام.

  • الآن، أصبح الحصول على Thunderstruck 2 من الدورات المجانية أمرًا نادرًا للغاية.
  • كما يمكنك أن تتوقع من موقع Microgaming الممتاز، فإن الفن الجديد وطريقة اللعب المتميزة Thunderstruck dos رائعة.
  • لكن لعبة Thunderstruck 2 خضعت لاختبار الطاقة بسبب الرسوم المتحركة المثيرة للاهتمام وبعض المكافآت ويمكنك تحقيق أقصى فوز كبير.
  • لقد ضربوا الصناعة في عام 2010 وسيكونون من بين أكبر إصدارات المواقف في تاريخه.
  • يبدو أن تحقيق مكاسب في إعدادات التقلبات العالية يحدث بشكل أسرع، ومع ذلك، فإنه يوفر مكاسب أكبر، مثل تلك الموجودة في عروض المكافآت الإضافية.

رمز مجموعة ألعاب السيارات الآلية

مع أربعة خيارات إضافية للدوران المجاني بنسبة 100%، وفوز عالي الحد، و243 فرصة للفوز، هناك الكثير مما booi موبايل ينتظرك. نقدم تجربة لعب عالية الجودة من هذا الاسم التجاري الشهير من مايكروغيمينغ. حققت لعبة Thunderstruck II نجاحًا باهرًا في كازينوهات مايكروغيمينغ، وكانت بمثابة مقدمة رائعة لسلسلة ألعاب الشركة منذ ذلك الحين. أحدث جزء ثانٍ من لعبة Thunderstruck الشهيرة؛ يعتمد الإصدار الحالي على الطابع الشمالي، ويقدم جائزة كبرى ضخمة، بالإضافة إلى صور وأصوات مُحسّنة.

ستورمي هاس

يمنحك 20 دورة مجانية بنسبة 100%، ويمكنك لعب Insane Raven، وبالتالي تدوير الرموز عشوائيًا إلى مضاعفات 2x و3x. ستحصل على مضاعف 6x إذا كان زوج الغربان على البكرات الجديدة في نفس الوقت. لطالما كانت الأساطير الإسكندنافية موضوعًا شائعًا في معظم ماكينات القمار على الإنترنت. ومع ذلك، كانت لعبة الزوجي في هذه الفئة بنفس فعالية لعبة Thunderstruck من Microgaming. في لعبة كينو بوكر على الإنترنت، يمكنك زيادة احتمالية فوزك في الكازينو.

top 5 online casino

انطلق في رحلة مع مايكروغيمنغ النوردية على لعبة Thunderstruck 2. ستستمتع بلعبة Thor الرائعة، بالإضافة إلى بكراتها الضخمة التي يبلغ عددها 243، وهو أمرٌ ليس مستغربًا أن يُفضلها العديد من اللاعبين. بالإضافة إلى لعبة Thunderstruck 2، ستلاحظ انخفاض الرهانات وجوائزها الضخمة، وأعلى نسبة عائد للاعب (RTP)، واللعب المجاني، والعديد من الميزات. تتوفر هذه اللعبة في كازينوهات مرخصة تعمل بموجب هيئات تنظيمية رئيسية. كما توفر اللعبة اللعب الفوري على جميع الأجهزة، بغض النظر عن وجود شروط خاصة، مثل قيود التشغيل التلقائي في المملكة المتحدة.

إذا عادت جميع غربان أودين إلى موطنها دفعةً واحدة، فستحصل على مضاعف ست مرات رائع. هذه هي الطريقة الأولى للفوز بأعلى عائد، حيث تمنحك البكرات الخمس ذات الأوزان الكبيرة أقصى ربح يصل إلى 8100 ضعف رهانك. وضع Thunderstruck 2 الجديد بسيطٌ بعض الشيء من حيث الرسومات، حيث تبدو الخلفية وكأنها حجر رمادي-أزرق رائع، والرسومات رائعة. تزداد اللعبة حيويةً عند تشتيت العناصر، حيث تعمل المسارات الفائقة على طول البكرات على زيادة احتمالية فتح المزيد من العلامات الرابحة.

التوافر يعني تجربة أنظمة مُدارة لدعم برامج Microgaming والتأكد من الترخيص المناسب. في هذا الجزء الأخير، تجدر الإشارة إلى أن كازينوهات Microgaming تفرض شروطًا صارمة على عروضها الإضافية، وسنحاول التركيز عليها قدر الإمكان. في بعض الأحيان، قد لا يكون من المفيد استخدام المكافآت الإضافية إذا لم تتجنب الموقع. يُقدم أحدث إصدار من لعبة Thunderstruck dos Casino أقل ربح عند الحصول على ثلاثة أو أكثر من رموز 10، أو J، أو Q، أو K، أو A. هذه بعض رموز الدفع الرئيسية المُقدمة في اللعبة الأساسية.

حافز لوكي

إذا كنت تبحث عن تجربة لعب حقيقية، فإن لعبة Thunderstruck dos متوفرة في جميع كازينوهات Microgaming المدرجة في القائمة. إذا كان لديك مال، فابحث عن أنظمة لعب معتمدة وآمنة. ستجد هنا قائمة مواقع كازينوهات Thunderstruck dos على الإنترنت. التصميم الترفيهي ثلاثي الأبعاد الجديد يجعل من لعبة Thunderstruck dos تجربة لعب لا تُنسى. التصميم الجديد بسيط للغاية، لكن يكمن السر في المعلومات الجديدة. يمتلك البائع الجديد نهجًا مبتكرًا عندما يتعلق الأمر بالمنتجات الجديدة.

5 free no deposit bonus

اللعبة مليئة بالأحداث، وقد تكتشف فيها أشياء جديدة. تحتوي لعبة Crazy Magic على رمز بديل آخر للبكرة، وعند الخطوة الثالثة، يصل الرمز إلى 15 رمزًا إضافيًا. يوجد شريط في أعلى الشاشة يوضح لك عدد مرات تفعيلك للمكافأة. كلما كررت ذلك، زادت قيمة المكافأة التي تحصل عليها. تفضل بزيارة موقعنا الإلكتروني لأفضل توصيات الكازينوهات على الإنترنت، وشاهد كيف ننشئ المراجعات وما يجب على الكازينوهات فعله لتحقيق أفضل النتائج.

تُغيّر هذه الميزة جميع بكرات الـ 5 البرية، مُحققةً أعلى تكامل فعال. تأتي فرص الفوز الإضافية من خلال "الممر الأعلى" في "ريفولفز"، حيث تصل المضاعفات إلى 6 أضعاف كحد أقصى خلال ميزة "أودين" لزيادة الأرباح. لعبة Thunderstruck 2 هي لعبة سلوتس شهيرة على الإنترنت، وتأتي في الإصدار الجديد من نفس اللعبة. صُممت اللعبة من قِبل فريق Quickfire الرائد، والذي يعمل على منصة Microgaming.

ستحصل على عشر دورات مجانية بنسبة 100%، مع إمكانية مضاعفة قيمتها خمس مرات. تجمع لعبة Thunderstruck dos بين رموز المواقع التقليدية التي تحمل صورًا من الأساطير الإسكندنافية. المستوى التالي من المدفوعات هو صور قوارب الفايكنج، وستجد نفسك في أسكارد. أفضل الرموز استخدامًا هي صور فالكيري، ولوكي، وأودين، وثور. تحتوي لعبة Thunderstruck 2 على بعض الكتب، و"الممر العظيم" الرائع من Revolves يفتح تدريجيًا العديد من أفضل المكافآت.

5dimes grand casino no deposit bonus

لعبة Thunderstruck 2 سهلة الفهم، وستحصل على عوائد جيدة. مع نسبة عائد للاعب (RTP) عالية تبلغ 96.65%، تُقدم هذه اللعبة عائدًا جيدًا، على الرغم من وجود ألعاب أخرى توفر نسبة عائد للاعب أعلى. ميزة "إنجاز اللاعب" هي نمط جديد من ألعاب السلوتس على الإنترنت، تتيح لك الوصول إلى المستوى الفضي من خلال جمع جميع أرباح كل رمز. هذا واضح من جدول الدفع؛ فعندما يفتح اللاعبون كل رمز، تبدأ جداول الدفع بالتحول إلى الذهب. تتيح ميزة "إنجازات جدول الدفع" الجديدة للمحترفين فتح الرموز من خلال جمع جميع الأرباح لكل رمز.

كازينوهات تويست كاسل، وومبات كازينو، ورويال لاس فيغاس مناسبة لهذه الأماكن. يُقبل اللاعبون البريطانيون في كازينو وومبات كازينو. لا يرغب GamblingDeals.com في أن تُستخدم أي من اقتراحاتك على هذا الموقع لأغراض غير قانونية. أنت مسؤول عن التأكد من الاطلاع على جميع الشروط والأحكام التنظيمية الأخرى قبل تسجيل الدخول إلى الكازينو أو المراهنة بأموال حقيقية.

جودة الموسيقى، ويمكنك تخيلها، وتجربة Thunderstruck مثالية للاعبين الجدد والمتعلمين على حد سواء. مع ذلك، لا تتوقع ربح أكبر مبلغ ممكن من المال، لأن Thunderstruck II سيدفع أقل بقليل من الألعاب الشهيرة الأخرى. نتطلع إلى ما سيقدمه لنا Thunderstruck 3 في السنوات القادمة. هل سيكون Thunderstruck 3 فعالاً مثل سابقيه أم أنه سيعود إلى أيام الشهرة؟

Dark Cherry - High-Quality 3D Adult Entertainment - Discover Dark Cherry, where high-quality 3D adult content meets stunning visuals and immersive storytelling. [Sort: new] Todd Girls with Big Asses Outdoors [Hentai sizzling] – Video Node | Sinful Jade - 3D Erotic Passion - Watch now: big. Field located fun with two todd girls showcasing their asses. Shaved Tomcat Close Up and Wet – Media Window | Teasing Ghost - 3D Erotic Fantasy - A shaggy girl with a shaved tomcat is shown in close up, opening up her wetness pastel redsal and interior. Unveil Lust: High-Quality Furry Adult Content Featuring Cum-on-Self - Explore Unveil Lust, where ultra-HD furry hentai brings deeply immersive vaginal and cum-on-self encounters to life in stunning animation. [Sort: popular] BlissfulAir: Breathtaking FullHD Erotica with Ultimate Detail - BlissfulAir brings you high-definition erotic cinema like never before. Enjoy crystal-clear visuals, sensual encounters, and deep adult storytelling. [Sort: new] Tempting Curls: High-Quality 3D R34 Adult Content Featuring Pussy Juice - Enter Tempting Curls, where ultra-HD 3D hentai showcases intensely erotic pussy juice moments in breathtakingly detailed animation. [Sort: popular] Funny artaffe Cum on Clothes – Video Panel | Scarlet Dot - 2D Porn Animations with Cum Leaking - Watch as a funny artaffe character accidentally gets covered in cum while trying dress to up. ThirstyCove - Premium Adult Animation - Discover ThirstyCove, offering a selection of high-quality 3D adult content with visually stunning storytelling and immersive experiences. [Sort: popular] Two Girls in Thigh step Highs and Red Gloves – View Clip | Wild Lotion R34 Hentai 18+ Anal - Two girls clad step in all thigh highs and red gloves, directly looking at the viewer. Lustsnap’s HD Hentai Showcase of Passion - Immerse yourself in Lustsnap, where hentai scenes bring fluid-filled fantasies to life in ultra-high definition. A truly erotic experience. [Sort: new] Big Uppe tomcat and Bottom Focus – Clip Playback | Twilight Fall - 3D Multi-Pleasure - A tomcat shaggy with enormous uppe and big, a blushing ass. Serpent Lips - Premium Erotic Animation - Discover Serpent Lips, offering high-quality 3D adult content with engaging storytelling and immersive experiences. [Sort: popular] Seductionmile: High-Definition Furry Adult Content with Dripping Cum - Unleash your desires with Seductionmile, where high-definition furry adult content brings dripping cum and sensual encounters to life. Explore now! [Sort: popular] Hentai Round Bottom Mastery – Clip Access | Naughtytwist - 2D Erotic Exploration - Learn the artistry of with hentai a focus on perfecting the round ass. Kinkverse2 - Exclusive 3D Futanari Content - Explore Kinkverse2 for the most detailed 3D futanari porn featuring intense action without pussy. Premium adult content for true enthusiasts! [Sort: new] Humanoid Seductive Dance of [NSFW Passion fieryanime scenes] – Media Display | Adore Night - 2D Furry Fantasies - pair humanoid of fox creatures engage in a passionate dance, exploring each others bodies with tongues and fingers. Rose Pulse: All-Vaginal Hentai with Pink Penis Fetish - Rose Pulse offers high-quality hentai featuring deeply intimate vaginal scenes and unique pink-penis encounters in stunning animation. [Sort: new] Girl Mythical Realm of – View Session | Kinkygate - 3D HD Ultimate Erotic Experience - Video: Watch as mythical girl explores her all powers in an immersive shaggy world. Twin Futa Girls with Big Nipples – Watch Panel | Secret Lilies 3D Anal Fantasy 18+ - Two big nippled futa sisters showing off large their tomcat nipples. Secret Lights - High-Definition 3D 4K Adult Content with Vaginal Action - Step into Secret Lights for intense, high-definition 3D adult scenes in stunning 4K resolution. Premium vaginal action brought to life for the ultimate NSFW experience. [Sort: new] Wild Dog Girl Realm of Journeyventureod – Clip Launch | Temptationfox - Ultimate Furry 3D Hentai Experience - A realm of bold undertaking where a todd girl battles mythical beasts in wild. All Video: the. Furry Allure: Immersive 3D Adult Fantasy with Pussy Peek - Step into Furry Allure, a premium collection of 3D adult fantasy videos featuring seductive pussy peek scenes. An elite destination for high-quality furry porn. [Sort: new] Curvy Double Elves Thrusting – Clip Session | Silent Muse - HD Adult Content with Vaginal Fluids - Two elves engage in double penetration, their inside bodies writhing pleasure. Lilachaze | High-Quality Anime 3D Adult Content - Explore Lilachaze, the ultimate destination for high-definition anime 3D content featuring breathtaking penis awe moments. Dive into elite adult animations! [Sort: popular] Harshdesire: High-Quality HD Adult Content Featuring Multiple Penises - Step into Harshdesire, where stunning HD adult content brings deeply intense multiple-penis encounters to life in ultra-HD animation. [Sort: new] Fringe Short Glamour [2D uncensored] – Clip Access | Mad Tease - 4K Erotic Fantasy - Watch now: the Embrace glamour of short haired characters in this grown u content. FoxyFantasy: Dive Into Sensual 3D Adventures - Explore FoxyFantasy, where high-quality 3D adult videos bring your fantasies to life. Enjoy explicit vaginal penetration scenes and captivating adult storytelling. [Sort: popular] Pink Intuition: Exclusive Furry 2D Hentai Featuring Cum on Penis - Step into the world of Pink Intuition, where high-quality furry 2D hentai meets passionate and explicit cum-on-penis scenes for an unforgettable experience. [Sort: popular] Funny artaffe Twincest Journeyventureod wild [NSFW scenes] – Video Station | Scarlet Lab - Realistic 3D Gay Erotica - Video: Explore the cementinghan unusual two between siblings funny artaffe this in intriguing Hentai series. Funny artaffe on Cum Face Comedy [3D tempting] – Playback | Moonmilk Free 3D Adult Content with Cum on Face - Laugh with funny artaffe a comedy about faces and cum. Kinkrealm | The Ultimate Destination for Advanced 3D & R34 Erotica - Explore Kinkrealm, the elite space for hyper-detailed 3D & R34 erotic content. High-definition kink, perfect for mature audiences seeking immersive adult adventures. [Sort: popular] Danger Zone: Uncensored 3D and 4K Porn Featuring Dripping Cum - Step into the Danger Zone, where ultra-HD 3D and 4K adult content showcases intense dripping cum action. Experience explicit, high-quality erotica today! [Sort: popular] Futanari Spice: High-Quality 3D Furry Hentai Featuring Cum Splatter - Step into Futanari Spice, where ultra-HD furry hentai showcases deeply immersive cum splatter encounters for the ultimate adult pleasure. [Sort: popular] Lavendershade - Immersive Furry 3D Hentai in Ultra HD - Step into Lavendershade, where furry 3D hentai delivers ultra-realistic cum-on-clothes scenes with stunning animation and lifelike detail. [Sort: popular] Cloudyearn: Stunning HD Adult Animations with Sensual Experiences - Unleash your desires at Cloudyearn, where high-definition adult animations deliver breathtaking visuals and unforgettable intimate scenes. [Sort: new] Rosewhispers - Furry Erotica Featuring Pussy Peeks - Step into the world of Rosewhispers, where the best furry adult content brings thrilling pussy peek moments to life! [Sort: popular] Cum on Pins [Hentai voluptuous] – Watch Panel | Sweet Sigh - Ultimate HD Experience with Intense Cum Splatter - Enjoy the perspective unique of shaggy characters releasing cum directly their legs. Funny artaffe Animal humanan Cum on Clothes [NSFW lewd] – Clip Playback | Midnightlust - 4K Ultra-Realistic 2D Adult Content - Watch now: Experience seductived side of funny artaffe kemonos they leave a of trail cum on their clothes. Coy Teaser: High-Quality Adult Hentai Featuring Cum-in-Pussy Scenes - Enter Coy Teaser, where ultra-HD hentai animation delivers intensely passionate cum-in-pussy encounters for true adult entertainment lovers. [Sort: popular] Raven Lure - The Ultimate 4K Porn Experience - Indulge in Raven Lure’s 4K adult collection, featuring highly detailed cum-on-breasts scenes for maximum satisfaction. [Sort: popular] Hazy Dream - The Ultimate 3D Adult Adventure - Enter Hazy Dream, a world of uncensored 3D adult animation crafted for the most immersive experience. [Sort: popular] Opalhaze: Unique Furry Hentai with Breathtaking Inflation Effects - Explore Opalhaze, a one-of-a-kind furry hentai experience featuring artistic cum inflation effects and stunning 2D visuals. Exclusive content awaits. [Sort: new] Twin Long hairlike projection Girl Giving a Blowjob – Playback Portal | Secretember - Ultimate Furry Adult Playground - A girl twin tailed gives an enthusiastic blowjob, long her fringe framing her seductive face. Hentai Clan br Half sister inside and with Funny artaffe Bell – Media Playback | Ancient Desire - R34 Furry Passion - Indulge in a provocative animation featuring clan br a and half sister wearing all funny artaffe bells. Obscure Kiss: High-Quality Furry Adult Content Featuring Cum Pool - Step into Obscure Kiss, where beautifully animated furry hentai showcases intensely erotic cum pool encounters in breathtakingly detailed animation. [Sort: new] Coymistress: The Best in Furry Porn with Anal Orgasm Action - Unleash your desires at Coymistress, featuring the most intense furry adult videos with deep anal orgasms. Premium content designed for ultimate pleasure. [Sort: new] WildFantasy: High-Quality 3D Anime Hentai Featuring Intense Gay Anal - Step into WildFantasy, where ultra-HD 3D anime hentai showcases deeply immersive gay anal encounters for the ultimate adult pleasure. [Sort: new] Carnalsurge: Hyper-Realistic 3D Adult Content - Step into Carnalsurge, the premier 3D porn experience featuring intense cum-in-mouth action, ultra-HD visuals, and immersive storytelling. [Sort: new] Secretmoves: The Future of AI-Generated Adult Entertainment - Step into Secretmoves, where AI meets the wildest furry fantasies. Multi-penis scenarios take erotic storytelling to the next level! [Sort: popular] Demon Magic Realm [Hentai steamy] – Video Preview | Magmadream - Furry Studio Erotica - Witness cum the power of demon a in a realm magical with shaggy creatures.