<?php
/**
 * Plugin Name: Easy Table of Contents
 * Plugin URI: https://tocwp.com/
 * Description: Adds a user friendly and fully automatic way to create and display a table of contents generated from the page content.
 * Version: 2.0.83
 * Author: Magazine3
 * Author URI: https://tocwp.com/
 * Text Domain: easy-table-of-contents
 * Domain Path: /languages
 * License: GPLv2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 *
 * Copyright 2022  Magazine3  ( email : team@magazine3.in )
 *
 * Easy Table of Contents is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Easy Table of Contents; if not, see <http://www.gnu.org/licenses/>.
 *
 * @package  Easy Table of Contents
 * @category Plugin
 * @author   Magazine3
 * @version  2.0.83
 */

use Eztoc\Table_Of_Contents\Debug;
use function Eztoc\Table_Of_Contents\Cord\insertElementByPTag;
use function Eztoc\Table_Of_Contents\Cord\insertElementByImgTag;
use function Eztoc\Table_Of_Contents\Cord\mb_find_replace;

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;

if ( ! class_exists( 'ezTOC' ) ) {

	/**
	 * Class ezTOC
	 */
	final class ezTOC {

		/**
		 * Current version.
		 *
		 * @since 1.0
		 * @var string
		 */
		const VERSION = '2.0.83';

		/**
		 * Stores the instance of this class.
		 *
		 * @access private
		 * @since  1.0
		 * @static
		 *
		 * @var ezTOC
		 */
		private static $instance;

		/**
		 * @since 2.0
		 * @var array
		 */
		private static $store = array();

		/**
		 * A dummy constructor to prevent the class from being loaded more than once.
		 *
		 * @access public
		 * @since  1.0
		 */
		public function __construct() { /* Do nothing here */ }

		/**
		 * @access private
		 * @since  1.0
		 * @static
		 *
		 * @return ezTOC
		 */
		public static function instance() {

			if ( ! isset( self::$instance ) && ! ( self::$instance instanceof self ) ) {

				self::$instance = new self;

				self::define_constants();
				self::includes();
				self::hooks();

				self::load_text_domain();
			}

			return self::$instance;
		}

		/**
		 * Define the plugin constants.
		 *
		 * @access private
		 * @since  1.0
		 * @static
		 */
		private static function define_constants() {

			define( 'EZ_TOC_DIR_NAME', plugin_basename( dirname( __FILE__ ) ) );
			define( 'EZ_TOC_BASE_NAME', plugin_basename( __FILE__ ) );
			define( 'EZ_TOC_PATH', dirname( __FILE__ ) );
			define( 'EZ_TOC_URL', plugin_dir_url( __FILE__ ) );
		}

		/**
		 * Includes the plugin dependency files.
		 *
		 * @access private
		 * @since  1.0
		 * @static
		 */
		private static function includes() {

			require_once( EZ_TOC_PATH . '/includes/class-eztoc-option.php' );
			require_once( EZ_TOC_PATH. '/includes/public-helper-function.php' );

			if ( is_admin() ) {

				// This must be included after `class.options.php` because it depends on it methods.
				require_once( EZ_TOC_PATH . '/includes/class-eztoc-admin.php' );
				require_once( EZ_TOC_PATH. '/includes/helper-function.php' );
				require_once( EZ_TOC_PATH . '/includes/class-eztoc-pointers.php' );

			}

			require_once( EZ_TOC_PATH . '/includes/inc.functions.php' );
			require_once( EZ_TOC_PATH . '/includes/class-eztoc-post.php' );
            require_once( EZ_TOC_PATH . '/includes/class-eztoc-widget.php' );
			require_once( EZ_TOC_PATH . '/includes/class-eztoc-widgetsticky.php' );
			require_once( EZ_TOC_PATH . '/includes/class-debug.php' );			
			require_once( EZ_TOC_PATH . '/includes/inc.cord-functions.php' );
			require_once( EZ_TOC_PATH . '/includes/inc.plugin-compatibility.php' );
			require_once( EZ_TOC_PATH . '/includes/class-eztoc-sitemap.php' );
			
		}

		/**
		 * Add the core action filter hook.
		 *
		 * @access private
		 * @since  1.0
		 * @static
		 */
		private static function hooks() {

			add_action( 'admin_head', array( __CLASS__, 'add_editor_button' ) );
			add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
			add_action( 'wp_enqueue_scripts', array( __CLASS__, 'ez_toc_inline_styles' ) );
			add_action( 'wp_enqueue_scripts', array( __CLASS__, 'ez_toc_inline_sticky_styles' ) );
			add_action( 'wp_head', array( __CLASS__, 'ez_toc_schema_sitenav_creator' ) );												
			add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts_for_exclude_css' ) );
			
			if ( !self::check_beaver_builder_plugin_active() ) {

				add_filter( 'the_content', array( __CLASS__, 'the_content' ), 100 );
				/*
				* Fix for toc not showing / links not working for StoreHub theme custom post types				
				*/
				add_filter( 'ilj_get_the_content', array( __CLASS__, 'the_content_storehub' ), 100 ); 
				
				if( defined('EASY_TOC_AMP_VERSION') ){
					add_filter( 'ampforwp_modify_the_content', array( __CLASS__, 'the_content' ) );
				}
				add_filter( 'term_description',  array( __CLASS__, 'toc_term_content_filter' ), 99,2);
				add_filter( 'woocommerce_taxonomy_archive_description_raw',  array( __CLASS__, 'toc_category_content_filter_woocommerce' ), 99,2);
				add_shortcode( 'ez-toc', array( __CLASS__, 'shortcode' ) );  
				//This is legacy hook,it will be removed in future versions.  
				$eztoc_shortcode =  apply_filters( 'ez_toc_shortcode', 'toc' ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy hook name.
				//This is the new hook , it should be used instead of the legacy one.
				$eztoc_shortcode =  apply_filters( 'eztoc_shortcode', 'toc' );
				add_shortcode( $eztoc_shortcode, array( __CLASS__, 'shortcode' ) );
				add_shortcode( 'ez-toc-widget-sticky', array( __CLASS__, 'ez_toc_widget_sticky_shortcode' ) );
				add_action( 'wp_footer', array(__CLASS__, 'sticky_toggle_content' ) );
				add_filter( 'wpseo_schema_graph', array( __CLASS__, 'ez_toc_schema_sitenav_yoast_compat'), 10, 1 );
				add_filter( 'get_the_archive_description', array( __CLASS__, 'toc_get_the_archive_description' ), 10,1);
				/*
				* Fix for toc not links not working if the page template created with SeedProd Pro builder & beaver builder	
				*/				
				if ( ezTOC_Option::get( 'seedprod-pro' ) || ezTOC_Option::get( 'beaver-builder' ) ) {				    
				    add_action( 'template_redirect', array( __CLASS__, 'ez_toc_buffer_start' ), 1 );				    
				    remove_filter( 'the_content', array( __CLASS__, 'the_content' ), 100 );
				}				

			}

		}		
	
		/**
		 * is_sidebar_hastoc function
		 * @since 2.0.51
		 * @static
		 * @return bool
		 */
		public static function is_sidebar_hastoc() {

			$status = false;

			$generate_toc_link_ids = ezTOC_Option::get('generate_toc_link_ids');
			if($generate_toc_link_ids){
				return true;
			}

			$widget_blocks = get_option( 'widget_block' );
			foreach( (array) $widget_blocks as $widget_block ) {
				if ( ! empty( $widget_block['content'] ) && ( has_shortcode( $widget_block['content'] , 'toc' ) || has_shortcode( $widget_block['content'] , 'ez-toc' ) || has_shortcode( $widget_block['content'] , 'ez-toc-widget-sticky' ) ) ) {					
					$status = true;
					break;
				}
			}
			if(!$status){
				$widget_texts = get_option( 'widget_text' );
				foreach( (array) $widget_texts as $widget_text ) {
					if ( ! empty( $widget_text['text'] ) && ( has_shortcode( $widget_text['text'] , 'toc' ) || has_shortcode( $widget_text['text'] , 'ez-toc' ) || has_shortcode( $widget_text['text'] , 'ez-toc-widget-sticky' ) ) ) {					
						$status = true;						
						break;
					}
				}

			}
			if(!$status){
				$widget_cust_htmls = get_option( 'widget_custom_html' );				
				foreach( (array) $widget_cust_htmls as $widget_cust_html ) {
					if ( ! empty( $widget_cust_html['content'] ) && ( has_shortcode( $widget_cust_html['content'] , 'toc' ) || has_shortcode( $widget_cust_html['content'] , 'ez-toc' ) || has_shortcode( $widget_cust_html['content'] , 'ez-toc-widget-sticky' ) ) ) {					
						$status = true;						
						break;
					}
				}

			}
			//This is legacy hook,it will be removed in future versions.
			$eztoc_sidebar_has_toc_filter =  apply_filters( 'ez_toc_sidebar_has_toc_filter', $status ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy hook name.
			//This is the new hook , it should be used instead of the legacy one.
			$eztoc_sidebar_has_toc_filter =  apply_filters( 'eztoc_sidebar_has_toc_filter', $status );

			return $eztoc_sidebar_has_toc_filter;
		}
                
        /**
	 * enqueue_scripts_for_exclude_css Method
	 * for adding toggle css on loading as CSS
	 * @access public
	 * @since  2.0.40
         * @static
	 */
        public static function enqueue_scripts_for_exclude_css()
        {
			if ( ezTOC_Option::get( 'exclude_css' ) && 'css' == ezTOC_Option::get( 'toc_loading' ) ) {
                                
				$cssChecked = '#ez-toc-container input[type="checkbox"]:checked + nav, #ez-toc-widget-container input[type="checkbox"]:checked + nav {opacity: 0;max-height: 0;border: none;display: none;}';
				wp_register_style( 'eztoc-exclude-toggle-css', false, array(), ezTOC::VERSION );
				wp_enqueue_style( 'eztoc-exclude-toggle-css', false, array(), ezTOC::VERSION );
				wp_add_inline_style( 'eztoc-exclude-toggle-css', $cssChecked );
			}
        }
        
		/**
         * check_beaver_builder_plugin_active Method
         * @since 2.0.34
		 * @return bool
		 */
		private static function check_beaver_builder_plugin_active() {
			//phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason : Nonce verification is not required here.
			if( has_action( 'the_content' ) && isset($_REQUEST['fl_builder'])) {
				return true;
			}
			return false;
		}
		/**
		 * Load the plugin translation.
		 *
		 * Credit: Adapted from Ninja Forms / Easy Digital Downloads.
		 *
		 * @access private
		 * @since  1.0
		 * @static
		 *
		 * @uses   apply_filters()
		 * @uses   get_locale()
		 * @uses   load_textdomain()
		 * @uses   load_plugin_textdomain()
		 *
		 * @return void
		 */
		public static function load_text_domain() {

			// Plugin textdomain. This should match the one set in the plugin header.
			$domain = 'easy-table-of-contents';

			// Set filter for plugin's languages directory
			//This is legacy hook,it will be removed in future versions.
			$languagesDirectory = apply_filters( "ez_{$domain}_languages_directory", EZ_TOC_DIR_NAME . '/languages/' ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy hook name.
			//This is the new hook , it should be used instead of the legacy one.
			$languagesDirectory = apply_filters( "eztoc_{$domain}_languages_directory", EZ_TOC_DIR_NAME . '/languages/' );

			// Traditional WordPress plugin locale filter
			$locale   = apply_filters( 'plugin_locale', get_locale(), $domain ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Using WP Core hook
			$fileName = sprintf( '%1$s-%2$s.mo', $domain, $locale );

			// Setup paths to current locale file
			$local  = $languagesDirectory . $fileName;
			$global = WP_LANG_DIR . "/{$domain}/" . $fileName;

			if ( file_exists( $global ) ) {

				// Look in global `../wp-content/languages/{$domain}/` folder.
				load_textdomain( $domain, $global );

			} elseif ( file_exists( $local ) ) {

				// Look in local `../wp-content/plugins/{plugin-directory}/languages/` folder.
				load_textdomain( $domain, $local );

			} else {

				// Load the default language files
				// phpcs:ignore PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound -- Using for compatibility.
				load_plugin_textdomain( $domain, false, $languagesDirectory );
			}
		}

		public static function ez_toc_inline_sticky_styles() {

			if ( ezTOC_Option::get( 'inline_css' ) ) {

				if ( self::is_enqueue_scripts_sticky_eligible() && function_exists('eztoc_read_file_contents') ) {

					$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';				

					$inline_css  = eztoc_read_file_contents( EZ_TOC_PATH . "/assets/css/ez-toc-sticky{$min}.css" );					
					$inline_css .= self::inline_counting_css( ezTOC_Option::get( 'heading-text-direction', 'ltr' ), 'ez-toc-sticky-toggle-direction', 'ez-toc-sticky-toggle-counter', 'counter', 'ez-toc-sticky-container' );
					$inline_css .= self::inline_sticky_toggle_css();

					wp_register_style( 'eztoc-sticky-style', false, array(), ezTOC::VERSION );
					wp_enqueue_style( 'eztoc-sticky-style', false, array(), ezTOC::VERSION );
					wp_add_inline_style( 'eztoc-sticky-style', $inline_css );

				}
				
			}
		}

		public static function ez_toc_inline_styles() {

			if ( ezTOC_Option::get( 'inline_css' ) ) {

				if ( self::is_enqueue_scripts_eligible() && function_exists('eztoc_read_file_contents') ) {

					$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';

					$inline_css  = eztoc_read_file_contents( EZ_TOC_PATH . "/assets/css/screen{$min}.css" );
					$inline_css .= self::inline_counting_css( ezTOC_Option::get( 'heading-text-direction', 'ltr' ) );
					$inline_css .= self::inline_counting_css( ezTOC_Option::get( 'heading-text-direction', 'ltr' ),'ez-toc-widget-direction','ez-toc-widget-container', 'counter', 'ez-toc-widget-container' );
					$inline_css .= self::inline_css();

					wp_register_style( 'eztoc-style', false, array(), ezTOC::VERSION );
					wp_enqueue_style( 'eztoc-style', false, array(), ezTOC::VERSION );
					wp_add_inline_style( 'eztoc-style', $inline_css );

				}
				
			}
		}

		public static function ez_toc_schema_sitenav_creator() {

			global $eztoc_disable_the_content;
			if ( ezTOC_Option::get( 'schema_sitenav_checkbox' ) == true  &&  ! ezTOC_Option::get( 'schema_sitenav_yoast_compat' , false ) ) {
				if ( ( self::is_enqueue_scripts_eligible() || self::is_enqueue_scripts_sticky_eligible() ) ) {

					$eztoc_disable_the_content = true;

					$post = ezTOC::get( get_the_ID() );

					if ( $post ) {

						$items = $post->getTocTitleId();

						if ( ! empty( $items ) ) {

							$output_array = array();

							foreach ( $items as $item ) {

								$output_array[] = array(
									"@context" => "https://schema.org",
									"@type"    => "SiteNavigationElement",
									'@id'      => '#ez-toc',
									"name"     => wp_strip_all_tags( $item['title'] ),
									"url"      => get_permalink() ."#". $item['id'],
								);

							}
							
							if ( ! empty($output_array) ) {

								$schema_opt = array();	
								$schema_opt['@context'] = "https://schema.org"; 
								$schema_opt['@graph']   = $output_array; 
								echo '<script type="application/ld+json" class="ez-toc-schema-markup-output">';
								echo wp_json_encode( $schema_opt );
								echo '</script>';

							}
							
						}
					}	
				}
										
			}			
		}

		public static function ez_toc_schema_sitenav_yoast_compat( $graph ) {
		
			// Check if the TOC schema is enabled in your plugin options.
			if ( ! ezTOC_Option::get( 'schema_sitenav_checkbox' ) || ! ezTOC_Option::get( 'schema_sitenav_yoast_compat', false ) ) {
				return $graph;
			}
			if ( ( !self::is_enqueue_scripts_eligible() && !self::is_enqueue_scripts_sticky_eligible() ) ) {
				return $graph;
			}

			// Get the TOC for the current post.
			$post = ezTOC::get( get_the_ID() );
			if ( ! $post ) {
				return $graph;
			}

			$items = $post->getTocTitleId();
			if ( empty( $items ) ) {
				return $graph;
			}

			  foreach ( $graph as &$piece ) {
				if ( isset( $piece['@type'] ) ) {
					
						$position = 1;
					 // Create the top-level TOC as a SiteNavigationElement
					 $top_level_navigation = [
						'@type' => 'SiteNavigationElement',
						'name'  => 'Table of Contents',
						'url'   => get_permalink() . '#ez-toc',
						'position' => $position,
						'hasPart' => []
					];
					// Add TOC items as child elements (nested if necessary)
					foreach ( $items as $item ) {
						$position++;
						// Check if this item has nested sub-items (e.g., subsections)
						if ( isset( $item['subitems'] ) && ! empty( $item['subitems'] ) ) {
							$top_level_navigation['hasPart'][] = [
								'@type' => 'SiteNavigationElement',
								'name'  => wp_strip_all_tags( $item['title'] ),
								'url'   => get_permalink() . '#' . $item['id'],
								'position' => $position,
								'hasPart' => array_map( function( $sub_item ) use ( &$position ) {
									return [
										'@type' => 'SiteNavigationElement',
										'name'  => wp_strip_all_tags( $sub_item['title'] ),
										'url'   => get_permalink() . '#' . $sub_item['id'],
										'position' => $position, 
									];
								}, $item['subitems'] )
							];
						} else {
							// If no sub-items, just add the main TOC item
							$top_level_navigation['hasPart'][] = [
								'@type' => 'SiteNavigationElement',
								'name'  => wp_strip_all_tags( $item['title'] ),
								'url'   => get_permalink() . '#' . $item['id'],
								'position' => $position, 
							];
						}
					}
	
					// Add the full navigation structure to the WebPage schema
					$piece['hasPart'][] = $top_level_navigation;
					break;
				}
			}

			return $graph;
		}

		
		/**
		 * Call back for the `wp_enqueue_scripts` action.
		 *
		 * Register and enqueue CSS and javascript files for frontend.
		 *
		 * @access private
		 * @since  1.0
		 * @static
		 */
		public static function enqueue_scripts() {

				$eztoc_post_id = get_the_ID();								
				// If SCRIPT_DEBUG is set and TRUE load the non-minified JS files, otherwise, load the minified files.
				$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';				

				if ( eztoc_is_plugin_active( 'js_composer_salient/js_composer.php') ) {					
					$postMetaContent = get_post_meta( $eztoc_post_id, '_nectar_portfolio_extra_content',true );
					if( !empty( $postMetaContent ) ){
						update_option( 'ez-toc-post-meta-content', array( $eztoc_post_id => do_shortcode( $postMetaContent ) ) );
					}
				}
									
				// Register stylesheet which can be called later using wp_enqueue_style() 
				wp_register_style( 'eztoc', EZ_TOC_URL . "assets/css/screen{$min}.css",array( ), ezTOC::VERSION );
				wp_register_style( 'eztoc-sticky', EZ_TOC_URL . "assets/css/ez-toc-sticky{$min}.css", array(), self::VERSION );

				// Register scripts which can be called later using wp_enqueue_script() 																																
				$in_footer = true;
				if ( ezTOC_Option::get( 'load_js_in' ) == 'header' ) {
					$in_footer = false;
				}
				wp_register_script( 'eztoc-sticky', EZ_TOC_URL . "assets/js/ez-toc-sticky{$min}.js", array( 'jquery'), ezTOC::VERSION . '-' . filemtime( EZ_TOC_PATH . "/assets/js/ez-toc-sticky{$min}.js" ), $in_footer );				
				wp_register_script( 'eztoc-js-cookie', EZ_TOC_URL . "vendor/js-cookie/js.cookie{$min}.js", array(), '2.2.1', $in_footer );
				wp_register_script( 'eztoc-jquery-sticky-kit', EZ_TOC_URL . "vendor/sticky-kit/jquery.sticky-kit{$min}.js", array( 'jquery' ), '1.9.2', $in_footer );                        			
				wp_register_script( 'eztoc-js', EZ_TOC_URL . "assets/js/front{$min}.js", array( 'jquery', 'eztoc-js-cookie', 'eztoc-jquery-sticky-kit' ), ezTOC::VERSION . '-' . filemtime( EZ_TOC_PATH . "/assets/js/front{$min}.js" ), $in_footer );
				//This is legacy hook,it will be removed in future versions.
				$eztoc_smscroll_jsfile_filter =  apply_filters('ez_toc_smscroll_jsfile_filter',EZ_TOC_URL . "assets/js/smooth_scroll{$min}.js"); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy hook name.
				//This is the new hook , it should be used instead of the legacy one.
				$eztoc_smscroll_jsfile_filter =  apply_filters('eztoc_smscroll_jsfile_filter',EZ_TOC_URL . "assets/js/smooth_scroll{$min}.js");
				wp_register_script( 'eztoc-scroll-scriptjs', $eztoc_smscroll_jsfile_filter, array( 'jquery' ), ezTOC::VERSION, $in_footer );
				wp_register_script( 'eztoc-elementor-anchor-fix', EZ_TOC_URL . 'assets/js/elementor-toc-anchor-fix.js', array(), ezTOC::VERSION, $in_footer );
				self::localize_scripts();
																													
				if ( self::is_enqueue_scripts_eligible() ) {
					if ( eztoc_is_plugin_active( 'elementor/elementor.php' ) ) {
						wp_enqueue_script( 'eztoc-elementor-anchor-fix' );
					}
					self::enqueue_registered_script();	
					self::enqueue_registered_style();	
					self::inline_main_counting_css();
					if ( eztoc_is_plugin_active( 'js_composer/js_composer.php') ) {
						self::inline_wp_bakery_js();
					}												
				}											
				
				if ( self::is_enqueue_scripts_sticky_eligible() ){
					self::enqueue_registered_sticky_script();
					self::enqueue_registered_sticky_style();
					self::inline_main_counting_sticky_css();					
				}
				
				$eztoc_current_theme = wp_get_theme();

				/**
				 * Foodie Pro Theme Compatibility
				 * for working sticky toggle
				 * in right way
				 * @since 2.0.39
				 */
				if ( 'Foodie Pro' == $eztoc_current_theme->get( 'Name' ) ) {

					wp_register_style( 'eztoc-foodie-pro', EZ_TOC_URL . "assets/css/foodie-pro{$min}.css",array(), ezTOC::VERSION );
					wp_enqueue_style( 'eztoc-foodie-pro' );

				}

				/**
				 * Thrive Theme Builder Compatibility
				 * add inline custom CSS to remove double line
				 * on links of our Easy TOC container
				 * @since 2.0.38
				 */
				if ( 'Thrive Theme Builder' == $eztoc_current_theme->get( 'Name' ) ) {

					wp_register_style( 'eztoc-thrive-theme-builder', EZ_TOC_URL . "assets/css/thrive-theme-builder{$min}.css",array(), ezTOC::VERSION );
					wp_enqueue_style( 'eztoc-thrive-theme-builder' );

				}
				
		}
		
		/**
         * localize_scripts Method
         * Localize scripts
         *
         * @since  2.0.52
         * @static
         * @uses wp_localize_script()
         * @return void
         *
         */
		public static function localize_scripts(){
				global $eztoc_shortcode_attr;				
			    $eztoc_post_id = get_the_ID();
				$js_vars = array();
				$eztoc_current_theme = wp_get_theme();
				if ( ezTOC_Option::get( 'smooth_scroll' ) ) {
					$js_vars['smooth_scroll'] = true;
				}else{
					$js_vars['smooth_scroll'] = false;
				}

				if ( ezTOC_Option::get( 'show_heading_text' ) && ezTOC_Option::get( 'visibility' ) ) {

					$width = ezTOC_Option::get( 'width' ) !== 'custom'
						? ezTOC_Option::get( 'width' )
						: ( ( ezTOC_Option::get( 'width_custom' ) !== '' )
							? ezTOC_Option::get( 'width_custom' ) . ezTOC_Option::get( 'width_custom_units' )
							: 'auto'
						);
					$js_vars['visibility_hide_by_default'] = ezTOC_Option::get( 'visibility_hide_by_default' ) ? true : false;
                                
					if( true == get_post_meta( $eztoc_post_id, '_ez-toc-visibility_hide_by_default', true ) ){
						$js_vars['visibility_hide_by_default'] = true;
						$js_vars['width'] = esc_js( $width );
					}                
				}else{

					if(ezTOC_Option::get( 'visibility' )){
						$js_vars['visibility_hide_by_default'] = ezTOC_Option::get( 'visibility_hide_by_default' ) ? true : false;
						if( true == get_post_meta( $eztoc_post_id, '_ez-toc-visibility_hide_by_default', true ) ){
							$js_vars['visibility_hide_by_default'] = true;
						}
												
					}
				}

				$offset = wp_is_mobile() ? ezTOC_Option::get( 'mobile_smooth_scroll_offset', 0 ) : ezTOC_Option::get( 'smooth_scroll_offset', 30 );
				$js_vars['scroll_offset'] = esc_js( $offset );

				if ( ezTOC_Option::get( 'widget_affix_selector' ) ) {
					$js_vars['affixSelector'] = ezTOC_Option::get( 'widget_affix_selector' );
				}

				if (ezTOC_Option::get( 'toc_loading' ) != 'css') {
					$icon = ezTOC::get_toc_toggle_icon();
					if( function_exists( 'ez_toc_pro_activation_link' ) ) {
						//This is legacy hook,it will be removed in future versions.
						$icon = apply_filters('ez_toc_modify_icon',$icon); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy hook name.
						//This is the new hook , it should be used instead of the legacy one.
						$icon = apply_filters('eztoc_modify_icon',$icon);
					}
					$js_vars['fallbackIcon'] = $icon;
				}

				if(ezTOC_Option::get( 'collapsable_sub_hd' )){
					$js_vars['collapseSubHd'] = true;
				}

				if(ezTOC_Option::get( 'ajax_load_more' )){
					$js_vars['ajax_toggle'] = true;
				}

				if(isset($eztoc_shortcode_attr['initial_view']) && $eztoc_shortcode_attr['initial_view'] == 'show'){
					$js_vars['visibility_hide_by_default'] = false;
				}

				if(isset($js_vars['visibility_hide_by_default']) && $js_vars['visibility_hide_by_default'] == true){
					$visibility_hide_by_device = ezTOC_Option::get( 'visibility_hide_by_device' ,['mobile','desktop']);
						if( function_exists('wp_is_mobile') &&  wp_is_mobile() ){
							$visiblity = (in_array('mobile', $visibility_hide_by_device)) ? "1" : "0";
						}else{
							$visiblity = (in_array('desktop', $visibility_hide_by_device)) ? "1" : "0";
						}		
					$js_vars['visibility_hide_by_device'] =$visiblity;

				}
				/** 
				 * If Chamomile theme is active then remove hamburger div from content
				 * @since 2.0.53
				 * */
				if ( 'Chamomile' == $eztoc_current_theme->get( 'Name' ) ) {
					$js_vars['chamomile_theme_is_on'] = true;
				}else{
					$js_vars['chamomile_theme_is_on'] = false;
				}
				
				if ( 0 < count( $js_vars ) ) {
					wp_localize_script( 'eztoc-js', 'ezTOC', $js_vars );
					// smooth scroll js localization
					$js_scroll = array();
					$js_scroll['scroll_offset'] = esc_js( $offset );					
					$js_scroll['add_request_uri'] = ezTOC_Option::get( 'add_request_uri' ) ? true : false;
					$js_scroll['add_self_reference_link'] = ezTOC_Option::get( 'add_self_reference_link' ) ? true : false;
					
					if(ezTOC_Option::get( 'smooth_scroll' ) && ezTOC_Option::get( 'avoid_anch_jump' )){
						$js_scroll['JumpJsLinks'] = true;
					}
					wp_localize_script( 'eztoc-scroll-scriptjs', 'eztoc_smooth_local', $js_scroll );						
				}
				//localize sticky js

				if ( ezTOC_Option::get( 'sticky-toggle' ) ) {
					$js_sticky = array();
					$js_sticky['close_on_link_click'] = false;
					if( (( 1 == ezTOC_Option::get('sticky-toggle-close-on-mobile', 0) || '1' == ezTOC_Option::get('sticky-toggle-close-on-mobile', 0) || true == ezTOC_Option::get('sticky-toggle-close-on-mobile', 0) ) && wp_is_mobile()) ||  ( 1 == ezTOC_Option::get('sticky-toggle-close-on-desktop', 0) || '1' == ezTOC_Option::get('sticky-toggle-close-on-desktop', 0) || true == ezTOC_Option::get('sticky-toggle-close-on-desktop', 0) ) ) {
						$js_sticky['close_on_link_click'] = true;
					}
					wp_localize_script( 'eztoc-sticky', 'eztoc_sticky_local', $js_sticky );
				}

		}

		/**
         * enqueue_registered_style_and_script Method
         * Enqueue styles and scripts later after registered
         *
         * @since  2.0.52
         * @static
         * @uses wp_enqueue_style() & wp_enqueue_script()
         * @return void
         *
         */
		public static function enqueue_registered_sticky_style() {
			
			if ( ! ezTOC_Option::get( 'exclude_css' )){
				if ( ! ezTOC_Option::get( 'inline_css' ) ) {
					wp_enqueue_style( 'eztoc-sticky' );
					$css = self::inline_sticky_toggle_css();
					wp_add_inline_style( 'eztoc-sticky', $css );
				}
			}
												
		}
		/**
         * enqueue_registered_style_and_script Method
         * Enqueue styles and scripts later after registered
         *
         * @since  2.0.52
         * @static
         * @uses wp_enqueue_style() & wp_enqueue_script()
         * @return void
         *
         */
		public static function enqueue_registered_style() {
			
			if( ! ezTOC_Option::get( 'exclude_css' ) ) {
				if ( ! ezTOC_Option::get( 'inline_css' ) ) {
					wp_enqueue_style( 'eztoc' );
					$css = self::inline_css();
					wp_add_inline_style( 'eztoc', $css );
				}
			}
												
		}
		/**
         * enqueue_registered_style_and_script Method
         * Enqueue styles and scripts later after registered
         *
         * @since  2.0.52
         * @static
         * @uses wp_enqueue_style() & wp_enqueue_script()
         * @return void
         *
         */
		public static function enqueue_registered_script(){

			if (ezTOC_Option::get( 'toc_loading' ) == 'js') {
					if ( ezTOC_Option::get( 'smooth_scroll' ) ) {
						wp_enqueue_script( 'eztoc-scroll-scriptjs' );
					}					
					wp_enqueue_script( 'eztoc-js' );
			}

		}

		/**
         * enqueue_registered_style_and_script Method
         * Enqueue styles and scripts later after registered
         *
         * @since  2.0.52
         * @static
         * @uses wp_enqueue_style() & wp_enqueue_script()
         * @return void
         *
         */
		public static function enqueue_registered_sticky_script(){

			wp_enqueue_script( 'eztoc-sticky');

		}
                        
        /**
         * inline_wp_bakery_js Method
         * Javascript code for WP Bakery Plugin issue for mobile screen
         *
         * @since  2.0.35
         * @static
         * @uses \wp_add_inline_script()
         * @return void
         *
         * ez-toc-list ez-toc-link
         * ez-toc-section
         */
        private static function inline_wp_bakery_js()
        {
			$sticky_js = '';
        
			if (wp_is_mobile()) {
				$sticky_js = "
					let ezTocStickyContainer = document.querySelector('#ez-toc-sticky-container');
					if (document.querySelectorAll('#ez-toc-sticky-container').length > 0) {
						let ezTocStickyContainerUL = ezTocStickyContainer.querySelectorAll('.ez-toc-link');
						for (let i = 0; i < ezTocStickyContainerUL.length; i++) {
							let anchorHREF = ezTocStickyContainerUL[i].getAttribute('href');
							ezTocStickyContainerUL[i].setAttribute('href', anchorHREF + '-' + uniqID);
						}
					}
				";
			}
	
			$inline_wp_bakery_js = "
				let mobileContainer = document.querySelector('#mobile.vc_row-fluid');
				if (document.querySelectorAll('#mobile.vc_row-fluid').length > 0) {
					let ezTocContainerUL = mobileContainer.querySelectorAll('.ez-toc-link');
					let uniqID = 'xs-sm-' + Math.random().toString(16).slice(2);
					for (let i = 0; i < ezTocContainerUL.length; i++) {
						let anchorHREF = ezTocContainerUL[i].getAttribute('href');
						let section = mobileContainer.querySelector('span.ez-toc-section' + anchorHREF);
						if (section) {
							section.setAttribute('id', anchorHREF.replace('#', '') + '-' + uniqID);
						}
						ezTocContainerUL[i].setAttribute('href', anchorHREF + '-' + uniqID);
					}
					{$sticky_js}
				}
			";
	
			wp_add_inline_script('ez-toc-js', $inline_wp_bakery_js);
        }

		/**
		 * Prints out inline CSS after the core CSS file to allow overriding core styles via options.
		 *
		 * @access private
		 * @since  1.0
		 * @static
		 */
		public static function inline_css() {

			$css = '';
			$eztoc_current_theme = wp_get_theme();
			if('Chamomile' == $eztoc_current_theme->get( 'Name' )){
				$css .= '@media screen and (max-width: 1000px) {
				          #ez-toc-container nav{
				            display: block;        
				          }    
				        }';
			}

			if ( ! ezTOC_Option::get( 'exclude_css' ) ) {

				$css .= 'div#ez-toc-container .ez-toc-title {font-size: ' . esc_attr( ezTOC_Option::get( 'title_font_size', 120 ) ) . esc_attr( ezTOC_Option::get( 'title_font_size_units', '%' ) ) . ';}';
				$css .= 'div#ez-toc-container .ez-toc-title {font-weight: ' . esc_attr( ezTOC_Option::get( 'title_font_weight', 500 ) ) . ';}';
				$css .= 'div#ez-toc-container ul li , div#ez-toc-container ul li a {font-size: ' . esc_attr(ezTOC_Option::get( 'font_size', 95 )) . esc_attr(ezTOC_Option::get( 'font_size_units', '%' )) . ';}';
				$css .= 'div#ez-toc-container ul li , div#ez-toc-container ul li a {font-weight: ' . esc_attr( ezTOC_Option::get( 'font_weight', 500 ) ) . ';}';
				$css .= 'div#ez-toc-container nav ul ul li {font-size: ' . esc_attr( ezTOC_Option::get( 'child_font_size', 90 ) . esc_attr(ezTOC_Option::get( 'child_font_size_units', '%' ) )) . ';}';

				if ( ezTOC_Option::get( 'theme' ) === 'custom' || ezTOC_Option::get( 'width' ) != 'auto' ) {

					$css .= 'div#ez-toc-container {';

					if ( ezTOC_Option::get( 'theme' ) === 'custom' ) {

						$css .= 'background: ' . esc_attr( ezTOC_Option::get( 'custom_background_colour','#f9f9f9' ) ) . ';border: '.esc_attr( ezTOC_Option::get( 'custom_border_size' ,1) ).'px solid ' . esc_attr( ezTOC_Option::get( 'custom_border_colour' ,'#aaa') ) . ';';
					}

					if ( 'auto' !== ezTOC_Option::get( 'width' ) ) {

						$css .= 'width: ';

						if ( 'custom' !== ezTOC_Option::get( 'width' ) ) {

							$css .= ezTOC_Option::get( 'width' );

						} else {

							$css .= ( ezTOC_Option::get( 'width_custom' ) !== '' )
								? ezTOC_Option::get( 'width_custom' ) . ezTOC_Option::get( 'width_custom_units' )
								: 'auto';
						}

						$css .= ';';
					}

					if ( 'custom' === ezTOC_Option::get( 'width' ) && '%' !== ezTOC_Option::get( 'width_custom_units' ) ) {
						$css .= 'max-width: 100%;';
					}

					$css .= '}';
				}

				if ( 'custom' === ezTOC_Option::get( 'theme' ) ) {

					$css .= 'div#ez-toc-container p.ez-toc-title , #ez-toc-container .ez_toc_custom_title_icon , #ez-toc-container .ez_toc_custom_toc_icon {color: ' . esc_attr( ezTOC_Option::get( 'custom_title_colour' ) ) . ';}';
					$css .= 'div#ez-toc-container ul.ez-toc-list a {color: ' . esc_attr( ezTOC_Option::get( 'custom_link_colour' ) ) . ';}';
					$css .= 'div#ez-toc-container ul.ez-toc-list a:hover {color: ' . esc_attr( ezTOC_Option::get( 'custom_link_hover_colour' ) ) . ';}';
					$css .= 'div#ez-toc-container ul.ez-toc-list a:visited {color: ' . esc_attr( ezTOC_Option::get( 'custom_link_visited_colour' ) ) . ';}';
					$css .= '.ez-toc-counter nav ul li a::before {color: ' . esc_attr( ezTOC_Option::get( 'custom_list_prefix_colour' ) ) . ';}';
					
				}

				// List Style Color (works with any theme)
				$list_prefix_colour = ezTOC_Option::get( 'list_prefix_colour', '' );
				if ( ! empty( $list_prefix_colour ) ) {
					$css .= '.ez-toc-counter nav ul li a::before {color: ' . esc_attr( $list_prefix_colour ) . ';}';
				}

				// Box title styling
				$css .= '.ez-toc-box-title {font-weight: bold; margin-bottom: 10px; text-align: center; text-transform: uppercase; letter-spacing: 1px; color: #666; padding-bottom: 5px;position:absolute;top:-4%;left:5%;background-color: inherit;transition: top 0.3s ease;}';
				$css .= '.ez-toc-box-title.toc-closed {top:-25%;}';

				if(ezTOC_Option::get( 'headings-padding' )){
					$css .= self::inline_headings_padding_css();	
				}
                                
			}
			return apply_filters('eztoc_pro_inline_css',$css);
			
		}

		/**
         * inline_main_counting_css Method
         * for adding inlineCounting CSS
         * in wp_head in last
         * @since 2.0.37
         * @return void
        */
        public static function inline_main_counting_sticky_css() {

			if ( ! ezTOC_Option::get( 'exclude_css' )) {
				if ( ! ezTOC_Option::get( 'inline_css' ) ) {
					$css = '';
					$css = self::inline_counting_css( ezTOC_Option::get( 'heading-text-direction', 'ltr' ), 'ez-toc-sticky-toggle-direction', 'ez-toc-sticky-toggle-counter', 'counter', 'ez-toc-sticky-container' ); 
					wp_add_inline_style( 'eztoc-sticky', $css );
				}
			}            	                                               

        }

        /**
         * inline_main_counting_css Method
         * for adding inlineCounting CSS
         * in wp_head in last
         * @since 2.0.37
         * @return void
        */
        public static function inline_main_counting_css() {

			if ( ! ezTOC_Option::get( 'exclude_css' )){
				if ( ! ezTOC_Option::get( 'inline_css' ) ) {
					$css = '';
					$css .= self::inline_counting_css( ezTOC_Option::get( 'heading-text-direction', 'ltr' ) );
					$css .= self::inline_counting_css( ezTOC_Option::get( 'heading-text-direction', 'ltr' ),'ez-toc-widget-direction','ez-toc-widget-container', 'counter', 'ez-toc-widget-container' );            		
					wp_add_inline_style( 'eztoc', $css );
				}
			}
                        
        }

        /**
         * inline_counting_css Method
         * @since 2.0.33
         * @scope private
         * @static
         * @param string $direction
         * @param string $directionClass
         * @param string $class
         * @param string $counter
         * @param string $containerId
         * @return string
        */
		public static function inline_counting_css( $direction = 'ltr', $directionClass = 'ez-toc-container-direction', $class = 'ez-toc-counter',  $counter = 'counter', $containerId = 'ez-toc-container' ) {
			$list_type = ezTOC_Option::get( $counter, 'decimal' );
			if( $list_type != 'none' ) {
				$inline_css = '';
				$counterListAll = array_merge( ezTOC_Option::getCounterListDecimal(), ezTOC_Option::getCounterList_i18n() );
				$listTypesForCounting = array_keys( $counterListAll );
				$inline_css .= ".$directionClass {direction: $direction;}";
		
				$listAnchorPosition = 'before';
				$marginCSS = 'margin-right: .2em;';
				$floatPosition = 'float: left;';
				if( $direction == 'rtl' ) {
					$class .= '-rtl';
					$marginCSS = 'margin-left: .2em;';
					$floatPosition = 'float: right;';
				}
				$eztoc_current_theme = wp_get_theme();
				$importantItem = '';
				if ( 'Edition Child' == $eztoc_current_theme->get( 'Name' ) ) {
					$importantItem = ' !important';
				}
		
				if( in_array( $list_type, $listTypesForCounting ) ) {
					if( $direction == 'rtl' ) {
						$length = 6;
						$counterRTLCSS = self::rtl_counter_reset_css( $length, $class );
						$counterRTLCSS .= self::rtl_counter_increment_css( $length, $class );
						$counterRTLCSS .= self::rtl_counter_content_css( $length, $list_type, $class );
						$inline_css .= $counterRTLCSS;
					}
					if( $direction == 'ltr' ) {
						$counterPositionCSS = "";
						if( 'outside' == ezTOC_Option::get( 'counter-position' ) )
							$counterPositionCSS = "min-width: 22px;width: auto;";
		
						$inline_css .= ".$class ul{counter-reset: item $importantItem;}";
						$inline_css .= ".$class nav ul li a::$listAnchorPosition {content: counters(item, '.', $list_type) '. ';display: inline-block;counter-increment: item;flex-grow: 0;flex-shrink: 0;$marginCSS $floatPosition $counterPositionCSS}";
					}
				} else {
					$content = "  ";
					if( $list_type == 'numeric' || $list_type == 'cjk-earthly-branch' )
						$content = ". ";
		
					$counterPositionCSS = "";
					if( 'outside' == ezTOC_Option::get( 'counter-position' ) ) {
						$counterPositionCSS = "min-width: 15px;width: auto;";
						if( 'square' == $list_type )
							$counterPositionCSS = "min-width: 20px;width: auto;";
						if( 'cjk-earthly-branch' == $list_type  )
							$counterPositionCSS = "min-width: 25px;width: auto;";
					}   
					$counterContent = "counter(item, $list_type) '$content'";
					if( $list_type == '- ' )
						$counterContent = 'counter(item, none) "- "';
		
					$inline_css .= ".$class ul {direction: $direction;counter-reset: item $importantItem;}";
					$inline_css .= ".$class nav ul li a::$listAnchorPosition {content: $counterContent;$marginCSS counter-increment: item;flex-grow: 0;flex-shrink: 0;$floatPosition $counterPositionCSS}";
				}
				return $inline_css;
			}
		}		

        /**
         * rtl_counter_reset_css Method
         * @since 2.0.33
         * @scope private
         * @static
         * @param int $length
         * @param string $class
         * @return string
        */
        private static function rtl_counter_reset_css( $length = 6, $class = 'ez-toc-counter-rtl' )
        {
            if ($length < 6) {
                $length = 6;
            }
            $counterResetCSS = "";
            for ($i = 1; $i <= $length; $i++) {
                $ul = [];
                for ($j = 1; $j <= $i; $j++) {
                    $ul[$j] = "ul";
                }
                $ul = implode(" ", $ul);
                $items = [];
                for ($j = $i; $j <= $length; $j++) {
                    $items[$j] = "item-level$j";
                }
                $items = implode(", ", $items);
                $counterResetCSS .= ".$class $ul {direction: rtl;counter-reset: $items;}";
            }
            return $counterResetCSS;
        }

        /**
         * rtl_counter_increment_css Method
         * @since 2.0.33
         * @scope private
         * @static
         * @param int $length
         * @param string $class
         * @return string
        */
        private static function rtl_counter_increment_css( $length = 6, $class = 'ez-toc-counter-rtl' )
        {
            if ($length < 6) {
                $length = 6;
            }
            $counterIncrementCSS = "";
            for ($i = 1; $i <= $length; $i++) {
                $ul = [];
                for ($j = 1; $j <= $i; $j++) {
                    $ul[$j] = "ul";
                }
                $ul = implode(" ", $ul);
                $item = "item-level$i";
                $counterIncrementCSS .= ".$class $ul li {counter-increment: $item;}";
            }
            return $counterIncrementCSS;
        }

        /**
         * rtl_counter_content_css Method
         * @since 2.0.33
         * @scope private
         * @static
         * @param int $length
         * @param string $list_type
         * @param string $class
         * @return string
        */
        private static function rtl_counter_content_css( $length = 6, $list_type = 'decimal', $class = 'ez-toc-counter-rtl' )
        {
			$counterPositionCSS = "";
			if( 'outside' == ezTOC_Option::get( 'counter-position' ) )
				$counterPositionCSS = "min-width: 22px;width: auto;";
            if ($length < 6) {
                $length = 6;
            }
            $counterContentCSS = "";
            for ($i = 1; $i <= $length; $i++) {
                $ul = [];
                for ($j = 1; $j <= $i; $j++) {
                    $ul[$j] = "ul";
                }
                $ul = implode(" ", $ul);
                $items = [];

                $cnt = $i;
                for ($j = 1; $j <= $i; $j++) {
                    $items[$cnt] = "counter(item-level$cnt, $list_type)";
                    $cnt--;
                }
                $items = implode(' "." ', $items);
                $counterContentCSS .= ".$class nav $ul li a::before {content: $items '. ';float: right;margin-left: 0.2rem;flex-grow: 0;flex-shrink: 0; $counterPositionCSS }";
            }
            return $counterContentCSS;
        }

		/**
         * inline_headings_padding_css Method
         *
         * @since  2.0.48
         * @static
         */
		private static function inline_headings_padding_css() 
		{
			$padding_top = ezTOC_Option::get( 'headings-padding-top' );
			$padding_bottom = ezTOC_Option::get( 'headings-padding-bottom' );
			$padding_left = ezTOC_Option::get( 'headings-padding-left' );
			$padding_right = ezTOC_Option::get( 'headings-padding-right' );
		
			$padding_top = ! empty( $padding_top ) && $padding_top !== '0' ? $padding_top . ezTOC_Option::get( 'headings-padding-top_units' ) : '0';
			$padding_bottom = ! empty( $padding_bottom ) && $padding_bottom !== '0' ? $padding_bottom . ezTOC_Option::get( 'headings-padding-bottom_units' ) : '0';
			$padding_left = ! empty( $padding_left ) && $padding_left !== '0' ? $padding_left . ezTOC_Option::get( 'headings-padding-left_units' ) : '0';
			$padding_right = ! empty( $padding_right ) && $padding_right !== '0' ? $padding_right . ezTOC_Option::get( 'headings-padding-right_units' ) : '0';
		
			return sprintf(
				'ul.ez-toc-list a.ez-toc-link { padding: %s %s %s %s; }',
				esc_attr( $padding_top ),
				esc_attr( $padding_right ),
				esc_attr( $padding_bottom ),
				esc_attr( $padding_left )
			);
		}
		

        /**
         * inline_sticky_toggle_css Method
         * Prints out inline Sticky Toggle CSS after the core CSS file to allow overriding core styles via options.
         *
         * @since  2.0.32
         * @static
         */
        private static function inline_sticky_toggle_css()
        {
            $custom_width = 'width: auto;';
            if (ezTOC_Option::get('sticky-toggle-width') == 'custom' && !empty(ezTOC_Option::get(
                    'sticky-toggle-width-custom'
                ))) {
                $custom_width = 'width: ' . ezTOC_Option::get('sticky-toggle-width-custom') . ezTOC_Option::get( 'sticky-toggle-width-custom_units' ) . ';' . PHP_EOL;
            }
            $custom_height = 'height: 100vh;';
            if (ezTOC_Option::get('sticky-toggle-height') == 'custom' && !empty(ezTOC_Option::get(
                    'sticky-toggle-height-custom'
                ))) {
                $custom_height = 'height: ' . ezTOC_Option::get('sticky-toggle-height-custom') . ezTOC_Option::get( 'sticky-toggle-height-custom_units' ). ';' . PHP_EOL;
            }
            
            $topMarginStickyContainer = '65px';
            if ( ezTOC_Option::get( 'show_heading_text' ) ) {
                $toc_title = ezTOC_Option::get( 'heading_text' );
                if( strlen($toc_title) > 20 ) {
                    $topMarginStickyContainer = '70px';
                }
                if( strlen($toc_title) > 40 ) {
                    $topMarginStickyContainer = '80px';
                }
                if( strlen($toc_title) > 60 ) {
                    $topMarginStickyContainer = '90px';
                }
            }
			
			$stickyToggleAlignTop="8%";
			$stickyToggleAlignChk = ezTOC_Option::get( 'sticky-toggle-alignment' ); 
			if ( !empty($stickyToggleAlignChk) ) {
				
				if($stickyToggleAlignChk  == 'middle'){
					$stickyToggleAlignTop = '45%';
				}
				if($stickyToggleAlignChk  == 'bottom'){
					$stickyToggleAlignTop = '75%';
				}

			}

			$stickyBgColor="#fff";
			$stickyHeadTxtColor="#111";
			$stickyHeadBgColor="#fff";
			$stickyAddlCss="";
			$stickyHeadTxtWeight =600;
			$stickyHeadTxtSize =18;
			
			//This is legacy hook,it will be removed in future versions.
			$stickyAddlCss = apply_filters('ez_toc_sticky_pro_css', $stickyAddlCss ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy hook name.
			//This is the new hook , it should be used instead of the legacy one.
			$stickyAddlCss = apply_filters('eztoc_sticky_pro_css', $stickyAddlCss );

            $inline_sticky_css = ".ez-toc-sticky-fixed{position: fixed;top: 0;left: 0;z-index: 999999;width: auto;max-width: 100%;} .ez-toc-sticky-fixed .ez-toc-sidebar {position: relative;top: auto;{$custom_width};box-shadow: 1px 1px 10px 3px rgb(0 0 0 / 20%);box-sizing: border-box;padding: 20px 30px;background: {$stickyBgColor};margin-left: 0 !important; {$custom_height} overflow-y: auto;overflow-x: hidden;} .ez-toc-sticky-fixed .ez-toc-sidebar #ez-toc-sticky-container { padding: 0px;border: none;margin-bottom: 0;margin-top: {$topMarginStickyContainer};} #ez-toc-sticky-container a { color: #000;} .ez-toc-sticky-fixed .ez-toc-sidebar .ez-toc-sticky-title-container {border-bottom-color: #EEEEEE;background-color: {$stickyHeadBgColor};padding:15px;border-bottom: 1px solid #e5e5e5;width: 100%;position: absolute;height: auto;top: 0;left: 0;z-index: 99999999;} .ez-toc-sticky-fixed .ez-toc-sidebar .ez-toc-sticky-title-container .ez-toc-sticky-title {font-weight: {$stickyHeadTxtWeight};font-size: {$stickyHeadTxtSize}px;color: {$stickyHeadTxtColor};} .ez-toc-sticky-fixed .ez-toc-close-icon {-webkit-appearance: none;padding: 0;cursor: pointer;background: 0 0;border: 0;float: right;font-size: 30px;font-weight: 600;line-height: 1;position: relative;color: {$stickyHeadTxtColor};top: -2px;text-decoration: none;} .ez-toc-open-icon {position: fixed;left: 0px;top:{$stickyToggleAlignTop};text-decoration: none;font-weight: bold;padding: 5px 10px 15px 10px;box-shadow: 1px -5px 10px 5px rgb(0 0 0 / 10%);background-color: {$stickyHeadBgColor};color:{$stickyHeadTxtColor};display: inline-grid;line-height: 1.4;border-radius: 0px 10px 10px 0px;z-index: 999999;} .ez-toc-sticky-fixed.hide {-webkit-transition: opacity 0.3s linear, left 0.3s cubic-bezier(0.4, 0, 1, 1);-ms-transition: opacity 0.3s linear, left 0.3s cubic-bezier(0.4, 0, 1, 1);-o-transition: opacity 0.3s linear, left 0.3s cubic-bezier(0.4, 0, 1, 1);transition: opacity 0.3s linear, left 0.3s cubic-bezier(0.4, 0, 1, 1);left: -100%;} .ez-toc-sticky-fixed.show {-webkit-transition: left 0.3s linear, left 0.3s easy-out;-moz-transition: left 0.3s linear;-o-transition: left 0.3s linear;transition: left 0.3s linear;left: 0;} .ez-toc-open-icon span.arrow { font-size: 18px; } .ez-toc-open-icon span.text {font-size: 13px;writing-mode: vertical-rl;text-orientation: mixed;} @media screen  and (max-device-width: 640px) {.ez-toc-sticky-fixed .ez-toc-sidebar {min-width: auto;} .ez-toc-sticky-fixed .ez-toc-sidebar.show { padding-top: 35px; } .ez-toc-sticky-fixed .ez-toc-sidebar #ez-toc-sticky-container { min-width: 100%; } }{$stickyAddlCss}";
			
			if( 'right' == ezTOC_Option::get( 'sticky-toggle-position', 'left') ) {
				$inline_sticky_css = ".ez-toc-sticky-fixed { position: fixed;top: 0;right: 0;z-index: 999999;width: auto;max-width: 100%;} .ez-toc-sticky-fixed .ez-toc-sidebar { position: relative;top: auto;width: auto !important;height: 100%;box-shadow: 1px 1px 10px 3px rgb(0 0 0 / 20%);box-sizing: border-box;padding: 20px 30px;background: {$stickyBgColor};margin-left: 0 !important;height: auto;overflow-y: auto;overflow-x: hidden; {$custom_height} } .ez-toc-sticky-fixed .ez-toc-sidebar #ez-toc-sticky-container { {$custom_width};padding: 0px;border: none;margin-bottom: 0;margin-top: {$topMarginStickyContainer};} #ez-toc-sticky-container a { color: #000; } .ez-toc-sticky-fixed .ez-toc-sidebar .ez-toc-sticky-title-container {border-bottom-color: #EEEEEE;background-color: {$stickyHeadBgColor};padding:15px;border-bottom: 1px solid #e5e5e5;width: 100%;position: absolute;height: auto;top: 0;left: 0;z-index: 99999999;} .ez-toc-sticky-fixed .ez-toc-sidebar .ez-toc-sticky-title-container .ez-toc-sticky-title { font-weight: {$stickyHeadTxtWeight}; font-size: {$stickyHeadTxtSize}px; color: {$stickyHeadTxtColor}; } .ez-toc-sticky-fixed .ez-toc-close-icon{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0;float:right;font-size:30px;font-weight:600;line-height:1;position:relative;color:{$stickyHeadTxtColor};top:-2px;text-decoration:none}.ez-toc-open-icon{position:fixed;right:0;top:{$stickyToggleAlignTop};text-decoration:none;font-weight:700;padding:5px 10px 15px;box-shadow:1px -5px 10px 5px rgb(0 0 0 / 10%);background-color:{$stickyHeadBgColor};color:{$stickyHeadTxtColor};display:inline-grid;line-height:1.4;border-radius:10px 0 0 10px;z-index:999999}.ez-toc-sticky-fixed.hide{-webkit-transition:opacity .3s linear,right .3s cubic-bezier(.4, 0, 1, 1);-ms-transition:opacity .3s linear,right .3s cubic-bezier(.4, 0, 1, 1);-o-transition:opacity .3s linear,right .3s cubic-bezier(.4, 0, 1, 1);transition:opacity .3s linear,right .3s cubic-bezier(.4, 0, 1, 1);right:-100%}.ez-toc-sticky-fixed.show{-moz-transition:right .3s linear;-o-transition:right .3s linear;transition:right .3s linear;right:0}.ez-toc-open-icon span.arrow{font-size:18px}.ez-toc-open-icon span.text{font-size:13px;writing-mode:vertical-lr;text-orientation:mixed;-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}@media screen and (max-device-width:640px){.ez-toc-sticky-fixed .ez-toc-sidebar{min-width:auto}.ez-toc-sticky-fixed .ez-toc-sidebar.show{padding-top:35px}.ez-toc-sticky-fixed .ez-toc-sidebar #ez-toc-sticky-container{min-width:100%}}{$stickyAddlCss}";
			}
			
			return $inline_sticky_css;
		}
				
		public static function is_enqueue_scripts_sticky_eligible() {

			return eztoc_stikcy_enable_support_status();

		}
		public static function is_enqueue_scripts_eligible() {

			$isEligible = self::is_eligible( get_post() );

			if($isEligible){
				if(!eztoc_auto_device_target_status()){
					$isEligible = false;
				}
			}

			if(!$isEligible){
				if( self::is_sidebar_hastoc() || is_active_widget( false, false, 'ezw_tco' ) || is_active_widget( false, false, 'ez_toc_widget_sticky' ) || get_post_meta( get_the_ID(), '_nectar_portfolio_extra_content',true )){
					$isEligible = true;
				}
			}

			return $isEligible;
		}
		/**
		 * Returns true if the table of contents is eligible to be printed, false otherwise.
		 *
		 * NOTE: Must bve use only within the loop.
		 *
		 * @access public
		 * @since  1.0
		 * @static
		 *
		 * @param WP_Post $post
		 *
		 * @return bool
		 */
		public static function is_eligible( $post ) {
			
			if ( empty( $post ) || ! $post instanceof WP_Post ) {

				Debug::log( 'not_instance_of_post', 'Not an instance if `WP_Post`.', $post );
				return false;
			}
                        
			/**
			 * Easy TOC Run On Amp Pages Check
			 * @since 2.0.46
			 */
			if ( ( ezTOC_Option::get( 'toc-run-on-amp-pages', 1 ) !== false && 0 == ezTOC_Option::get( 'toc-run-on-amp-pages', 1 ) || '0' == ezTOC_Option::get( 'toc-run-on-amp-pages', 1 ) || false == ezTOC_Option::get( 'toc-run-on-amp-pages', 1 ) ) && !eztoc_non_amp() ) {
				Debug::log( 'non_amp', 'Is frontpage, TOC is not enabled.', false );
				return false;                            
			}

			/**
			 * New Restriction
			 * @since 2.0.59
			 */
			if( ezTOC_Option::get( 'restrict_url_text' ) && ezTOC_Option::get( 'restrict_url_text' ) != '' ){
				$all_urls = nl2br(ezTOC_Option::get( 'restrict_url_text' ));
				$all_urls = str_replace('<br />', '', $all_urls);
				$urls_arr = explode(PHP_EOL, $all_urls);
				if(is_array($urls_arr)){
					foreach ($urls_arr as $url_arr) {
						if ( isset($_SERVER['REQUEST_URI']) && false !== strpos( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), trim($url_arr) ) ) {
							Debug::log( 'is_restricted_path', 'In restricted path, post not eligible.', ezTOC_Option::get( 'restrict_path' ) );
							return false;
						}
					}
				}
			}
			//This is legacy hook,it will be removed in future versions.
			$eztoc_shortcode = apply_filters( 'ez_toc_shortcode', 'toc' ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy hook name.
			//This is the new hook , it should be used instead of the legacy one.
			$eztoc_shortcode = apply_filters( 'eztoc_shortcode', 'toc' );			
			if ( has_shortcode( $post->post_content, $eztoc_shortcode ) || has_shortcode( $post->post_content, 'ez-toc' ) ) {
				Debug::log( 'has_ez_toc_shortcode', 'Has instance of shortcode.', true );
				return true;
			}
                        
			if ( is_front_page() && ! ezTOC_Option::get( 'include_homepage' ) ) {
				Debug::log( 'is_front_page', 'Is frontpage, TOC is not enabled.', false );
				return false;
			}

			$type = get_post_type( $post->ID );

			Debug::log( 'current_post_type', 'Post type is.', $type );

			$enabled = in_array( $type, ezTOC_Option::get( 'enabled_post_types', array() ), true );
			$insert  = in_array( $type, ezTOC_Option::get( 'auto_insert_post_types', array() ), true );

			$is_product_category_enabled = ezTOC_Option::get( 'include_product_category', false );
			if( $is_product_category_enabled && function_exists('is_product_category') && is_product_category() ){
				$insert = true;
			}

			Debug::log( 'is_supported_post_type', 'Is supported post type?', $enabled );
			Debug::log( 'is_auto_insert_post_type', 'Is auto insert for post types?', $insert );

			if ( $insert || $enabled ) {

				if ( ezTOC_Option::get( 'restrict_path' ) ) {

					/**
					 * @link https://wordpress.org/support/topic/restrict-path-logic-does-not-work-correctly?
					 */
					if ( isset($_SERVER['REQUEST_URI']) && false !== strpos( ezTOC_Option::get( 'restrict_path' ), sanitize_text_field(wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ) {

						Debug::log( 'is_restricted_path', 'In restricted path, post not eligible.', ezTOC_Option::get( 'restrict_path' ) );
						return false;

					} else {

						Debug::log( 'is_not_restricted_path', 'Not in restricted path, post is eligible.', ezTOC_Option::get( 'restrict_path' ) );
						return true;
					}

				} else {

					if ( $insert && 1 === (int) get_post_meta( $post->ID, '_ez-toc-disabled', true ) ) {

						Debug::log( 'is_auto_insert_disable_post_meta', 'Auto insert enabled and disable TOC is enabled in post meta.', false );
						return false;

					} elseif ( $insert && 0 === (int) get_post_meta( $post->ID, '_ez-toc-disabled', true ) ) {

						Debug::log( 'is_auto_insert_enabled_post_meta', 'Auto insert enabled and disable TOC is not enabled in post meta.', true );
						return true;

					} elseif ( $enabled && 1 === (int) get_post_meta( $post->ID, '_ez-toc-insert', true ) ) {

						Debug::log( 'is_supported_post_type_disable_insert_post_meta', 'Supported post type and insert TOC is enabled in post meta.', true );
						return true;

					} elseif ( $enabled && $insert ) {

						Debug::log( 'supported_post_type_and_auto_insert', 'Supported post type and auto insert TOC is enabled.', true );
						return true;
					}

					Debug::log( 'not_auto_insert_or_not_supported_post_type', 'Not supported post type or insert TOC is disabled.', false );
					return false;
				}

			} else {

				Debug::log( 'not_auto_insert_and_not_supported post_type', 'Not supported post type and do not auto insert TOC.', false );
				return false;
			}
		}

		/**
		 * Get TOC from store and if not in store process post and add it to the store.
		 *
		 * @since 2.0
		 *
		 * @param int $id
		 *
		 * @return ezTOC_Post|null
		 */
		public static function get( $id ) {

			$post = null;

			if ( isset( self::$store[ $id ] ) && self::$store[ $id ] instanceof ezTOC_Post && !eztoc_is_plugin_active( 'js_composer_salient/js_composer.php' ) ) {

				$post = self::$store[ $id ];
			} else {
				
				$post_id = ! empty( $id ) ? $id : get_the_ID();
				$post = ezTOC_Post::get( $post_id );

				if ( $post instanceof ezTOC_Post ) {

					self::$store[ $id ] = $post;
				}
			}

			return $post;
		}

		/**
		 * Sanitize a CSS color value for safe output in `<style>` context.
		 *
		 * Allows: hex colors, rgb()/rgba(), hsl()/hsla(), `var(--token)`,
		 * and a small set of CSS keywords.
		 *
		 * @since 2.0.83
		 *
		 * @param mixed $value
		 * @return string
		 */
		public static function sanitize_css_color( $value ) {
			if ( ! is_string( $value ) ) {
				return '';
			}

			$value = trim( $value );
			if ( '' === $value ) {
				return '';
			}

			$keywords = array(
				'transparent',
				'currentcolor',
				'inherit',
				'initial',
				'unset',
				'revert',
				'revert-layer',
			);
			if ( in_array( strtolower( $value ), $keywords, true ) ) {
				return $value;
			}

			$hex = sanitize_hex_color( $value );
			if ( ! empty( $hex ) ) {
				return $hex;
			}

			if ( preg_match( '/^var\\(--[A-Za-z0-9_-]+\\)$/', $value ) ) {
				return $value;
			}

			// rgb() / rgba()
			if ( preg_match( '/^rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})(?:\\s*,\\s*(0|1|0?\\.\\d+)\\s*)?\\)$/', $value, $m ) ) {
				$r = (int) $m[1];
				$g = (int) $m[2];
				$b = (int) $m[3];
				if ( $r >= 0 && $r <= 255 && $g >= 0 && $g <= 255 && $b >= 0 && $b <= 255 ) {
					return $value;
				}
			}

			// hsl() / hsla()
			if ( preg_match( '/^hsla?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})%\\s*,\\s*(\\d{1,3})%(?:\\s*,\\s*(0|1|0?\\.\\d+)\\s*)?\\)$/', $value, $m ) ) {
				$h = (int) $m[1];
				$s = (int) $m[2];
				$l = (int) $m[3];
				if ( $h >= 0 && $h <= 360 && $s >= 0 && $s <= 100 && $l >= 0 && $l <= 100 ) {
					return $value;
				}
			}

			return '';
		}

		/**
		 * Sanitize a CSS length unit for safe concatenation.
		 *
		 * @since 2.0.83
		 *
		 * @param mixed  $unit
		 * @param array  $allowed
		 * @param string $default
		 * @return string
		 */
		public static function sanitize_css_unit( $unit, array $allowed, $default ) {
			if ( ! is_string( $unit ) ) {
				return $default;
			}
			$unit = trim( $unit );
			return in_array( $unit, $allowed, true ) ? $unit : $default;
		}

		/**
		 * Sanitize a CSS font-weight.
		 *
		 * @since 2.0.83
		 *
		 * @param mixed $value
		 * @param string $default
		 * @return string
		 */
		private static function sanitize_css_font_weight( $value, $default = '' ) {
			if ( ! is_string( $value ) ) {
				return $default;
			}
			$value = trim( $value );
			if ( '' === $value ) {
				return $default;
			}

			$lower = strtolower( $value );
			if ( in_array( $lower, array( 'normal', 'bold', 'bolder', 'lighter', 'inherit', 'initial', 'unset', 'revert' ), true ) ) {
				return $value;
			}

			if ( preg_match( '/^(100|200|300|400|500|600|700|800|900)$/', $value ) ) {
				return $value;
			}

			return $default;
		}

        /**
         * Callback for the registered shortcode `[ez-toc-widget-sticky]`
         *
         * NOTE: Shortcode is run before the callback @see ezTOC::the_content() for the `the_content` filter
         *
         * @access private
         * @since  2.0.41
         *
         * @param array|string $atts    Shortcode attributes array or empty string.
         * @param string       $content The enclosed content (if the shortcode is used in its enclosing form)
         * @param string       $tag     Shortcode name.
         *
         * @return string
         */
        public static function ez_toc_widget_sticky_shortcode( $atts, $content, $tag ) {
			             
			global $wp_widget_factory;

            if ( 'ez-toc-widget-sticky' == $tag ) {
    
                // Check which attributes were actually provided before shortcode_atts sets defaults
                $has_title = isset( $atts['title'] );
                $has_title_font_size = isset( $atts['title_font_size'] );
                $has_title_font_size_unit = isset( $atts['title_font_size_unit'] );
                $has_title_font_weight = isset( $atts['title_font_weight'] );
                $has_title_font_color = isset( $atts['title_font_color'] );
                $has_text_font_size = isset( $atts['text_font_size'] );
                $has_text_font_size_unit = isset( $atts['text_font_size_unit'] );
                $has_text_font_weight = isset( $atts['text_font_weight'] );
                $has_text_font_color = isset( $atts['text_font_color'] );
                $has_scroll_fixed_position = isset( $atts['scroll_fixed_position'] );
                $has_toc_background_color = isset( $atts['toc_background_color'] );
                $has_toc_title_background_color = isset( $atts['toc_title_background_color'] );
                
                extract( shortcode_atts( array(
                    'highlight_color' => '#ededed',
                    'title' => 'Table of Contents',
                    'advanced_options' => '',
                    'scroll_fixed_position' => 30,
                    'sidebar_width' => 'auto',
                    'sidebar_width_size_unit' => 'none',
                    'fixed_top_position' => 30,
                    'fixed_top_position_size_unit' => 'px',
                    'navigation_scroll_bar' => 'on',
                    'scroll_max_height' => 'auto',
                    'scroll_max_height_size_unit' => 'none',
					'title_font_size' => '120',
					'title_font_size_unit' => '%',
					'title_font_weight' => '600',
					'title_font_color' => '',
					'text_font_size' => '100',
					'text_font_size_unit' => '%',
					'text_font_weight' => '400',
					'text_font_color' => '',
                    'toc_background_color' => '',
                    'toc_title_background_color' => '',
                    'ez_toc_widget_sticky_before_widget_container' => '',
                    'ez_toc_widget_sticky_before_widget' => '',
                    'ez_toc_widget_sticky_before' => '',
                    'ez_toc_widget_sticky_after' => '',
                    'ez_toc_widget_sticky_after_widget' => '',
                    'ez_toc_widget_sticky_after_widget_container' => '',
					'show_toggle'=> 'true',
					'device_target'=> ''
                ), $atts ) );

				// Sanitize shortcode attributes that are used in `<style>` context.
				$title_font_color = self::sanitize_css_color( $title_font_color );
				$text_font_color  = self::sanitize_css_color( $text_font_color );
				$highlight_color   = self::sanitize_css_color( $highlight_color );
				$toc_background_color = self::sanitize_css_color( $toc_background_color );
				$toc_title_background_color = self::sanitize_css_color( $toc_title_background_color );

				$title_font_size_unit = self::sanitize_css_unit( $title_font_size_unit, array( '%', 'px', 'pt', 'em', 'rem', 'vw', 'vh' ), '%' );
				$text_font_size_unit  = self::sanitize_css_unit( $text_font_size_unit, array( '%', 'px', 'pt', 'em', 'rem', 'vw', 'vh' ), '%' );

				$title_font_weight = self::sanitize_css_font_weight( $title_font_weight, '600' );
				$text_font_weight  = self::sanitize_css_font_weight( $text_font_weight, '400' );

                $widget_name = esc_html( 'ezTOC_WidgetSticky' );
                
                $instance = array(
                    'title' => ( $has_title && ! empty ( $title ) ) ? $title : ezTOC_Option::get( 'heading_text', 'Table of Contents' ),
					'sidebar_sticky_title' => ( $has_title && ! empty ( $title ) ) ? $title : ezTOC_Option::get( 'heading_text', 'Table of Contents' ),
                    'highlight_color' => ( ! empty ( $highlight_color ) ) ? $highlight_color : '#ededed',
                    'advanced_options' => ( ! empty ( $advanced_options ) ) ? $advanced_options : '',
                    'scroll_fixed_position' => ( $has_scroll_fixed_position && ! empty ( $scroll_fixed_position ) ) ? ( int ) $scroll_fixed_position : (int) ezTOC_Option::get( 'smooth_scroll_offset', 30 ),
                    'sidebar_width' => ( ! empty ( $sidebar_width ) ) ? ( 'auto' == $sidebar_width ) ? $sidebar_width : ( int ) wp_strip_all_tags ( $sidebar_width ) : 'auto',
                    'sidebar_width_size_unit' => ( ! empty ( $sidebar_width_size_unit ) ) ? $sidebar_width_size_unit : 'none',
                    'fixed_top_position' => ( ! empty ( $fixed_top_position ) ) ? ( 'auto' == $fixed_top_position ) ? $fixed_top_position : ( int ) wp_strip_all_tags ( $fixed_top_position ) : 30,
                    'fixed_top_position_size_unit' => ( ! empty ( $fixed_top_position_size_unit ) ) ? $fixed_top_position_size_unit : 'px',
                    'navigation_scroll_bar' => ( ! empty ( $navigation_scroll_bar ) ) ? $navigation_scroll_bar : 'on',
                    'scroll_max_height' => ( ! empty ( $scroll_max_height ) ) ? ( 'auto' == $scroll_max_height ) ? $scroll_max_height : ( int ) wp_strip_all_tags ( $scroll_max_height ) : 'auto',
                    'scroll_max_height_size_unit' => ( ! empty ( $scroll_max_height_size_unit ) ) ? $scroll_max_height_size_unit : 'none',
					'sidebar_sticky_title_size' => ( $has_title_font_size && ! empty ( $title_font_size ) ) ? ( 'auto' == $title_font_size ) ? $title_font_size : ( int ) wp_strip_all_tags ( $title_font_size ) : (int) ezTOC_Option::get( 'title_font_size', 120 ),
					'sidebar_sticky_title_size_unit' => ( $has_title_font_size_unit && ! empty ( $title_font_size_unit ) ) ? $title_font_size_unit : ezTOC_Option::get( 'title_font_size_units', '%' ),
					'sidebar_sticky_title_weight' => ( $has_title_font_weight && ! empty ( $title_font_weight ) ) ? $title_font_weight : ezTOC_Option::get( 'title_font_weight', '600' ),
					'sidebar_sticky_title_color' => ( $has_title_font_color && ! empty ( $title_font_color ) ) ? $title_font_color : self::sanitize_css_color( ezTOC_Option::get( 'custom_title_colour', '' ) ),
					'sidebar_sticky_size' => ( $has_text_font_size && ! empty ( $text_font_size ) ) ? ( 'auto' == $text_font_size ) ? $text_font_size : ( int ) wp_strip_all_tags ( $text_font_size ) : (int) ezTOC_Option::get( 'font_size', 95 ),
					'sidebar_sticky_size_unit' => ( $has_text_font_size_unit && ! empty ( $text_font_size_unit ) ) ? $text_font_size_unit : ezTOC_Option::get( 'font_size_units', '%' ),
					'sidebar_sticky_weight' => ( $has_text_font_weight && ! empty ( $text_font_weight ) ) ? $text_font_weight : ezTOC_Option::get( 'font_weight', '400' ),
					'sidebar_sticky_color' => ( $has_text_font_color && ! empty ( $text_font_color ) ) ? $text_font_color : self::sanitize_css_color( ezTOC_Option::get( 'custom_link_colour', '' ) ),
					'toc_background_color' => ( $has_toc_background_color && ! empty ( $toc_background_color ) ) ? $toc_background_color : self::sanitize_css_color( ezTOC_Option::get( 'custom_background_colour', '' ) ),
					'toc_title_background_color' => ( $has_toc_title_background_color && ! empty ( $toc_title_background_color ) ) ? $toc_title_background_color : self::sanitize_css_color( ezTOC_Option::get( 'custom_title_background', '' ) ),
					'show_toggle' => ( ! empty ( $show_toggle ) ) ? $show_toggle : '',
					'device_target' => ( ! empty ( $device_target ) ) ? $device_target : ''
                );
                
                if ( !is_a( $wp_widget_factory->widgets[ $widget_name ], 'WP_Widget' ) ):
                    $wp_class = 'WP_Widget_' . ucwords(strtolower($class));

                    if (!is_a($wp_widget_factory->widgets[$wp_class], 'WP_Widget')):
						/* translators: %s: Widget class name */
                        return '<p>'.sprintf(esc_html__("%s: Widget class not found. Make sure this widget exists and the class name is correct","easy-table-of-contents"),'<strong>'.$class.'</strong>').'</p>';
                    else:
                        $class = $wp_class;
                    endif;
                endif;

                $id = uniqid( time() );
                ob_start();
                the_widget( $widget_name, $instance, array(
                    'widget_id' => 'ez-toc-widget-sticky-' . $id,
                    'ez_toc_widget_sticky_before_widget_container' => $ez_toc_widget_sticky_before_widget_container,
                    'ez_toc_widget_sticky_before_widget' => $ez_toc_widget_sticky_before_widget,
                    'ez_toc_widget_sticky_before' => $ez_toc_widget_sticky_before,
                    'ez_toc_widget_sticky_after' => $ez_toc_widget_sticky_after,
                    'ez_toc_widget_sticky_after_widget' => $ez_toc_widget_sticky_after_widget,
                    'ez_toc_widget_sticky_after_widget_container' => $ez_toc_widget_sticky_after_widget_container,
                    ) 
                );
                $output = ob_get_contents();
                ob_end_clean();
                return $output;
            }
        }
                
		/**
		 * Callback for the registered shortcode `[ez-toc]`
		 *
		 * NOTE: Shortcode is run before the callback @see ezTOC::the_content() for the `the_content` filter
		 *
		 * @access private
		 * @since  1.3
		 *
		 * @param array|string $atts    Shortcode attributes array or empty string.
		 * @param string       $content The enclosed content (if the shortcode is used in its enclosing form)
		 * @param string       $tag     Shortcode name.
		 *
		 * @return string
		 */
		public static function shortcode( $atts, $content, $tag ) {
				global $eztoc_shortcode_attr;
				$eztoc_shortcode_attr = $atts;
				$html = '';
				
				if(!eztoc_shortcode_enable_support_status($atts)){
					return $html;
				}
				if( ( ezTOC_Option::get( 'toc-run-on-amp-pages', 1 ) !== false && 0 == ezTOC_Option::get( 'toc-run-on-amp-pages', 1 ) || '0' == ezTOC_Option::get( 'toc-run-on-amp-pages', 1 ) || false == ezTOC_Option::get( 'toc-run-on-amp-pages', 1 ) ) && !eztoc_non_amp() ){
					return $html;
				}
				// Do not render on category/archive/search when content runs in the loop; use eztoc_shortcode_allow_non_singular to override.
				$explicit_post_id = isset( $atts['post_id'] ) ? absint( $atts['post_id'] ) : 0;
				if ( ! apply_filters( 'eztoc_shortcode_allow_non_singular', false, $atts, $tag ) && ! $explicit_post_id && ! is_singular() ) {
					return $html;
				}
				//Enqueue css and styles if that has not been added by wp_enqueue_scripts			
				self::enqueue_registered_script();	
				self::enqueue_registered_style();	
				self::inline_main_counting_css();		
				$pid = (function_exists('get_queried_object_id') && class_exists('Storyhub'))?get_queried_object_id():get_the_ID();		

				$post_id = isset( $atts['post_id'] ) ? (int) $atts['post_id'] : $pid;
				
				$post_exclude = get_post_meta( $post_id, '_ez-toc-exclude', true );
				$heading_levels = get_post_meta( $post_id, '_ez-toc-heading-levels', true );
				
				/* Update post meta if exclude and heading levels are set in shortcode temporarily
				* so that  self::get( $post_id ); takes the values and then remove them after
				* the post object is created.
				*/

				// Updating post meta for exclude and heading levels	

				if ( isset ( $atts['exclude'] ) && $atts['exclude'] != '' ) {
					update_post_meta( $post_id, '_ez-toc-exclude', $atts['exclude'] );	
				}

				if (isset($atts["heading_levels"]) && $atts["heading_levels"] != '') {
					$headings = explode(',', $atts["heading_levels"]);
					update_post_meta( $post_id, '_ez-toc-heading-levels', $headings );
				}
																				
				$post = self::get( $post_id );

				// setting original post meta for exclude and heading levels	
				
				if ( isset ( $atts['exclude'] ) && $atts['exclude'] != '' ) {
					update_post_meta( $post_id, '_ez-toc-exclude', $post_exclude );		
				}

				if (isset($atts["heading_levels"]) && $atts["heading_levels"] != '') {
					update_post_meta( $post_id, '_ez-toc-heading-levels', $heading_levels );
				}

				if ( ! $post instanceof ezTOC_Post ) {

						Debug::log( 'not_instance_of_post', 'Not an instance if `WP_Post`.', $pid );

						return Debug::log()->appendTo( $content );
				}
									
				$options =  array();
				if (isset($atts["label"])) {
					$options['header_label'] = $atts["label"];
				}
				if (isset($atts["header_label"])) {
					$options['header_label'] = $atts["header_label"];
				}
				if (isset($atts["display_header_label"]) && $atts["display_header_label"] == "no") {
					$options['no_label'] = true;
				}
				if(isset($atts["no_label"]) && $atts["no_label"] == "true") {
					$options['no_label'] = true;
				}
				if (isset($atts["toggle_view"]) && $atts["toggle_view"] == "no") {
					$options['no_toggle'] = true;
				}
				if (isset($atts["initial_view"]) && $atts["initial_view"] == 'hide') {
					$options['visibility_hide_by_default'] = true;
				}
				if (isset($atts["initial_view"]) && $atts["initial_view"] == 'show') {
					$options['visibility_hide_by_default'] = false;
				}
				if (isset($atts["display_counter"]) && $atts["display_counter"] == "no") {
					$options['no_counter'] = true;
				}
				if (isset($atts["view_more"]) && $atts["view_more"] > 0) {
					$options['view_more'] = $atts["view_more"];
				}
				if (isset($atts["class"]) && $atts["class"] != '') {
					$options['class'] = $atts["class"];
				}
				
				if(isset($atts["wrapping"]) && $atts["wrapping"] != ''){
					$options['wrapping'] = $atts["wrapping"];
				}
				if(isset($atts["columns"]) && $atts["columns"] != ''){
					$options['columns'] = absint( $atts["columns"] );
				}
				if(isset($atts["word_count_limit"]) && $atts["word_count_limit"] != ''){
					$options['word_count_limit'] = $atts["word_count_limit"];
				}
				if(isset($atts["box_title"]) && $atts["box_title"] != ''){
					$options['box_title'] = $atts["box_title"];
				}
				$html = count($options) > 0 ? $post->getTOC($options) : $post->getTOC();	
			
				return apply_filters( 'eztoc_shortcode_final_toc_html', $html );
		}

		/**
		 * Whether or not apply `the_content` filter.
		 *
		 * @since 2.0
		 *
		 * @return bool
		 */
		private static function maybe_apply_the_content_filter() {

			$apply = true;

			global $wp_current_filter;

			// Do not execute if root current filter is one of those in the array.
			if (isset($wp_current_filter[0]) && in_array( $wp_current_filter[0], array( 'get_the_excerpt', 'init', 'wp_head' ), true ) ) {

				$apply = false;
			}

			// bail if feed, search or archive
			if ( is_feed() || is_search() || is_archive() ) {
				
				if( (true == ezTOC_Option::get( 'include_category', false) && is_category()) || (true == ezTOC_Option::get( 'include_tag', false) && is_tag()) || (true == ezTOC_Option::get( 'include_product_category', false) &&  (function_exists('is_product_category') && is_product_category()) ) || (true == ezTOC_Option::get( 'include_custom_tax', false) && is_tax())) {
					
					$apply = true;
				} else {
					$apply = false;
				}
			}

			/*
			 * `[ez-toc]`  Skip any non-singular main-loop post content; term/woo description filters call
			 * `the_content` directly and are not in the main post loop.
			 *
			 * Exception: `include_homepage` (see is_eligible()) must still allow TOC for qualifying posts on the
			 * front page.
			 */
			if ( $apply && ! is_singular() && ( is_home() || ( in_the_loop() && is_main_query() ) ) ) {
				if ( ! ( true == ezTOC_Option::get( 'include_homepage', false ) && is_front_page() ) ) {
					$apply = false;
				}
			}

			if( function_exists('get_current_screen') ) {
				$my_current_screen = get_current_screen();
				if ( isset( $my_current_screen->id )  ) {

					if( $my_current_screen->id == 'edit-post' ) {          
						$apply = false;
					}
				}

				if(is_object($my_current_screen) && method_exists( $my_current_screen, 'is_block_editor' ) && $my_current_screen->is_block_editor()){
					$apply = false;
				}
			}

			if ( ! empty( array_intersect( $wp_current_filter, array( 'get_the_excerpt', 'init', 'wp_head' ) ) ) ) {
				$apply = false;
			}

			if ((function_exists('et_core_is_model_view') && et_core_is_model_view()) || (function_exists('et_builder_is_enabled') && et_builder_is_enabled())) {
				// Divi frontend & backend builder
				$apply = false;
			} 
			/**
			 * Whether or not to apply `the_content` filter callback.
			 *
			 * @see ezTOC::the_content()
			 *
			 * @since 2.0
			 *
			 * @param bool $apply
			 */
			//This is legacy hook,it will be removed in future versions.
			$eztoc_maybe_apply_the_content_filter = apply_filters( 'ez_toc_maybe_apply_the_content_filter', $apply ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy hook name.
			//This is the new hook , it should be used instead of the legacy one.
			$eztoc_maybe_apply_the_content_filter = apply_filters( 'eztoc_maybe_apply_the_content_filter', $apply );	 		
			return $eztoc_maybe_apply_the_content_filter;
		}

		/**
		 * Callback for the `the_content` filter.
		 *
		 * This will add the inline table of contents page anchors to the post content. It will also insert the
		 * table of contents inline with the post content as defined by the user defined preference.
		 *
		 * @since 1.0
		 *
		 * @param string $content
		 *
		 * @return string
		 */
	public static function the_content( $content ) {
			
		// Prevent infinite recursion
		global $eztoc_processing_content;
		if ( ! empty( $eztoc_processing_content ) ) {
			return $content;
		}
		$eztoc_processing_content = true;
			                    
		if ( function_exists( 'post_password_required' ) ) {
			if ( post_password_required() ) {
				$eztoc_processing_content = false;
				return Debug::log()->appendTo( $content );
			}
		}
		if( ezTOC_Option::get( 'disable_toc_links' ,false ) ){
			$eztoc_processing_content = false;
			return Debug::log()->appendTo( $content );
		}
		$maybeApplyFilter = self::maybe_apply_the_content_filter();
			$content = apply_filters( 'eztoc_modify_the_content', $content );
								
		Debug::log( 'the_content_filter', 'The `the_content` filter applied.', $maybeApplyFilter );

		if ( ! $maybeApplyFilter ) {
			$eztoc_processing_content = false;
			return Debug::log()->appendTo( $content );
		}
		// Fix for getting current page id when sub-queries are used on the page
			$ez_toc_current_post_id = function_exists('get_queried_object_id')?get_queried_object_id():get_the_ID();
			$eztoc_current_theme = wp_get_theme();
			// Bail if post not eligible and widget is not active.
			if('MicrojobEngine Child' == $eztoc_current_theme->get( 'Name' ) || class_exists( 'Timber' ) ){
				$isEligible = self::is_eligible( get_post($ez_toc_current_post_id) );
			}else{
				$isEligible = self::is_eligible( get_post() );
			}
			
			
			//More button
			$options =  array();
			if (ezTOC_Option::get( 'ctrl_headings' ) == true) {
				$options['view_more'] = ezTOC_Option::get( 'limit_headings_num' );
			}
			$post_ctrl_headings = get_post_meta( $ez_toc_current_post_id, '_ez-toc-p_ctrl_heading', true );
			$post_ctrl_headings_limit = get_post_meta( $ez_toc_current_post_id, '_ez-toc-p_limit_headings_num', true );

			if($post_ctrl_headings == true && $post_ctrl_headings_limit > 0){
				$options['view_more'] = get_post_meta( $ez_toc_current_post_id, '_ez-toc-p_limit_headings_num', true );
			}

			$isEligible = apply_filters('eztoc_do_shortcode',$isEligible);

			if($isEligible){
				if(!eztoc_auto_device_target_status()){
					$isEligible = false;
				}
			}

			Debug::log( 'post_eligible', 'Post eligible.', $isEligible );
			$return_only_an = false; 
			$post_type = get_post_type( $ez_toc_current_post_id );
			$sticky_enabled_on_post = in_array( $post_type, ezTOC_Option::get( 'sticky-post-types', array() ), true );
			if(!$isEligible && (self::is_sidebar_hastoc() || is_active_widget( false, false, 'ezw_tco' ) || is_active_widget( false, false, 'ez_toc_widget_sticky' ) || ( ezTOC_Option::get('sticky-toggle') && $sticky_enabled_on_post ) )){
				$isEligible = true;
				$return_only_an = true;
			}
			
			if ( ! $isEligible ) {
				return Debug::log()->appendTo( $content );
			}
			$eztoc_current_theme = wp_get_theme();
			if($eztoc_current_theme->get('Name') == 'MicrojobEngine Child'  || class_exists( 'Timber' ) ){
				$post = self::get( $ez_toc_current_post_id );
		}else{
			$post = self::get( get_the_ID());
		}
		
		
		if ( ! $post instanceof ezTOC_Post ) {

			Debug::log( 'not_instance_of_post', 'Not an instance if `WP_Post`.', get_the_ID() );
			$eztoc_processing_content = false;
			return Debug::log()->appendTo( $content );
		}
		 //Bail if no headings found.
		 if ( ! $post->hasTOCItems() && ezTOC_Option::get( 'no_heading_text' ) != 1) {
			$eztoc_processing_content = false;
		 	return Debug::log()->appendTo( $content );
		 }
		         
		$find    = $post->getHeadings();
		$replace = $post->getHeadingsWithAnchors();
			$toc 	 = count($options) > 0 ? $post->getTOC($options) : $post->getTOC();
			$headings = implode( PHP_EOL, $find );
			$anchors  = implode( PHP_EOL, $replace );

			$headingRows = count( $find ) + 1;
			$anchorRows  = count( $replace ) + 1;

			$style = "background-image: linear-gradient(#F1F1F1 50%, #F9F9F9 50%); background-size: 100% 4em; border: 1px solid #CCC; font-family: monospace; font-size: 1em; line-height: 2em; margin: 0 auto; overflow: auto; padding: 0 8px 4px; white-space: nowrap; width: 100%;";

			Debug::log(
				'found_post_headings',
				'Found headings:',
				"<textarea id='ez-toc-debug-headings-found' rows='{$headingRows}' style='{$style}' wrap='soft'>{$headings}</textarea>"
			);

			Debug::log(
				'replace_post_headings',
				'Replace found headings with:',
				"<textarea id='ez-toc-debug-headings-replace' rows='{$anchorRows}' style='{$style}' wrap='soft'>{$anchors}</textarea>"
			);
			

		if ( $return_only_an ) {
			Debug::log( 'side_bar_has shortcode', 'Shortcode found, add links to content.', true );
			$eztoc_processing_content = false;
			return mb_find_replace( $find, $replace, $content );
		}
		// If shortcode used or post not eligible, return content with anchored headings.
		if ( strpos( $content, 'ez-toc-container' ) || ! $isEligible ) {

			Debug::log( 'shortcode_found', 'Shortcode found, add links to content.', true );
			$eztoc_processing_content = false;
			return mb_find_replace( $find, $replace, $content );
		}
			
			$position  = get_post_meta( get_the_ID(), '_ez-toc-position-specific', true );
			if (empty($position)) {
				$position = ezTOC_Option::get( 'position' );
			}

			Debug::log( 'toc_insert_position', 'Insert TOC at position', $position );

			switch ( $position ) {

				case 'top':
					$content = $toc . mb_find_replace( $find, $replace, $content );
					break;

				case 'bottom':
					$content = mb_find_replace( $find, $replace, $content ) . $toc;
					break;

				case 'after':
					$replace[0] = $replace[0] . $toc;
					$content    = mb_find_replace( $find, $replace, $content );
					break;
				case 'afterpara':
					$exc_blkqt  = get_post_meta( get_the_ID(), '_ez-toc-s_blockqoute_checkbox', true );
					if ( empty( $exc_blkqt ) ) {
						$exc_blkqt = ezTOC_Option::get( 'blockqoute_checkbox' );
					}
					//blockqoute
					$blockquotes = array();
					if($exc_blkqt == true){
						preg_match_all("/<blockquote(.*?)>(.*?)<\/blockquote>/s", $content, $blockquotes);
						if(!empty($blockquotes)){
					    	$content = eztoc_para_blockquote_replace($blockquotes, $content, 1);
					   	}
					}
					$content = insertElementByPTag( mb_find_replace( $find, $replace, $content ), $toc );
					//add blockqoute back
					if($exc_blkqt == true && !empty($blockquotes)){
					    $content = eztoc_para_blockquote_replace($blockquotes, $content, 2);
				    }
					break;
				case 'aftercustompara':
					$exc_blkqt  = get_post_meta( get_the_ID(), '_ez-toc-s_blockqoute_checkbox', true );
					if ($exc_blkqt) {
						$exc_blkqt = ezTOC_Option::get( 'blockqoute_checkbox' );
					}
					//blockqoute
					$blockquotes = array();
					if($exc_blkqt == true){
						preg_match_all("/<blockquote(.*?)>(.*?)<\/blockquote>/s", $content, $blockquotes);
						if(!empty($blockquotes)){
					    	$content = eztoc_para_blockquote_replace($blockquotes, $content, 1);
					   	}
					}
					$paragraph_index  = get_post_meta( get_the_ID(), '_ez-toc-s_custom_para_number', true );
					if (empty($paragraph_index)) {
						$paragraph_index = ezTOC_Option::get( 'custom_para_number' );
					}
					if($paragraph_index == 1){
						$content = insertElementByPTag( mb_find_replace( $find, $replace, $content ), $toc );
					}else if($paragraph_index > 1){
						$closing_p = '</p>';
						$paragraphs = explode( $closing_p, $content );
						if(!empty($paragraphs) && is_array($paragraphs) && $paragraph_index <= count($paragraphs)){
							$paragraph_id = $paragraph_index;
							foreach ($paragraphs as $index => $paragraph) {
								if ( trim( $paragraph ) ) {
									$paragraphs[$index] .= $closing_p;
								}
								$pos = strpos($paragraph, '<p');
								if ( $paragraph_id == $index + 1 && $pos !== false ) {
									$paragraphs[$index] .= $toc;
								}
							}
							$content = implode( '', $paragraphs );
							$content = mb_find_replace( $find, $replace, $content );
						}else{
							$content = insertElementByPTag( mb_find_replace( $find, $replace, $content ), $toc );	
						}
					}else{
						$content = insertElementByPTag( mb_find_replace( $find, $replace, $content ), $toc );	
					}
					//add blockqoute back
					if($exc_blkqt == true && !empty($blockquotes)){
					    $content = eztoc_para_blockquote_replace($blockquotes, $content, 2);
				    }
					break;	
				case 'aftercustomimg':
					$img_index  = get_post_meta( get_the_ID(), '_ez-toc-s_custom_img_number', true );
					if (empty($img_index)) {
						$img_index = ezTOC_Option::get( 'custom_img_number' );
					}
					if($img_index == 1){
						$content = insertElementByImgTag( mb_find_replace( $find, $replace, $content ), $toc );
					}else if($img_index > 1){
						$closing_img = '</figure>';
						$imgs = explode( $closing_img, $content );
						if(!empty($imgs) && is_array($imgs) && $img_index <= count($imgs)){
							$img_id = $img_index;
							foreach ($imgs as $index => $img) {
								if ( trim( $img ) ) {
									$imgs[$index] .= $closing_img;
								}
								$pos = strpos($img, '<figure');
								if ( $img_id == $index + 1 && $pos !== false ) {
									$imgs[$index] .= $toc;
								}
							}
							$content = implode( '', $imgs );
							$content = mb_find_replace( $find, $replace, $content );
						}else{
							$content = insertElementByImgTag( mb_find_replace( $find, $replace, $content ), $toc );	
						}
					}else{
						$content = insertElementByImgTag( mb_find_replace( $find, $replace, $content ), $toc );	
					}
					break;	
				case 'before':
				default:
					$content    = mb_find_replace( $find, $replace, $content );

					/**
					 * @link https://wordpress.org/support/topic/php-notice-undefined-offset-8/
					 */
					if ( ! array_key_exists( 0, $replace ) ) {
						break;
					}

					$pattern = '`<h[1-6]{1}[^>]*' . preg_quote( $replace[0], '`' ) . '`msuU';
					$result  = preg_match( $pattern, $content, $matches );

					/*
					 * Try to place TOC before the first heading found in eligible heading, failing that,
					 * insert TOC at top of content.
					 */
					if ( 1 === $result ) {

						Debug::log( 'toc_insert_position_found', 'Insert TOC before first eligible heading.', $result );

						$start   = strpos( $content, $matches[0] );
						$content = substr_replace( $content, $toc, $start, 0 );

					} else {

						Debug::log( 'toc_insert_position_not_found', 'Insert TOC before first eligible heading not found.', $result );

					}
		}
            
		$eztoc_processing_content = false;
		return Debug::log()->appendTo( $content );
	}

		/**
		 * sticky_toggle_content Method
		 * Call back for the `wp_footer` action.
		 *
		 * @since  2.0.32
		 * @static
		 */
		public static function sticky_toggle_content() {
					  
			  if( self::is_enqueue_scripts_sticky_eligible() ){

				if( function_exists( 'post_password_required' ) ) {
					if(post_password_required() ) {
						return false;
					}
			    }

				$toggleClass = "hide";
				$linkZindex  = "";

				$post = self::get( get_the_ID() );

				if ( null !== $post) {

					$stickyToggleTOC = $post->get_sticky_toggle_toc();

					if(!empty($stickyToggleTOC)){
						$openButtonText = esc_html__( 'Index', 'easy-table-of-contents' );
						if( !empty( ezTOC_Option::get( 'sticky-toggle-open-button-text' ) ) ) {
							$openButtonText = ezTOC_Option::get( 'sticky-toggle-open-button-text' );
						}
						if( !empty( ezTOC_Option::get( 'sticky-toggle-open' ) ) ) {
							$isTOCOpen = ezTOC_Option::get( 'sticky-toggle-open' );
							if($isTOCOpen){
								$toggleClass="show";
								$linkZindex="z-index:-1;";
							}
						}
						if( !empty( ezTOC_Option::get( 'sticky-design' )) ) {
							$toggleClass="show";
						}

					$designClass = apply_filters( 'eztoc_sticky_design_class', "" );
					$arrowSide = ( 'right' == ezTOC_Option::get( 'sticky-toggle-position', 'left') )?"&#8592;":"&#8594;"; 
					
					$themeClass = 'ez-toc-sticky-'.ezTOC_Option::get( 'sticky_theme', 'grey' );
										
					?>
					<div class="ez-toc-sticky <?php echo esc_attr($designClass);?>">
						<div class="ez-toc-sticky-fixed <?php echo esc_attr($toggleClass); ?> <?php echo esc_attr($themeClass); ?>">
							<div class='ez-toc-sidebar'><?php echo $stickyToggleTOC; //phpcs:ignore  ?></div>
						</div>
						<a class='ez-toc-open-icon' href='#' onclick='ezTOC_showBar(event)' <?php echo $linkZindex ?"style='".esc_attr($linkZindex)."'":''; ?>>
							<span class="arrow"><?php echo esc_html($arrowSide); ?></span>
							<span class="text"><?php echo esc_html($openButtonText); ?></span>
						</a>
					</div>
					<?php
					}
				}
			  }
				
		}

		/**
		 * Call back for the `wp_head` action.
		 *
		 * Add add button for shortcode in wysisyg editor .
		 *
		 * @access private
		 * @since  1.0
		 * @static
		 */
		public static function add_editor_button() {
			
            if ( !current_user_can( 'edit_posts' ) &&  !current_user_can( 'edit_pages' ) ) {
                       return;
               }
			   
		
           if ( 'true' == get_user_option( 'rich_editing' ) ) {
			   $show_mce_button = true;
			   if ( ! ezTOC_Option::get( 'show-toc-toolbar-classic', true ) ) {
				   $show_mce_button = false;
			   }
			   if ( $show_mce_button ) {			
				add_filter( 'mce_external_plugins', array( __CLASS__, 'toc_add_tinymce_plugin'));
				add_filter( 'mce_buttons', array( __CLASS__, 'toc_register_mce_button' ));
               }
			}
			
		}
		
		/**
		 * Call back for the `mce_external_plugins` action.
		 *
		 * Register new button in the editor.
		 *
		 * @access private
		 * @since  1.0
		 * @static
		 */		
		
		public static function toc_register_mce_button( $buttons ) {
            
				array_push( $buttons, 'toc_mce_button' );
				return $buttons;
		}
			
		/**
		 * Call back for the `mce_buttons` action.
		 *
		 * Add  js to insert the shortcode on the click event.
		 *
		 * @access private
		 * @since  1.0
		 * @static
		 */
		public static function toc_add_tinymce_plugin( $plugin_array ) {
			
				$plugin_array['toc_mce_button'] = EZ_TOC_URL .'assets/js/toc-mce-button.js';
				return $plugin_array;
		}

		/**
         * get_toc_toggle_icon Method
         * @access public
   		 * @since  2.0.35
   		 * @static
		 * @return string
		 */
		public static function get_toc_toggle_icon( $type = '' )
		{
			$iconColor = '#000000';
			if( ezTOC_Option::get( 'custom_title_colour' ) )
			{
				$iconColor = ezTOC_Option::get( 'custom_title_colour' );
			}
			$spanClass = '';
			if( ezTOC_Option::get( 'toc_loading' ) == 'css' && $type != 'widget-with-visibility_on_header_text' ) 
			{
				$spanClass = 'ez-toc-cssicon';
			}

			return '<span class="' . esc_attr($spanClass) . '"><span class="eztoc-hide" style="display:none;">Toggle</span><span class="ez-toc-icon-toggle-span"><svg style="fill: ' . esc_attr($iconColor) . ';color:' . esc_attr($iconColor) . '" xmlns="http://www.w3.org/2000/svg" class="list-377408" width="20px" height="20px" viewBox="0 0 24 24" fill="none"><path d="M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z" fill="currentColor"></path></svg><svg style="fill: ' . esc_attr($iconColor) . ';color:' . esc_attr($iconColor) . '" class="arrow-unsorted-368013" xmlns="http://www.w3.org/2000/svg" width="10px" height="10px" viewBox="0 0 24 24" version="1.2" baseProfile="tiny"><path d="M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z"/></svg></span></span>';
		}

		 /**
         * the_category_content_filter Method
         * @access public
   		 * @since  2.0.46
   		 * @static
		 * @return string
		 */
		public static function toc_term_content_filter( $description , $term_id ) {
                    if( (is_category() && true == ezTOC_Option::get( 'include_category', false)) || (is_tax() && true == ezTOC_Option::get( 'include_custom_tax', false)) || (is_tag() && true == ezTOC_Option::get( 'include_tag', false)) ) {
						if(!is_admin() && !empty($description)){							
							return self::the_content($description);
						}
                    }
                    return $description;
		}

		public static function toc_category_content_filter_woocommerce( $description , $term ) {
					if( true == ezTOC_Option::get( 'include_product_category', false) ) {
						if(!is_admin() && !empty($description)){
							return self::the_content($description);
						}
					}
					return $description;
		}

		/**
		 * the_content_storehub Method
		 * Call back for the `the_content` filter.
		 *
		 * This will add the inline table of contents page anchors to the post content. It will also insert the
		 * table of contents inline with the post content as defined by the user defined preference.
		 *
		 * @access public
		 * @since  1.0
		 * @static
		 * @param string $content
		 * @return string
		 */
		public static function the_content_storehub ( $content ) {
				                    
			if( function_exists( 'post_password_required' ) ) {
				if( post_password_required() ) return Debug::log()->appendTo( $content );
			}
		
			$maybeApplyFilter = self::maybe_apply_the_content_filter();													
			$content = apply_filters('eztoc_modify_the_content',$content);
			
		Debug::log( 'the_content_filter', 'The `the_content` filter applied.', $maybeApplyFilter );
		
		if ( ! $maybeApplyFilter ) {
		
			return Debug::log()->appendTo( $content );
		}
		
		$isEligible = self::is_eligible( get_post() );
	
		$isEligible = apply_filters('eztoc_do_shortcode',$isEligible);
		
		if($isEligible){
			if(!eztoc_auto_device_target_status()){
				$isEligible = false;
			}
		}
		
		Debug::log( 'post_eligible', 'Post eligible.', $isEligible );
		if(!$isEligible && (self::is_sidebar_hastoc() || is_active_widget( false, false, 'ezw_tco' ) || is_active_widget( false, false, 'ez_toc_widget_sticky' ) || ezTOC_Option::get('sticky-toggle') )){
			$isEligible = true;
		}
		
		if ( ! $isEligible ) {
			$eztoc_processing_content = false;
			return Debug::log()->appendTo( $content );
		}
		
		$post = self::get( get_the_ID());
		
		if ( ! $post instanceof ezTOC_Post ) {
		
			Debug::log( 'not_instance_of_post', 'Not an instance if `WP_Post`.', get_the_ID() );
		
			return Debug::log()->appendTo( $content );
		}
		 //Bail if no headings found.
		 if ( ! $post->hasTOCItems() && ezTOC_Option::get( 'no_heading_text' ) != 1) {
		
			 return Debug::log()->appendTo( $content );
		 }
				 
		$find    = $post->getHeadings();
		$replace = $post->getHeadingsWithAnchors();

		return mb_find_replace( $find, $replace, $content );
		
		}


		/**
		 * Start output buffering to catch final HTML.
		 * SeedProd bypasses the_content, so we must filter later.
		 */
		public static function ez_toc_buffer_start() {
			// Only run if the post is eligible
			if ( self::is_eligible( get_post() ) && !is_admin() ) {
				ob_start( array( __CLASS__, 'ez_toc_buffer_end' ) );
			}
		}

		/**
		 * Process the final HTML output buffer.
		 * This is where we inject the spans.
		 */
		public static function ez_toc_buffer_end( $buffer ) {
			
			// Get the post object for the current page
			$post_obj = self::get( get_the_ID() );

			if ( ! $post_obj instanceof ezTOC_Post || ! $post_obj->hasTOCItems() || ezTOC_Option::get( 'disable_toc_links' ,false ) ) {
				return $buffer; // No items or disabled, return original HTML
			}

			// Get headings to find and headings with anchors to replace
			$find    = $post_obj->getHeadings();
			$replace = $post_obj->getHeadingsWithAnchors();

			if ( empty($find) || empty($replace) ) {
				return $buffer;
			}

			// Use mb_find_replace to inject spans into the final HTML buffer
			return mb_find_replace( $find, $replace, $buffer );
		}

		/**
		 * Add TOC in product category description when using Kadence theme
		 * @param mixed $description
		 * @return mixed
		 */
		public static function toc_get_the_archive_description( $description ) {
			$eztoc_current_theme = wp_get_theme();
			if (  ( $eztoc_current_theme->get( 'Name' ) === 'Kadence' || $eztoc_current_theme->get( 'Template' ) === 'kadence' ) && function_exists('is_product_category') && is_product_category() ) {
				if( true == ezTOC_Option::get( 'include_product_category', false) ) {
					if(!is_admin() && !empty($description)){
						return self::the_content($description);
					}
				}
			}
			return $description;
		}


	}

	/**
	 * The main function responsible for returning the Easy Table of Contents instance to functions everywhere.
	 *
	 * Use this function like you would a global variable, except without needing to declare the global.
	 *
	 * Example: <?php $instance = ezTOC(); ?>
	 *
	 * @access public
	 * @since  1.0
	 *
	 * @return ezTOC
	 */
	function ezTOC() {

		return ezTOC::instance();
	}

	// Start Easy Table of Contents.
	add_action( 'plugins_loaded', 'ezTOC' );
}

register_activation_hook(__FILE__, 'eztoc_activate');
function eztoc_activate($network_wide) {
	if ( !( is_multisite() && $network_wide ) ) {
    	add_option('ez_toc_do_activation_redirect', true);
	}
}