
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
<?php defined( 'ABSPATH' ) OR die( 'This script cannot be accessed directly.' );

/**
 * Main class of US Bbuilder
 */

if ( ! class_exists( 'USBuilder' ) ) {

	final class USBuilder {

		/**
		 * Param name in the URL address bar
		 * NOTE: This value must have valid characters for hooks and URL.
		 */
		const BUILDER_SLUG = 'us-builder';

		/**
		 * Main container
		 *
		 * @var string
		 */
		const MAIN_CONTAINER = 'container';

		/**
		 * Meta key for post custom css (Meta key compatible from WPBakery Page Builder)
		 *
		 * @var string
		 */
		const META_KEY_FOR_CUSTOM_CSS = '_wpb_post_custom_css';

		/**
		 * Css classes for the body element
		 *
		 * @var array
		 */
		private $_body_classes = [];

		/**
		 * @access public
		 */
		public function __construct() {
			global $wpdb;

			// Get current builder slug
			$builder_slug = static::get_slug();

			// TODO: add proper capability check, see #2232
			if ( is_admin() ) {

				// On the builder page, we initialize all the necessary components
				if ( static::is_builder_page() ) {

					// Get the id of the post being edited
					$post_id = static::get_post_id();

					// Get minimal information about a record
					$post = $wpdb->get_row( "SELECT post_type, post_status FROM {$wpdb->posts} WHERE ID = " . $post_id . " LIMIT 1;" );

					// Check if a post exists
					if ( ! $post_id OR is_null( $post ) ) {
						wp_die( us_translate( 'You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?' ) );
					}

					// Checking edit permission by post type
					if ( ! in_array( $post->post_type, $this->get_allowed_edit_post_types() ) ) {
						wp_die( 'Editing of this page is not supported.' );
					}

					// Checking edit permission by post ID
					if ( ! current_user_can( 'edit_post', $post_id ) ) {
						wp_die( us_translate( 'Sorry, you are not allowed to access this page.' ) );
					}

					// Publish the post if it doesn't exist
					if ( $post->post_status === 'auto-draft' ) {
						wp_update_post( array(
							'ID' => $post_id,
							'post_title' => '#' . $post_id,
							'post_status' => 'publish',
						) );
					}

					// Initializing the builder page post
					add_action( "admin_action_{$builder_slug}", array( $this, 'init_builder_page' ), 1 );

					// Add styles and scripts on the builder page
					add_action( 'wp_print_styles', array( $this, 'enqueue_assets_for_builder' ), 1 );

					// Outputs the editor scripts, stylesheets, and default settings.
					add_action( 'usb_admin_footer_scripts', array( $this, 'admin_footer_scripts' ), 1 );

					// At regular admin pages ...
				} else {
					// .. adding a link to US Builder editor for posts and pages
					add_filter( 'post_row_actions', [ $this, 'row_actions' ], 501, 2 );
					add_filter( 'page_row_actions', [ $this, 'row_actions' ], 501, 2 );

					add_action( 'edit_form_after_title', [ $this, 'output_builder_switch' ] );
				}

			} else {
				// If the site is open in the builder, then hide the admin bar
				if ( static::is_preview_page() ) {
					// Hide admin bar
					add_filter( 'show_admin_bar', '__return_false' );

					// This is an instance of the class for working with shortcodes
					$shortcode = USBuilder_Shortcode::instance();

					// Cancel the output of styles for content on the preview page
					add_filter( 'us_is_output_design_css_for_content', '__return_false', 1 );

					// Prepares shortcodes for display on the preview page
					add_action( 'the_content', array( $shortcode, 'prepare_text' ), 1, 1 );

					// Add data-usbid attribute to html when output shortcode result
					add_filter( 'do_shortcode_tag', array( $shortcode, 'add_usbid_to_html' ), 9999, 3 );

					// Export of sources such as content and custom css
					add_action( 'wp_footer', array( $shortcode, 'export_page_sources' ), 9999 );

					// Add styles and scripts on the preview page
					add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets_for_preview' ) );

					// The output html for highlighting the selected element
					add_action( 'us_after_footer', array( $this, 'after_footer_action' ) );

					// Bind a method to manipulate the admin menu
				} elseif ( has_action( 'admin_bar_menu' ) ) {
					add_action( 'admin_bar_menu', [ $this, 'admin_bar_menu_action' ], 501 );
				}
			}

			// Auxiliary filters for class static methods
			add_filter( 'usb_is_builder_page', sprintf( '%s::is_builder_page', __CLASS__ ) );
			add_filter( 'usb_is_preview_page', sprintf( '%s::is_preview_page', __CLASS__ ) );
			add_filter( 'usb_get_usbid_container', sprintf( '%s::get_usbid_container', __CLASS__ ) );

			// Init the class for handling AJAX requests
			if ( wp_doing_ajax() ) {
				USBuilder_Ajax::init();
			}
		}

		/**
		 * Get the builder slug.
		 *
		 * @access public
		 * @return string The builder slug.
		 */
		static public function get_slug() {
			return sanitize_title( self::BUILDER_SLUG );
		}

		/**
		 * Get the id of the main container
		 *
		 * @access public
		 * @return string
		 */
		static public function get_usbid_container() {
			return static::is_preview_page()
				? ' data-usbid="' . self::MAIN_CONTAINER . '" '
				: '';
		}

		/**
		 * Get the id of the post being edited.
		 *
		 * @access public
		 * @return int Returns the id of the page being edited
		 */
		static public function get_post_id() {
			return (int) us_arr_path( $_REQUEST, 'post', get_queried_object_id() );
		}

		/**
		 * Add styles and scripts on the preview page
		 *
		 * @access public
		 */
		public function enqueue_assets_for_preview() {
			wp_enqueue_script( 'usb-preview-js', US_BUILDER_URL . '/assets/js/us-builder-preview.js', array( 'jquery' ), US_CORE_VERSION );
			wp_enqueue_style( 'usb-preview-css', US_BUILDER_URL . '/assets/css/us-builder-preview.css', array(), US_CORE_VERSION );
		}

		/**
		 * Add styles and scripts on the builder page
		 *
		 * @access public
		 */
		public function enqueue_assets_for_builder() {
			global $wp_scripts, $wp_styles;

			// Reset styles
			$wp_styles = new WP_Styles;
			wp_default_styles( $wp_styles );

			// Reset scripts
			$wp_scripts = new WP_Scripts;
			wp_default_scripts( $wp_scripts );

			// Include all files needed to use the WordPress media API
			wp_enqueue_media();
			wp_enqueue_editor();

			// WordPress styles for correct appearance of fields
			wp_enqueue_style( 'forms' );
			wp_enqueue_style( 'editor-buttons' );

			// Theme admin styles
			us_admin_print_styles();

			// Builder styles
			wp_enqueue_style( 'us-builder', US_BUILDER_URL . '/assets/css/us-builder.css', array(), US_CORE_VERSION );

			// Add only the necessary scripts, we will not load everything since we do not need it
			$builder_slug = static::get_slug();

			// Enqueue USOF JS files separately, when US_DEV is set
			if ( defined( 'US_DEV' ) ) {
				foreach ( us_config( 'assets-admin.js', array() ) as $key => $admin_js_file ) {
					wp_enqueue_script( 'usof-js-' . $key, US_CORE_URI . $admin_js_file, array(), US_CORE_VERSION );
				}
			} else {
				wp_enqueue_script( 'usof-scripts', US_CORE_URI . '/usof/js/usof.min.js', array( 'jquery' ), US_CORE_VERSION, TRUE );
			}

			wp_enqueue_script( $builder_slug, US_BUILDER_URL . '/assets/js/builder.js', array( 'jquery' ), US_CORE_VERSION );
		}

		/**
		 * Including additional scripts or settings in the output
		 * NOTE: The output of scripts in this method should exclude the initialization of the wp editor,
		 * the initialization is performed in the USOF
		 *
		 * @access public
		 */
		public function admin_footer_scripts() {
			// Get output footer scripts
			do_action( 'admin_print_footer_scripts' );

			// This is the output of methods for params callbacks
			$js_callbacks = array();
			foreach ( us_config( 'shortcodes.theme_elements', array(), /* Reload */ TRUE ) as $elm_filename ) {
				if ( $elm_config = us_config( "elements/$elm_filename", array() ) ) {
					// Ignore elements which are not available via condition
					if ( isset( $elm_config['place_if'] ) AND ! $elm_config['place_if'] ) {
						continue;
					}
					// Do not run further code in cycle if the element has no params
					if ( empty( $elm_config['params'] ) ) {
						continue;
					}
					$elm_filename = us_get_shortcode_full_name( $elm_filename );
					foreach ( $elm_config['params'] as $param_name => $param_config ) {
						if ( us_arr_path( $param_config, 'usb_preview', TRUE ) === TRUE ) continue;
						if ( empty( $param_config['usb_preview'][ 0 ] ) ) {
							$param_config['usb_preview']= array( $param_config['usb_preview'] );
						}
						foreach ( $param_config['usb_preview'] as $instructions ) {
							if ( empty( $instructions[ 'callback' ] ) ) continue;
							$callback_body = (string) $instructions[ 'callback' ];
							$js_callbacks[] = $elm_filename . '_' . $param_name . ':function( value ){' . $callback_body . '}';
						}
					}
				}
			}
			$jscode = '
				window.$usbdata = window.$usbdata || {}; // Single space for data
				window.$usbdata.previewCallbacks = {' . implode( ",", $js_callbacks ) . '};
			';
			echo '<script>' . $jscode .'</script>';
		}

		/**
		 * Return the html for highlighting the selected element
		 *
		 * @access public
		 * @return string
		 */
		public function after_footer_action() {
			echo '
			<!-- Begin builder hover -->
			<div class="usb-builder-hover">
				<div class="usb-builder-hover-panel">
					<div class="usb-builder-hover-panel-name">Element</div>
					<div class="usb-builder-hover-panel-btn icon_duplicate" title="' . esc_attr( __( 'Duplicate', 'us' ) ) . '"></div>
					<div class="usb-builder-hover-panel-btn icon_delete" title="' . esc_attr( us_translate( 'Delete' ) ) . '"></div>
				</div>
				<div class="usb-builder-hover-h"></div>
			</div>
			<!-- End builder hover -->';

			$js_init_methods = array();
			foreach ( us_config( 'shortcodes.theme_elements', array(), /* Reload */ TRUE ) as $elm_filename ) {
				if ( $elm_config = us_config( "elements/$elm_filename", array() ) ) {
					// Ignore elements which are not available via condition
					if ( isset( $elm_config['place_if'] ) AND ! $elm_config['place_if'] ) {
						continue;
					}
					$elm_filename = us_get_shortcode_full_name( $elm_filename );
					// Add function for JS initialization of preview from `usb_init_js` option
					if ( ! empty( $elm_config['usb_init_js'] ) ) {
						$js_init_methods[] = $elm_filename . ':function( $elm ){' . (string) $elm_config['usb_init_js'] . '}';
					}

				}
			}
			// This is the output of methods for initializing JS scripts
			$jscode = '
				window.$usbdata = window.$usbdata || {}; // Single space for data
				window.$usbdata.elmsInitJSMethods = {' . implode( ",", $js_init_methods ) . '};
			';
			echo '<script>' . $jscode .'</script>';
		}

		/**
		 * This is the hook used to add, remove, or manipulate admin bar items
		 *
		 * @access public
		 * @param WP_Admin_Bar $wp_admin_bar The admin bar
		 */
		public function admin_bar_menu_action( \WP_Admin_Bar $wp_admin_bar ) {
			// TODO: add method for getting ID for all other special pages,
			// for example search page's link is not wokring: http://prntscr.com/11sy6fs

			// Getting the post id
			$post_id = is_front_page() ? get_option( 'page_on_front' ) : get_queried_object_id();
			$edit_link = static::get_edit_permalink( $post_id );

			if ( current_user_can( 'edit_post', $post_id ) AND ! empty( $edit_link ) ) {
				$wp_admin_bar->add_node(
					array(
						'id' => 'edit_us_builder',
						'title' => __( 'Edit Live', 'us' ),
						'href' => $edit_link,
						'meta' => array(
							'class' => 'us-builder',
							'html' => '<style>.us-builder > a{font-weight:600!important;color:#23ccaa!important}</style>',
						),
					)
				);
			}

		}

		/**
		 * Post types that are available for editing by the builder.
		 *
		 * @return array List of post types names
		 */
		private function get_allowed_edit_post_types() {
			return array_keys( us_get_public_post_types( array( /* add post types that should not yet be supported by US Builder here */ ) ) );
		}

		/**
		 * Add a link that will be displayed under the title of the record in the records table in the admin panel
		 *
		 * @access public
		 * @param array $actions
		 * @param \WP_Post $post The current post object.
		 * @return array
		 */
		public function row_actions( $actions, \WP_Post $post ) {
			if ( in_array( $post->post_type, $this->get_allowed_edit_post_types() ) ) {
				// Add a link to edit with USBuilder
				$edit_url = static::get_edit_permalink( $post->ID );
				$actions['edit_us_builder'] = '<a href="' . esc_url( $edit_url ) . '">' . strip_tags( __( 'Edit Live', 'us' ) ) . '</a>';
			}
			return $actions;
		}

		/**
		 * Add a button that switched editing to US builder
		 *
		 * @access public
		 * @param \WP_Post $post The current post object.
		 */
		public function output_builder_switch( \WP_Post $post ) {
			if ( ! in_array( $post->post_type, $this->get_allowed_edit_post_types() ) ) return;
			?>
			<div id="us-builder-switch">
				<a href="<?php echo static::get_edit_permalink( $post->ID ) ?>" class="button button-primary">
					<span><?php echo __( 'Edit Live', 'us' ); ?></span>
				</a>
			</div>
			<?php
		}

		/**
		 * The determines if builder page.
		 *
		 * @access public
		 * @return bool TRUE if builder page, FALSE otherwise
		 */
		final static public function is_builder_page() {
			global $pagenow;
			return (
				us_strtolower( basename( $pagenow, '.php' ) ) === 'post'
				AND ! empty( $_REQUEST[ 'post' ] )
				AND us_strtolower( us_arr_path( $_REQUEST, 'action' ) ) === static::get_slug()
			);
		}

		/**
		 *  The determines if builder preview page.
		 *
		 *  @access public
		 *  @return bool TRUE if builder page, FALSE otherwise
		 */
		final static public function is_preview_page() {
			$builder_slug = static::get_slug();
			if ( $nonce = us_arr_path( $_REQUEST, $builder_slug ) ) {
				return (bool) wp_verify_nonce( $nonce, $builder_slug );
			}
			return FALSE;
		}

		/**
		 * Get the edit permalink.
		 *
		 * @access public
		 * @param int $id The post ID
		 * @return string Link to edit page
		 */
		static public function get_edit_permalink( $post_id ) {
			return admin_url( '/post.php?post=' . (int) $post_id . '&action=' . static::get_slug() );
		}

		/**
		 * Remove prefix from shortcode name
		 *
		 * @access private
		 * @param string $shortcode_name The shortcode name
		 * @param string $prefix The shortcode prefix
		 * @return string
		 */
		static public function get_clean_shortcode_name( $shortcode_name, $prefix = 'us_' ) {
			return ( strpos( $shortcode_name, $prefix ) === 0 )
				? substr( $shortcode_name , strlen( $prefix ) )
				: $shortcode_name;
		}

		/**
		 * Initializing the builder page
		 *
		 * @access public
		 */
		public function init_builder_page() {
			$post_id = static::get_post_id();
			$builder_slug = static::get_slug();
			$builder_nonce = wp_create_nonce( $builder_slug );

			// The get edit page url
			$page_link = apply_filters( 'the_permalink', get_permalink( $post_id ) );
			$edit_page_link = get_edit_post_link( $post_id );

			/**
			 * Different templates that are required for the USBuilder to work on the frontend side
			 * @var array
			 */
			$templates = array(
				// TODO: move this to a config?
				'vc_row' => '[vc_row usbid="{%vc_row%}"][vc_column usbid="{%vc_column%}"]{%content%}[/vc_column][/vc_row]',
			);

			// VC TTA (Tabs/Tour/Accordion) Section ( The sections that are created with a new element )
			// TODO: move this to a config?
			$templates['vc_tta_section']  = '[vc_tta_section title="{%title_1%}" usbid="{%vc_tta_section_1%}"]';
			$templates['vc_tta_section'] .= '[vc_column_text usbid="{%vc_column_text%}"]{%vc_column_text_content%}[/vc_column_text]';
			$templates['vc_tta_section'] .= '[/vc_tta_section]';
			$templates['vc_tta_section'] .= '[vc_tta_section title="{%title_2%}" usbid="{%vc_tta_section_2%}"][/vc_tta_section]';

			// Get options for jsoncss generator
			$jsoncss_options = us_get_jsoncss_options();
			unset( $jsoncss_options['css_mask'] );

			// Create a list of colors variables, based on CSS vars
			$color_vars = array();
			foreach ( us_config( 'theme-options.colors.fields', array() ) as $color_option => $color_option_params ) {
				// Do not add empty color values
				if ( us_get_color( $color_option, TRUE, FALSE ) === '' ) {
					continue;
				}
				// Do not add variables without "color" prefix in its names
				if ( strpos( $color_option, 'color' ) !== 0 ) {
					continue;
				}
				// Remove "color" prefix
				$color_option = substr( $color_option, strlen( 'color' ) );
				// Add color to general list
				$color_vars[ $color_option ]  = us_get_color( $color_option, /* Gradient */ TRUE, /* CSS var */ TRUE );
			}

			// Create a list of global fonts variables, based on CSS vars
			// TODO: avoid hardcode when #2183 will be done
			$font_vars = array();
			foreach ( array( 'body', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ) as $font_name ) {
				$font_vars[ $font_name ] = us_get_font_family( $font_name );
			}

			/**
			 * Get responsive states
			 * @var array
			 */
			$states = (array) us_get_responsive_states();

			/**
			 * The general settings for US Builder
			 *
			 * NOTE! All parameters and data are used on the front-end in USBuilder
			 * and changing or deleting may break the work of the USBuilder.
			 */
			$usb_settings = (array) USBuilder_Ajax::get_actions();
			$usb_settings += array(
				'_nonce' => USBuilder_Ajax::create_nonce(),

				// Meta key for post custom css
				'metaKeyForCustomCss' => self::META_KEY_FOR_CUSTOM_CSS,

				// Settings for shortcodes
				'shortcode' => array(
					// List of container shortcodes (e.g. [us_hwrapper]...[/us_hwrapper])
					'containers' => array(),
					// List of shortcodes which have inner content (e.g. [us_message]...[/us_message]), but shouldn't be containers
					'edit_content' => array(),
					// List of default values for shortcodes
					'default_values' => array(),
					// The a list of strict relations between shortcodes (separate multiple values with comma)
					'relations' => array(
						'as_parent' => array(
							// Since we introduced a new type of root container at the level of shortcodes and builder,
							// then we will add a rule for it that should be ignored when adding a new element
							self::MAIN_CONTAINER => array(
								'only' => 'vc_row',
							),
						),
					),
				),

				// Default placeholder (Used in importing shortcodes)
				'placeholder' => us_get_img_placeholder( 'full', TRUE ),

				// Post types for selection in Grid element (Used in importing shortcodes)
				'grid_post_types' => us_grid_available_post_types_for_import(),

				// Templates shortcodes or html
				'template' => $templates,

				// Default parameters for AJAX requests
				'ajaxArgs' => array(
					$builder_slug => $builder_nonce,
					'post_id' => $post_id,
				),

				// The set responsive states
				'responsiveStates' => array_keys( $states ),

				// Get breakpoints of responsive states
				'breakpoints' => $states,

				// Settings for the css compiler
				'designOptions' => array_merge(
					$jsoncss_options,
					array(
						'customPrefix' => 'usb_custom_', // prefix for custom classes when generating styles from design options
						'fontVars' => $font_vars,
						'colorVars' => $color_vars,
					)
				),
			);

			unset( $vc_row_template, $vc_row_html_template, $handler_add_usbid_to_html );

			if ( is_rtl() ) {
				$this->_body_classes[] = 'rtl';
			}

			$fieldsets = $elms_categories = $js_init_list = array();

			// Get all elements available in the theme
			foreach ( us_config( 'shortcodes.theme_elements', array(), TRUE ) as $elm_filename ) {
				if ( $elm_config = us_config( "elements/$elm_filename", array() ) ) {
					// Ignore elements which are not available via condition
					if ( isset( $elm_config['place_if'] ) AND ! $elm_config['place_if'] ) {
						continue;
					}
					$fieldsets[ $elm_filename ] = $elm_config;
					// The list of all containers
					if ( ! empty( $elm_config['is_container'] ) ) {
						$usb_settings['shortcode']['containers'][] = $elm_filename;
					}
					// The list of strict relations between shortcodes
					// All permissions are extracted from WPB settings for compatibility and correct work both on the USBuilder and WPB
					foreach ( array( 'as_parent', 'as_child' ) as $relation ) {
						if (
							isset( $elm_config[ $relation ] ) AND
							! empty( $elm_config[ $relation ] ) AND
							is_array( $elm_config[ $relation ] )
						) {
							$separator = ',';
							foreach ( $elm_config[ $relation ] as $condition => $shortcodes ) {
								if ( $shortcodes = explode( $separator, $shortcodes ) ) {
									foreach ( $shortcodes as &$shortcode ) {
										$shortcode = static::get_clean_shortcode_name( $shortcode );
									}
								}
								if ( is_array( $shortcodes ) ) {
									/**
									 * Checking a condition for correctness or absence ( Required only|except )
									 * @link https://kb.wpbakery.com/docs/developers-how-tos/nested-shortcodes-container/
									 * @var string
									 */
									$condition = in_array( $condition, array( 'only', 'except' ) )
										? $condition
										: 'only';
									// Separate multiple values with comma
									$shortcodes = implode( $separator, $shortcodes );
									$usb_settings['shortcode']['relations'][ $relation ][ $elm_filename ][ $condition ] = $shortcodes;
								}
							}
						}
					}
					// Create elements list
					$elm_filename = us_get_shortcode_full_name( $elm_filename );
					$elms_categories[ us_arr_path( $elm_config, 'category', '' ) ][ $elm_filename ] = array(
						'hide_on_adding_list' => us_arr_path( $elm_config, 'hide_on_adding_list', '' ),
						'icon' => us_arr_path( $elm_config, 'icon', '' ),
						'is_container' => us_arr_path( $elm_config, 'is_container', FALSE ),
						'title' => us_arr_path( $elm_config, 'title', $elm_filename ),
					);
				}
			}

			// Shortcodes that contain inner content for the editor as a value
			foreach ( $fieldsets as $elm_name => $fieldset ) {
				foreach ( us_arr_path( $fieldset, 'params', array() ) as $param_name => $options ) {

					// Get default values for the edited content, if any
					if ( $param_name === 'content' OR $options['type'] === 'editor' ) {
						$elm_name = static::get_clean_shortcode_name( $elm_name );
						$usb_settings['shortcode']['edit_content'][ $elm_name ] = $param_name;
						if ( ! empty( $options['std'] ) ) {
							$usb_settings['shortcode']['default_values'][ $elm_name ][ $param_name ] = $options['std'];
						}
					}

					// Get default values for select
					if ( $options['type'] === 'select' AND empty( $options['std'] ) AND is_array( $options['options'] ) ) {
						$keys = array_keys( $options['options'] );
						if ( $value = us_arr_path( $keys, '0' ) ) {
							$usb_settings['shortcode']['default_values'][ $elm_name ][ $param_name ] = $value;
						}
					}

					// For the Group default value transform array to a string (compatibility with WPBakery builder)
					if ( $options['type'] == 'group' AND ! empty( $options['std'] ) ) {
						$elm_name = static::get_clean_shortcode_name( $elm_name );
						$usb_settings['shortcode']['default_values'][ $elm_name ][ $param_name ] = rawurlencode( json_encode( $options['std'] ) );
					}

					// Remove prefixes needed for compatibility from Visual Composer
					if ( ! empty( $options['type'] ) ) {
						$fieldsets[ $elm_name ]['params'][ $param_name ]['type'] = static::get_clean_shortcode_name( $options['type'] );
					}
				}
			}

			/**
			 * Texts for the builder and different custom messages
			 * NOTE: Translation keys are duplicated in JavaScript files!
			 * @var array
			 */
			$text_translations = array(
				'all_inner_elms_del' => __( 'All inner elements will also be deleted.', 'us' ),
				'page_leave_warning' => us_translate( 'The changes you made will be lost if you navigate away from this page.' ),
				'page_updated' => sprintf( '%s <a href="%s" target="_blank">%s</a>', us_translate( 'Page updated.' ), $page_link, us_translate( 'View Page' ) ),
				'editing_not_supported' => __( 'Editing of this element is not supported.', 'us' ) . sprintf( '<br><a href="%s" target="_blank">%s</a>', $edit_page_link, __( 'Edit page in Backend', 'us' ) ),
				'section' => __( 'Section', 'us' ),
				'paste_row' => __( 'Paste Row/Section', 'us' ),
				'page_custom_css' => __( 'Page Custom CSS', 'us' ),
				'invalid_data' => us_translate( 'Invalid data provided.' ),
			);

			// Formation of the title of the edited page
			$admin_page_title = strip_tags( __( 'Edit Live', 'us' ) . ' - ' . get_the_title( $post_id ) );

			// Apply filters for `body_classes`
			$this->_body_classes = (array) apply_filters( 'usb_body_classes', $this->_body_classes );

			// The formation of the main page
			us_load_template(
				'builder/templates/main', array(
					'ajaxurl' => admin_url( 'admin-ajax.php' ),
					'body_classes' => implode( ',', $this->_body_classes ),
					'builder_slug' => $builder_slug,
					'edit_page_link' => $edit_page_link,
					'elms_categories' => $elms_categories,
					'fieldsets' => $fieldsets,
					'iframe_page_url' => add_query_arg( $builder_slug, $builder_nonce, $page_link ),
					'js_init_list' => $js_init_list,
					'page_link' => $page_link,
					'text_translations' => $text_translations,
					'title' => $admin_page_title,
					'usb_settings' => $usb_settings,
				)
			);
			exit;
		}
	}
}
