[]];
			return \gp\tool\Files::$last_modified;
		}
		public static function CheckArray($array, $update_data){
			foreach($array as $addon => $addon_info){
				$addon_id = false;
				if( isset($addon_info['id']) ){
					$addon_id = $addon_info['id'];
				}elseif( isset($addon_info['addon_id']) ){ //for layouts
					$addon_id = $addon_info['addon_id'];
				}
				if( !$addon_id || !isset($update_data['packages'][$addon_id]) ){
					continue;
				}
				$installed_version = 0;
				if( isset($addon_info['version']) ){
					$installed_version = $addon_info['version'];
				}
				$new_addon_info = $update_data['packages'][$addon_id];
				$new_addon_version = $new_addon_info['version'];
				if( version_compare($installed_version, $new_addon_version, '>=') ){
					continue;
				}
				//new version found
				if( !isset($new_addon_info['name']) && isset($addon_info['name']) ){
					$new_addon_info['name'] = $addon_info['name'];
				}
				self::$new_versions[$addon_id] = $new_addon_info;
			}
		}
		public static function AdminScripts(){
			global $langmessage, $config;
			$scripts = [];
			// Content
			$scripts['Admin/Menu'] = [
				'class'		=> '\\gp\\admin\\Menu',
				'method'	=> 'RunScript',
				'label'		=> $langmessage['file_manager'],
				'group'		=> 'content',
			];
			$scripts['Admin/Menu/Menus'] = [
				'class'		=> '\\gp\\admin\\Menu\\Menus',
				'method'	=> 'RunScript',
			];
			$scripts['Admin/Menu/Ajax'] = [
				'class'		=> '\\gp\\admin\\Menu\\Ajax',
				'method'	=> 'RunScript',
			];
			$scripts['Admin/Uploaded'] = [
				'class'		=> '\\gp\\admin\\Content\\Uploaded',
				'method'	=> 'RunScript',
				'label'		=> $langmessage['uploaded_files'],
				'group'		=> 'content',
			];
			$scripts['Admin/Extra'] = [
				'class'		=> '\\gp\\admin\\Content\\Extra',
				'method'	=> 'RunScript',
				'label'		=> $langmessage['theme_content'],
				'group'		=> 'content',
			];
			$scripts['Admin/Galleries'] = [
				'class'		=> '\\gp\\admin\\Content\\Galleries',
				'label'		=> $langmessage['galleries'],
				'group'		=> 'content',
			];
			$scripts['Admin/Trash'] = [
				'class'		=> '\\gp\\admin\\Content\\Trash',
				'label'		=> $langmessage['trash'],
				'group'		=> 'content',
			];
			// Appearance
			$scripts['Admin_Theme_Content'] = [
				'class'		=> '\\gp\\admin\\Layout',
				'method'	=> 'RunScript',
				'label'		=> $langmessage['Appearance'],
				'group'		=> 'appearance',
			];
			$scripts['Admin_Theme_Content/Edit'] = [
				'class'		=> '\\gp\\admin\\Layout\\Edit',
				'method'	=> 'RunScript',
				'label'		=> $langmessage['layouts'],
			];
			$scripts['Admin_Theme_Content/Available'] = [
				'class'		=> '\\gp\\admin\\Layout\\Available',
				'method'	=> 'ShowAvailable',
				'label'		=> $langmessage['Available'] . ' (' . $langmessage['layouts'] . ')',
			];
			$scripts['Admin_Theme_Content/Text'] = [
				'class'		=> '\\gp\\admin\\Layout\\Text',
				'method'	=> 'RunScript',
			];
			$scripts['Admin_Theme_Content/Image'] = [
				'class'		=> '\\gp\\admin\\Layout\\Image',
				'method'	=> 'RunScript',
			];
			if( gp_remote_themes ){
				$scripts['Admin_Theme_Content/Remote'] = [
					'class'		=> '\\gp\\admin\\Layout\\Remote',
					'method'	=> 'DefaultDisplay',
					'label'		=> $langmessage['Search'] . ' (' . $langmessage['layouts'] . ')',
				];
			}
			// Settings
			$scripts['Admin/Configuration'] = [
				'class'		=> '\\gp\\admin\\Configuration',
				'method'	=> 'RunScript',
				'label'		=> $langmessage['configuration'],
				'group'		=> 'settings',
			];
			$scripts['Admin/Configuration/CDN'] = [
				'class'		=> '\\gp\\admin\\Configuration\\CDN',
				'method'	=> 'RunScript',
				'label'		=> 'CDN',
				'group'		=> 'settings',
			];
			$scripts['Admin/Users'] = [
				'class'		=> '\\gp\\admin\\Settings\\Users',
				'method'	=> 'RunScript',
				'label'		=> $langmessage['user_permissions'],
				'group'		=> 'settings',
			];
			$scripts['Admin/Permissions'] = [
				'class'		=> '\\gp\\admin\\Settings\\Permissions',
				'method'	=> 'RunScript',
			];
			$scripts['Admin/CKEditor'] = [
				'class'		=> '\\gp\\admin\\Settings\\CKEditor',
				'label'		=> 'CKEditor',
				'group'		=> 'settings',
			];
			$scripts['Admin/Classes'] = [
				'class'		=> '\\gp\\admin\\Settings\\Classes',
				'label'		=> $langmessage['Manage Classes'],
				'group'		=> 'settings',
			];
			$scripts['Admin/Permalinks'] = [
				'class'		=> '\\gp\\admin\\Settings\\Permalinks',
				'label'		=> $langmessage['permalinks'],
				'group'		=> 'settings',
			];
			$scripts['Admin/Missing'] = [
				'class'		=> '\\gp\\admin\\Settings\\Missing',
				'method'	=> 'RunScript',
				'label'		=> $langmessage['Link Errors'],
				'group'		=> 'settings',
			];
			// Tools
			$scripts['Admin/Port'] = [
				'class'		=> '\\gp\\admin\\Tools\\Port',
				'label'		=> $langmessage['Export'],
				'group'		=> 'tools',
				'method'	=> 'RunScript',
			];
			$scripts['Admin/Status'] = [
				'class'		=> '\\gp\\admin\\Tools\\Status',
				'label'		=> $langmessage['Site Status'],
				'group'		=> 'tools',
				'method'	=> 'RunScript',
			];
			$scripts['Admin/Uninstall'] = [
				'class'		=> '\\gp\\admin\\Tools\\Uninstall',
				'label'		=> $langmessage['uninstall_prep'],
				'group'		=> 'tools',
			];
			$scripts['Admin/Cache'] = [
				'class'		=> '\\gp\\admin\\Tools\\Cache',
				'label'		=> $langmessage['Resource Cache'],
				'group'		=> 'tools',
			];
			// Unlisted
			$scripts['Admin/Addons'] = [
				'class'		=> '\\gp\\admin\\Addons',
				'method'	=> 'RunScript',
				'label' 	=> $langmessage['plugins'],
			];
			$scripts['Admin/Addons/Available'] = [
				'class'		=> '\\gp\\admin\\Addon\\Available',
				'method'	=> 'DefaultDisplay',
				'label' 	=> $langmessage['Available'] . ' (' . $langmessage['plugins'] . ')',
			];
			if( gp_remote_plugins ){
				$scripts['Admin/Addons/Remote'] = [
					'class'		=> '\\gp\\admin\\Addon\\Remote',
					'method'	=> 'DefaultDisplay',
					'label'		=> $langmessage['Search'] . ' (' . $langmessage['plugins'] . ')',
				];
			}
			$scripts['Admin/Errors'] = [
				'class'			=> '\\gp\\admin\\Tools\\Errors',
				'label' 		=> 'Errors',
			];
			$scripts['Admin/About'] = [
				'class'			=> '\\gp\\admin\\About',
				'label'			=> 'About ' . CMS_NAME,
			];
			$scripts['Admin/Browser'] = [
				'class'			=> '\\gp\\admin\\Content\\Browser',
				'permission'	=> 'Admin_Uploaded',
			];
			$scripts['Admin/Preferences'] = [
				'class'			=> '\\gp\\admin\\Settings\\Preferences',
				'label'			=> $langmessage['Preferences'],
			];
			$scripts['Admin/Notifications'] = [
				'class'			=> '\\gp\\admin\\Notifications',
				'method'		=> 'ListNotifications',
				'label'			=> $langmessage['Notifications'],
			];
			$scripts['Admin/Notifications/Manage'] = [
				'class'			=> '\\gp\\admin\\Notifications',
				'method'		=> 'ManageNotifications',
				'permission'	=> 'Admin/Notifications',
			];
			$scripts['Admin/Revisions'] = [
				'class'			=> '\\gp\\admin\\Content\\Revisions',
				'method'		=> 'RunScript',
			];
			// Addon admin links
			if( isset($config['admin_links']) && is_array($config['admin_links']) ){
				foreach( $config['admin_links'] as $link_name => $addon_info ){
					$link_label = $addon_info['label'];
					$link_label	= \gp\tool\Plugins::Filter('AdminLinkLabel', [$link_label, $link_name]);
					$config['admin_links'][$link_name]['label'] = $link_label;
				}
				//prefix admin link labels with plugin icon
				$admin_links = $config['admin_links'];
				foreach( $admin_links as $link_name => $addon_info ){
					$addon_name = $config['addons'][$addon_info['addon']]['name'];
					$admin_links[$link_name]['label'] = ' ' . $addon_info['label'];
				}
				$scripts += $admin_links;
			}
			gpSettingsOverride('admin_scripts', $scripts);
			return $scripts;
		}
		/**
		 * Determine if the current user has permissions for the $script
		 * @static
		 * @return bool
		 *
		 */
		public static function HasPermission($script){
			global $gpAdmin;
			if( is_array($gpAdmin) ){
				$gpAdmin += ['granted' => ''];
				return self::CheckPermission($gpAdmin['granted'], $script);
			}
			return false;
		}
		/**
		 * Determine if a user has permissions for the $script
		 * @static
		 * @since 3.0b2
		 * @return bool
		 *
		 */
		public static function CheckPermission($granted,$script){
			if( $granted == 'all' ){
				return true;
			}
			$script		= self::WhichPermission($script);
			$granted	= ',' . $granted . ',';
			if( strpos($granted, ',' . $script . ',') !== false ){
				return true;
			}
			return false;
		}
		/**
		 * Return the permission setting that should be checked against a list of grated permissions
		 * Admin_Browser -> Admin_Uploaded
		 * Admin_Theme_Content/Text -> Admin_Theme_Content
		 *
		 */
		public static function WhichPermission($script){
			// prepare list of permissions
			$scripts	= self::AdminScripts();
			$possible	= [];
			foreach($scripts as $pscript => $info){
				$pscript = str_replace('/', '_', $pscript);
				if( isset($info['permission']) ){
					$possible[$pscript] = $info['permission'];
				}elseif( isset($info['label']) ){
					$possible[$pscript] = $pscript;
				}
			}
			// find the relevant permission in the list of possible permissions
			$script		= str_replace('/', '_', $script);
			$parts 		= explode('_', $script);
			while($parts){
				$check = implode('_', $parts);
				if( !isset($possible[$check]) ){
					array_pop($parts);
					continue;
				}
				return $possible[$check];
			}
			return $script;
		}
		/**
		 * Determine if a user can edit a specific page
		 * @static
		 * @since 3.0b2
		 * @param string $index The data index of the page
		 * @return bool
		 *
		 */
		public static function CanEdit($index){
			global $gpAdmin;
			//pre 3.0 check
			if( !isset($gpAdmin['editing']) ){
				return self::HasPermission('file_editing');
			}
			if( $gpAdmin['editing'] == 'all' ){
				return true;
			}
			if( strpos($gpAdmin['editing'], ',' . $index . ',') !== false ){
				return true;
			}
			return false;
		}
		/**
		 * Used to update the basic 'file_editing' permission value to the new 'editing' value used in 3.0b2+
		 * @since 3.0b2
		 * @static
		 *
		 */
		public static function EditingValue(&$user_info){
			if( isset($user_info['editing']) ){
				return;
			}
			if( self::CheckPermission($user_info['granted'], 'file_editing') ){
				$user_info['editing'] = 'all';
				return 'all';
			}
			$user_info['editing'] = '';
		}
		/**
		 * Output the main admin toolbar
		 * @static
		 *
		 */
		public static function GetAdminPanel(){
			global $page, $gpAdmin;
			//don't send the panel when it's a gpreq=json request
			if( !self::$show_toolbar ){
				return;
			}
			\gp\tool::LoadComponents('gp-admin-toolbar');
			$reqtype = \gp\tool::RequestType();
			if( $reqtype != 'template' && $reqtype != 'admin' ){
				return;
			}
			$class = '';
			$position = '';
			if( \gp\tool::RequestType() != 'admin' ){
				$position = ' style="top:' . max(-10, $gpAdmin['gpui_ty']) . 'px;'
					. 'left:' . max(-10, $gpAdmin['gpui_tx']) . 'px"';
				if( isset($gpAdmin['gpui_cmpct']) && $gpAdmin['gpui_cmpct'] ){
					$class = ' compact';
					if( $gpAdmin['gpui_cmpct'] === 2 ){
						$class = ' compact min';
					}elseif( $gpAdmin['gpui_cmpct'] === 3 ){
						$class = ' minb';
					}
				}
			}
			$class = ' class="keep_viewable' . $class.'"';
			echo "\n\n";
			echo '
';
			//toolbar
			echo '
';
			self::AdminPanelLinks(true);
			echo '
 '; //end simplepanel
			echo "\n\n";
			self::AdminToolbar();
		}
		/**
		 * Show Admin Toolbar
		 *
		 */
		public static function AdminToolbar(){
			global $page, $langmessage;
			if( !method_exists($page, 'AdminLinks') ){
				return;
			}
			if( isset($GLOBALS['GP_ARRANGE_CONTENT']) ){
				return;
			}
			$links = $page->AdminLinks();
			if( empty($links) ){
				return;
			}
			echo '';
			echo '
';
			//admin_link
			self::FormatAdminLinks($links);
			echo '
';
			self::ToolbarEditLinks();
			echo '
 ';
		}
		/**
		 * Toolbar edit links
		 *
		 */
		public static function ToolbarEditLinks(){
			global $page, $gp_titles, $langmessage;
			if( !\gp\admin\Tools::CanEdit($page->gp_index) ){
				return;
			}
			$links = [];
			//page edit
			if( $page->pagetype == 'display' ){
				$links[] = \gp\tool::Link(
					$page->title,
					' ' . $langmessage['Sections'],
					'cmd=ManageSections',
					[
						'data-cmd'	=> 'inline_edit_generic',
						'data-arg'	=> 'manage_sections'
					]
				);
			}
			//extra edit
			$links[] = \gp\tool::Link(
				$page->title,
				' ' . $langmessage['theme_content'],
				'cmd=ManageSections&mode=extra',
				[
					'data-cmd'	=> 'inline_edit_generic',
					'data-arg'	=> 'manage_sections',
					'data-mode'	=> 'extra',
					'class'		=> 'gp_extra_edit'
				]
			);
			//layout edit
			$links[] = \gp\tool::Link(
				'Admin_Theme_Content/Edit/' . urlencode( \gp\tool::GetCurrentLayoutId() ),
				' ' . $langmessage['layout'],
				'redir=' . rawurlencode($page->requested)
			);
			//revision history
			$links[] = \gp\tool::Link(
				'/Admin/Revisions/'.$page->gp_index,
				' ' . $langmessage['Revision History'],
				'',
				[
					'title'		=> $langmessage['Revision History'],
					'class'		=> 'admin-link admin-link-revision-history',
				]
			);
			echo '';
			self::FormatAdminLinks($links);
			echo '
';
		}
		public static function FormatAdminLinks($links){
			global $langmessage;
			foreach($links as $label => $link){
				echo '';
				if( is_numeric($label) ){
					if( is_array($link) ){
						echo call_user_func_array(['\\gp\\tool', 'Link'], $link); /* preferred */
					}else{
						echo $link; //just a text label
					}
					echo '';
					continue;
				}
				if( empty($link) ){
					echo '';
					echo $label;
					echo '';
				}elseif( is_array($link) ){
					$add_class = ($label == $langmessage['options']) ? ' admin-link-dropdown-options' : '';
					echo '';
					echo ' ' . $label;
					echo '';
					echo '';
					self::FormatAdminLinks($link);
					echo '
';
				}else{
					echo '';
					echo $label;
					echo '';
				}
				echo '';
			}
		}
		/**
		 * Output the link areas that are displayed in the main admin toolbar and admin_main
		 * @param bool $in_panel Whether or not the links will be displayed in the toolbar
		 * @static
		 *
		 */
		public static function AdminPanelLinks($in_panel=true){
			global $langmessage, $page, $gpAdmin;
			//content
			$links = self::GetAdminGroup('content');
			self::_AdminPanelLinks($in_panel, $links, 'Content', 'fa fa-file-text', 'con');
			//appearance
			$links = self::GetAppearanceGroup($in_panel);
			self::_AdminPanelLinks($in_panel, $links, 'Appearance', 'fa fa-th', 'app');
			//add-ons
			$addon_links = self::GetAddonLinks($in_panel); // now returns array( (string)links, (boolean)permissions )
			$links = $addon_links[0];
			$addon_permissions = $addon_links[1];
			// msg("Any Addon Permisisons? " . pre($addon_permissions) );
			if( $addon_permissions ){
				self::_AdminPanelLinks($in_panel, $links, 'plugins', 'fa fa-plug', 'add');
			}
			//settings
			$links = self::GetAdminGroup('settings');
			self::_AdminPanelLinks($in_panel, $links, 'Settings', 'fa fa-sliders', 'set');
			//tools
			$links = self::GetAdminGroup('tools');
			self::_AdminPanelLinks($in_panel, $links, 'Tools', 'fa fa-wrench', 'tool');
			//notifications
			if( \gp\admin\Tools::HasPermission('Admin/Notifications') ){
				$notifications = new \gp\admin\Notifications();
				$notifications->GetNotifications($in_panel);
			}
			//username
			ob_start();
			self::GetFrequentlyUsed($in_panel);
			echo '';
			echo \gp\tool::Link('Admin/Preferences', $langmessage['Preferences']);
			echo '';
			echo '';
			echo \gp\tool::Link(
					$page->title,
					$langmessage['logout'],
					'cmd=logout',
					['data-cmd' => 'cnreq']
				);
			echo '';
			echo '';
			echo \gp\tool::Link('Admin/About', 'About ' . CMS_NAME);
			echo '';
			$links = ob_get_clean();
			self::_AdminPanelLinks($in_panel, $links, $gpAdmin['useralias'], 'fa fa-user-circle', 'use');
			// stats
			ob_start();
			echo '? Memory';
			echo '? Max Memory';
			echo '? Seconds';
			echo '? Milliseconds';
			echo '0 DB Queries';
			$links = ob_get_clean();
			self::_AdminPanelLinks($in_panel, $links, 'Performance', 'fa fa-bar-chart', 'cms');
			//resources
			if( $page->pagetype === 'admin_display' ){
				ob_start();
				if( gp_remote_plugins && self::HasPermission('Admin_Addons') ){
					echo '';
					echo \gp\tool::Link('Admin/Addons/Remote', $langmessage['Download Plugins']);
					echo '';
				}
				if( gp_remote_themes && self::HasPermission('Admin_Theme_Content') ){
					echo '';
					echo \gp\tool::Link('Admin_Theme_Content/Remote', $langmessage['Download Themes']);
					echo '';
				}
				echo 'Support Forum';
				echo 'Service Providers';
				echo 'Official ' . CMS_NAME . ' Site';
				echo 'Report A Bug';
				$links = ob_get_clean();
				self::_AdminPanelLinks($in_panel, $links, 'resources', 'fa fa-globe', 'res');
				if( $in_panel ){
					echo '';
					echo CMS_NAME . ' ' . gpversion;
					echo '
';
				}
			}
		}
		/**
		 * Get the appropriate remote browse url if available
		 *
		 */
		public static function RemoteUrl($type){
			if( $type == 'theme' || $type == 'themes' ){
				if( gp_remote_themes ){
					return addon_browse_path . '/Themes';
				}
			}
			if( $type == 'plugin' || $type == 'plugins' ){
				if( gp_remote_plugins ){
					return addon_browse_path . '/Plugins';
				}
			}
			return false;
		}
		/**
		 * Helper function for outputting link groups in AdminPanelLinks()
		 * as of 5.2-rc new params:
		 * @param string $class, CSS class(es) for panelgroup, TODO: better make it $attrs?
		 * @param string $badge, HTML for optional badge, TODO: should be better an array of separated class and content
		 *
		 */
		public static function _AdminPanelLinks($in_panel, $links, $lang_key, $icon_class, $panel_arg, $class='', $badge=''){
			global $langmessage;
			if( empty($links) ){
				return;
			}
			$label = isset($langmessage[$lang_key]) ? $langmessage[$lang_key] : $lang_key;
			echo '';
			self::PanelHeading($in_panel, $label, $icon_class, $panel_arg, $badge);
			echo '';
			echo '
';
			echo '';
		}
		public static function PanelHeading($in_panel, $label, $icon, $arg, $badge){
			global $gpAdmin;
			if( !$in_panel ){
				echo '';
				echo ' ';
				echo '' . $label . '';
				echo '';
				echo '';
				return;
			}
			echo '
';
			echo '';
			echo '' . $label . '';
			echo $badge;
			echo '';
			if( $gpAdmin['gpui_vis'] == $arg ){
				echo '
';
			}else{
				echo '
';
			}
		}
		/**
		 * Get the links for the Frequently Used section of the admin toolbar
		 *
		 */
		public static function GetFrequentlyUsed($in_panel){
			global $langmessage, $gpAdmin;
			$expand_class = 'expand_child';
			if( !$in_panel ){
				$expand_class = 'expand_child_click';
			}
			//frequently used
			echo '
';
			echo '';
			echo $langmessage['frequently_used'];
			echo '';
			if( $in_panel ){
				echo '';
			}else{
				echo '';
			}
			$scripts = self::AdminScripts();
			$add_one = true;
			if( isset($gpAdmin['freq_scripts']) ){
				foreach($gpAdmin['freq_scripts'] as $link => $hits ){
					if( isset($scripts[$link]) && isset($scripts[$link]['label']) ){
						echo '- ';
						echo \gp\tool::Link($link, $scripts[$link]['label']);
						echo '
 ';
						if( $link === 'Admin/Menu' ){
							$add_one = false;
						}
					}
				}
				if( $add_one && count($gpAdmin['freq_scripts']) >= 5 ){
					$add_one = false;
				}
			}
			if( $add_one ){
				echo '- ';
				echo \gp\tool::Link('Admin/Menu', $scripts['Admin/Menu']['label']);
				echo '
 ';
			}
			echo '
';
			echo '
';
		}
		/**
		 * Ues $update_status from update codes to execute some cleanup code
		 * on a regular interval (7 days)
		 *
		 */
		public static function ScheduledTasks(){
			global $dataDir;
			switch(self::$update_status){
				case 'embedcheck':
				case 'checkincompat':
					//these will continue
				break;
				case 'checklater':
				default:
				return;
			}
			self::CleanCache();
		}
		/**
		 * Delete all files older than 2 weeks
		 * If there are more than 200 files older than one week
		 *
		 */
		public static function CleanCache(){
			global $dataDir;
			$dir = $dataDir . '/data/_cache';
			if( !file_exists($dir) ){
				return;
			}
			$files = scandir($dir);
			$times = [];
			foreach($files as $file){
				if( $file == '.' || $file == '..' || strpos($file, '.php') !== false ){
					continue;
				}
				$full_path	= $dir . '/' . $file;
				$time		= filemtime($full_path);
				$diff		= time() - $time;
				//if relatively new ( < 3 days), don't delete it
				if( $diff < 259200 ){
					continue;
				}
				//if old ( > 14 days ), delete it
				if( $diff > 1209600 ){
					\gp\tool\Files::RmAll($full_path);
					continue;
				}
				$times[$file] = $time;
			}
			//reduce further if needed till we have less than 200 files
			arsort($times);
			$times = array_keys($times);
			while( count($times) > 200 ){
				$full_path = $dir . '/' . array_pop($times);
				\gp\tool\Files::RmAll($full_path);
			}
		}
		public static function AdminHtml(){
			global $page, $gp_admin_html;
			ob_start();
			echo '
';
			if( isset($page->admin_html) ){
				echo $page->admin_html;
			}
			self::GetAdminPanel();
			self::CheckStatus();
			self::ScheduledTasks();
			$gp_admin_html = ob_get_clean() . $gp_admin_html;
		}
		public static function CheckStatus(){
			switch(self::$update_status){
				case 'embedcheck':
					$img_path = \gp\tool::GetUrl('Admin', 'cmd=embededcheck');
					\gp\tool::IdReq($img_path);
				break;
				case 'checkincompat':
					$img_path = \gp\tool::IdUrl('ci'); //check in
					\gp\tool::IdReq($img_path);
				break;
			}
		}
		public static function GetAdminGroup($grouping){
			global $langmessage, $page;
			$scripts = self::AdminScripts();
			ob_start();
			foreach($scripts as $script => $info){
				if( !isset($info['group']) || $info['group'] !== $grouping ){
					continue;
				}
				if( !self::HasPermission($script) ){
					continue;
				}
				echo '
';
				if( isset($info['popup']) && $info['popup'] == true ){
					echo \gp\tool::Link(
							$script,
							$info['label'],
							'',
							['data-cmd' => 'gpabox']
						);
				}else{
					echo \gp\tool::Link(
							$script,
							$info['label']
						);
				}
				echo '';
				switch($script){
					case 'Admin/Menu':
						echo '
';
						echo \gp\tool::Link(
								'Admin/Menu/Ajax',
								'+ ' . $langmessage['create_new_file'],
								'cmd=AddHidden&redir=redir',
								[
									'title'		=> $langmessage['create_new_file'],
									'data-cmd'	=> 'gpabox',
								]
							);
						echo '';
						break;
				}
			}
			$result = ob_get_clean();
			if( !empty($result) ){
				return $result;
			}
			return false;
		}
		public static function GetAppearanceGroup($in_panel){
			global $page, $langmessage, $gpLayouts, $config;
			if( !self::HasPermission('Admin_Theme_Content') ){
				return false;
			}
			ob_start();
			echo '
';
			echo \gp\tool::Link('Admin_Theme_Content', $langmessage['manage']);
			echo '';
			if( !empty($page->gpLayout) ){
				echo '
';
				echo \gp\tool::Link(
						'Admin_Theme_Content/Edit/' . urlencode($page->gpLayout),
						$langmessage['edit_this_layout']
					);
				echo '';
			}
			echo '
';
			echo \gp\tool::Link(
					'Admin_Theme_Content/Available',
					$langmessage['available_themes']
				);
			echo '';
			if( gp_remote_themes ){
				echo '
';
				echo \gp\tool::Link(
						'Admin_Theme_Content/Remote',
						$langmessage['Download Themes']
					);
				echo '';
			}
			//list of layouts
			$expand_class = 'expand_child';
			if( !$in_panel ){
				$expand_class = 'expand_child_click';
			}
			echo '
';
			echo '' . $langmessage['layouts'] . '';
			if( $in_panel ){
				echo '';
			}else{
				echo '';
			}
			if( !empty($page->gpLayout) ){
				$to_hightlight = $page->gpLayout;
			}else{
				$to_hightlight = $config['gpLayout'];
			}
			foreach($gpLayouts as $layout => $info){
				if( $to_hightlight == $layout ){
					echo '- ';
				}else{
					echo '
 - ';
				}
				$display = '' .
					'  ' . $info['label'];
				echo \gp\tool::Link(
						'Admin_Theme_Content/Edit/' . rawurlencode($layout),
						$display
					);
				echo '
 ';
			}
			echo '
';
			echo '
';
			return ob_get_clean();
		}
		/**
		 * Clean a string for use in a page label
		 * Some tags will be allowed
		 *
		 */
		public static function PostedLabel($string){
			// Remove control characters
			$string = preg_replace('#[[:cntrl:]]#u', '', $string); //[\x00-\x1F\x7F]
			//change known entities to their character equivalent
			$string = \gp\tool\Strings::entity_unescape($string);
			return self::LabelHtml($string);
		}
		/**
		 * Convert a label to a slug
		 * Does not use PostedSlug() so entity_unescape isn't called twice
		 * @since 2.5b1
		 *
		 */
		public static function LabelToSlug($string){
			return self::PostedSlug($string, true);
		}
		/**
		 * Clean a slug posted by the user
		 * @param string $slug The slug provided by the user
		 * @return string
		 * @since 2.4b5
		 *
		 */
		public static function PostedSlug($string, $from_label=false){
			global $config;
			$orig_string	= $string;
			$string			= \gp\tool\Editing::Sanitize($string);
			//illegal characters
			$string = str_replace(
				['?',	'*',	':',	'|'],
				['',	'',		'',		''],
				$string
			);
			//change known entities to their character equivalent
			$string = \gp\tool\Strings::entity_unescape($string);
			//if it's from a label, remove any html
			if( $from_label ){
				$string = self::LabelHtml($string);
				$string = strip_tags($string);
				//after removing tags, unescape special characters
				$string = str_replace(
					['<',	'>',	'"',	''',	'&'],
					['<',		'>',	'"',		"'", 		'&'],
					$string
				);
			}
			// # character after unescape for entities and unescape of special chacters when $from_label is true
			$string = str_replace('#', '', $string);
			//slashes
			$string = self::SlugSlashes($string);
			$string = str_replace(' ', $config['space_char'], $string);
			return \gp\tool\Plugins::Filter('PostedSlug', [$string, $orig_string, $from_label]);
		}
		/**
		 * Fix the html for page labels
		 *
		 */
		public static function LabelHtml($string){
			//prepend with space for preg_split(), space will be trimmed at the end
			$string = ' ' . $string;
			//change non html entity uses of & to & (not exact but should be sufficient)
			$pieces = preg_split('#(&(?:\#[0-9]{2,4}|[a-zA-Z0-9]{2,8});)#', $string, 0, PREG_SPLIT_DELIM_CAPTURE);
			$string = '';
			for($i = 0; $i < count($pieces); $i++){
				if( $i % 2 ){
					$string .= $pieces[$i];
				}else{
					$string .= str_replace('&', '&', $pieces[$i]);
				}
			}
			//change non html tag < and > into < and >
			$pieces = preg_split('#(<(?:/?)[a-zA-Z0-9][^<>]*>)#', $string, 0, PREG_SPLIT_DELIM_CAPTURE);
			$string = '';
			for($i=0; $i< count($pieces); $i++){
				if( $i % 2 ){
					$string .= $pieces[$i];
				}else{
					$string .= \gp\tool::LabelSpecialChars($pieces[$i]);
				}
			}
			//only allow tags that are legal to be inside 
 except for