CVE-2020-36638: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: ** UNSUPPORTED WHEN ASSIGNED ** A vulnerability was found in Chris92de AdminServ. It has been rated as problematic. This issue affects some unknown processing of the file resources/core/adminserv.php. The manipulation of the argument error leads to cross site scripting. The attack may be initiated remotely. The patch is named 9a45087814295de6fb3a3fe38f96293665234da1. It is recommended to apply a patch to fix this issue. The associated identifier of this vulnerability is VDB-217043. NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 6.1
Published: 2022-12-30T12:15Z
Repository: https://github.com/Chris92de/AdminServ
Language: PHP
Files changed: .gitattributes, .htaccess, README.md, config/adminlevel.cfg.php, config/adminserv.cfg.php, config/extension.cfg.php, config/index.php, config/servers.cfg.php, index.php, plugins/_newplugin/config.ini, plugins/_newplugin/script.php, plugins/coppers/config.ini, plugins/coppers/js/event.js, plugins/coppers/lang/fr.php, plugins/coppers/script.php, plugins/coppers/styles/coppers.css, plugins/coppers/view.php, plugins/planets/config.ini, plugins/planets/js/event.js, plugins/planets/lang/fr.php, plugins/planets/script.php, plugins/planets/styles/planets.css, plugins/planets/view.php, resources/ajax/add_chatserverline.php, resources/ajax/ds_getservers.php, resources/ajax/ds_initialize.php, resources/ajax/get_chatserverlines.php, resources/ajax/get_colorstr.php, resources/ajax/get_current_serverinfo.php, resources/ajax/get_directory_list.php, resources/ajax/get_maplist.php, resources/ajax/get_matchset_fileexists.php, resources/ajax/get_matchset_mapimport.php, resources/ajax/get_matchset_mapselection.php, resources/ajax/get_server_adminlevel.php, resources/ajax/mapsorder_sort.php, resources/ajax/script_settings.php, resources/ajax/speed_admin.php, resources/ajax/upload.php, resources/cache/mapslist-DtrackmaniadedicatedUserDataMaps.json, resources/class/GbxRemote.inc.php, resources/class/file.class.php, resources/class/folder.class.php, resources/class/gbxdatafetcher.inc.php, resources/class/str.class.php, resources/class/timedate.class.php, resources/class/tmnick.class.php, resources/class/upload.class.php, resources/class/utils.class.php, resources/class/zip.class.php, resources/core/adminlevel.php, resources/core/adminserv.php, resources/core/cache.php, resources/core/event.php, resources/core/logs.php, resources/core/plugin.php, resources/core/server.php, resources/core/sort.php, resources/core/ui.php, resources/css/displayserv.css, resources/css/fileuploader.css, resources/css/global.css, resources/css/ie.css, resources/css/jqueryui/black.css, resources/css/jqueryui/blue.css, resources/css/jqueryui/green.css, resources/css/jqueryui/orange.css, resources/css/jqueryui/purple.css, resources/css/jqueryui/red.css, resources/css/mobile.css, resources/css/theme.php, resources/js/adminserv_event.js, resources/js/adminserv_funct.js, resources/js/colorpicker.js, resources/js/displayserv.js, resources/js/fileuploader.js, resources/js/jquery-ui.js, resources/js/jquery.js, resources/lang/de.php, resources/lang/dk.php, resources/lang/es.php, resources/lang/fr.php, resources/lang/nl.php, resources/lang/no.php, resources/lang/pl.php, resources/process/chat.php, resources/process/config-addlevel.php, resources/process/config-addserver.php, resources/process/config-adminlevel.php, resources/process/config-levelsorder.php, resources/process/config-password.php, resources/process/config-servers.php, resources/process/config-serversorder.php, resources/process/config.preprocess.php, resources/process/connection.php, resources/process/gameinfos.php, resources/process/general.php, resources/process/guestban.php, resources/process/maps-creatematchset.php, resources/process/maps-list.php, resources/process/maps-local.php, resources/process/maps-matchset.php, resources/process/maps-order.php, resources/process/maps.preprocess.php, resources/process/plugins-list.php, resources/process/srvopts.php, resources/templates/chat.tpl.php, resources/templates/config-addlevel.tpl.php, resources/templates/config-addserver.tpl.php, resources/templates/config-adminlevel.tpl.php, resources/templates/config-levelsorder.tpl.php, resources/templates/config-password.tpl.php, resources/templates/config-servers.tpl.php, resources/templates/config-serversorder.tpl.php, resources/templates/connection.tpl.php, resources/templates/footer.tpl.php, resources/templates/gameinfos-field.tpl.php, resources/templates/gameinfos-gamemode.tpl.php, resources/templates/gameinfos-general.tpl.php, resources/templates/gameinfos.tpl.php, resources/templates/general.tpl.php, resources/templates/guestban.tpl.php, resources/templates/header.tpl.php, resources/templates/maps-creatematchset.tpl.php, resources/templates/maps-directorylist.tpl.php, resources/templates/maps-list.tpl.php, resources/templates/maps-local.tpl.php, resources/templates/maps-matchset.tpl.php, resources/templates/maps-menu.tpl.php, resources/templates/maps-order.tpl.php, resources/templates/maps-upload.tpl.php, resources/templates/page-error.tpl.php, resources/templates/plugins-list.tpl.php, resources/templates/srvopts.tpl.php, robots.txt
Commit date: 2020-09-29 11:36:11 +0200
Commit message: Merge pull request #6 from lacaulac/patch-1

- Fixed an XSS vulnerability (patch by @lacaulac)
Thanks for reporting it!
Diff: diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..412eeda
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs     diff=csharp
+*.sln    merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc	 diff=astextplain
+*.DOC	 diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot  diff=astextplain
+*.DOT  diff=astextplain
+*.pdf  diff=astextplain
+*.PDF	 diff=astextplain
+*.rtf	 diff=astextplain
+*.RTF	 diff=astextplain
diff --git a/.htaccess b/.htaccess
new file mode 100644
index 0000000..be4371c
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,2 @@
+Options +FollowSymlinks
+Options -Indexes
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3448199
--- /dev/null
+++ b/README.md
@@ -0,0 +1,34 @@
+AdminServ
+=========
+
+WebInterface to manage Trackmania Forever and ManiaPlanet dedicated servers.
+
+######Introduction
+Welcome to the new home of AdminServ.
+The original author of this awesome piece of work - kev717 - gave me [permission](http://forum.maniaplanet.com/viewtopic.php?p=231516#p231516) to continue updating this project.
+Feel free to submit pull requests, issues or feature requests.
+
+
+######About AdminServ
+Inspired by remoteCP and similar endeavours, AdminServ is a web interface which allows you to remotely control almost all aspects of your ManiaPlanet or TMForever servers. 
+
+######Main Features
+- Compatible with both TMForever and ManiaPlanet servers
+- Configure your servers online, from everywhere!
+- Display optimizations for Team mode
+- Folder-based organization of your maps
+- Allows managing your MatchSettings and playlists
+- Supports third-party plugins
+- Easily customizable (Header logo, Website title name, color scheme)
+
+######Requirements
+- A web server
+- PHP 5.3+
+- A dedicated TMForever/ManiaPlanet server
+
+######How-to install
+- Download the [latest release](https://github.com/Chris92de/AdminServ/releases)
+- Unpack it on your webserver
+- Navigate to wherever you placed it in your browser
+- Done! You're ready to configure everything in your browser
+- (optional) Add the location of your TMForever/ManiaPlanet server to the allowed open_basedir directories in your php.ini
diff --git a/config/adminlevel.cfg.php b/config/adminlevel.cfg.php
new file mode 100644
index 0000000..8a1dcd7
--- /dev/null
+++ b/config/adminlevel.cfg.php
@@ -0,0 +1,160 @@
+<?php
+class AdminLevelConfig {
+	public static $ADMINLEVELS = array(
+		/********************* ADMINLEVELS CONFIGURATION *********************/
+		
+		'SuperAdmin' => array(
+			'adminlevel' => array(
+				'type' => 'SuperAdmin',
+			),
+			'access' => array(
+				'server_options',
+				'game_infos',
+				'chat',
+				'maps_list',
+				'maps_local',
+				'maps_upload',
+				'maps_order',
+				'maps_matchsettings',
+				'maps_create_matchsettings',
+				'link_access_server',
+				'plugins_list',
+				'guest_ban',
+			),
+			'permission' => array(
+				'speed_admin',
+				'switch_server',
+				'player_kick',
+				'player_ban',
+				'player_guest',
+				'player_ignore',
+				'player_forcetospectator',
+				'player_forcetoplayer',
+				'player_changeteam',
+				'force_scores',
+				'cancel_vote',
+				'srvopts_general_name',
+				'srvopts_general_comment',
+				'srvopts_general_playerpassword',
+				'srvopts_general_spectatorpassword',
+				'srvopts_general_nbplayers',
+				'srvopts_general_nbspectators',
+				'srvopts_advanced',
+				'srvopts_adminlevelpassword',
+				'srvopts_importexport',
+				'gameinfos_general_gamemode',
+				'gameinfos_general_options',
+				'gameinfos_general_warmup',
+				'gameinfos_teams_options',
+				'gameinfos_gamemode_options',
+				'chat_sendmessage',
+				'maps_list_moveaftercurrent',
+				'maps_list_removetolist',
+				'maps_local_add',
+				'maps_local_insert',
+				'maps_local_download',
+				'maps_local_rename',
+				'maps_local_move',
+				'maps_local_delete',
+				'maps_upload_add',
+				'maps_upload_insert',
+				'maps_upload_folder',
+				'maps_matchsettings_save',
+				'maps_matchsettings_load',
+				'maps_matchsettings_add',
+				'maps_matchsettings_insert',
+				'maps_matchsettings_edit',
+				'maps_matchsettings_delete',
+				'folder_new',
+				'folder_rename',
+				'folder_move',
+				'folder_delete',
+				'guestban_addplayer',
+				'guestban_removeplayer',
+				'guestban_playlist_new',
+				'guestban_playlist_save',
+				'guestban_playlist_load',
+				'guestban_playlist_delete',
+			),
+		),
+		'Admin' => array(
+			'adminlevel' => array(
+				'type' => 'Admin',
+			),
+			'access' => array(
+				'server_options',
+				'game_infos',
+				'chat',
+				'maps_list',
+				'maps_local',
+				'maps_upload',
+				'maps_order',
+				'maps_matchsettings',
+				'maps_create_matchsettings',
+				'link_access_server',
+				'plugins_list',
+				'guest_ban',
+			),
+			'permission' => array(
+				'speed_admin',
+				'switch_server',
+				'player_kick',
+				'player_ban',
+				'player_guest',
+				'player_ignore',
+				'player_forcetospectator',
+				'player_forcetoplayer',
+				'player_changeteam',
+				'force_scores',
+				'cancel_vote',
+				'srvopts_general_name',
+				'srvopts_general_comment',
+				'srvopts_general_playerpassword',
+				'srvopts_general_spectatorpassword',
+				'srvopts_general_nbplayers',
+				'srvopts_general_nbspectators',
+				'gameinfos_general_gamemode',
+				'gameinfos_general_warmup',
+				'gameinfos_teams_options',
+				'gameinfos_gamemode_options',
+				'chat_sendmessage',
+				'maps_list_moveaftercurrent',
+				'maps_list_removetolist',
+				'maps_local_add',
+				'maps_local_insert',
+				'maps_local_download',
+				'maps_local_rename',
+				'maps_local_move',
+				'maps_upload_add',
+				'maps_upload_insert',
+				'maps_upload_folder',
+				'maps_matchsettings_save',
+				'maps_matchsettings_load',
+				'maps_matchsettings_add',
+				'maps_matchsettings_insert',
+				'maps_matchsettings_edit',
+				'folder_new',
+				'folder_rename',
+				'folder_move',
+				'guestban_addplayer',
+				'guestban_removeplayer',
+				'guestban_playlist_new',
+				'guestban_playlist_save',
+				'guestban_playlist_load',
+			),
+		),
+		'User' => array(
+			'adminlevel' => array(
+				'type' => 'User',
+			),
+			'access' => array(
+				'chat',
+				'maps_list',
+				'link_access_server',
+			),
+			'permission' => array(
+			),
+		),
+	);
+}
+?>
\ No newline at end of file
diff --git a/config/adminserv.cfg.php b/config/adminserv.cfg.php
new file mode 100644
index 0000000..54bbf3a
--- /dev/null
+++ b/config/adminserv.cfg.php
@@ -0,0 +1,82 @@
+<?php
+class OnlineConfig {
+	/********************* ONLINE CONFIGURATION *********************/
+	
+	const ACTIVATE = true; // Activate the online configuration
+	const PASSWORD = '0b28a5799a32c687dad2c5183718ceac'; // Checking password. This password is generated in MD5
+	const ADDRESS = ''; // Checking address. Can be localhost or IP address
+	const ADD_ONLY = false; // Add only server. Unable to modify or delete
+	const ADMINLEVEL = true; // Activate the admin level configuration
+}
+
+class AdminServConfig {
+	/********************* OPTIONAL CONFIGURATION *********************/
+	
+	/* GENERAL */
+	const TITLE = 'Admin,Serv'; // The comma seperates the color
+	const SUBTITLE = 'For maniaplanet servers'; // if null it's hidden
+	const LOGO = 'logo.png'; // if null it's hidden
+	const DEFAULT_THEME = 'red'; // The first theme to be loaded
+	const DEFAULT_LANGUAGE = 'auto'; // Can be language code (fr, en, etc) or auto = automatic detection
+	const USE_DISPLAYSERV = true; // Show DisplayServ tool on connection page
+	const AUTOSAVE_MATCHSETTINGS = true; // Save the MatchSettings in the server config (possibility to disable online)
+	
+	/* ADVANCED */
+	const MD5_PASSWORD = false; // if true, the dedicated server password is checked in MD5
+	const LIMIT_PLAYERS_LIST = 250; // Display limit for lines in player list
+	const LIMIT_MAPS_LIST = 1000; // Display limit for lines in maps list
+	const LOCAL_GET_MAPS_ON_SERVER = true; // if true, the current server maps list is loaded in local maps page for easy compare with icon change. But if you have a lot of maps in server, it is better to disable it
+	const RECENT_STATUS_PERIOD = 24; // Recent status period in hour for maps/matchsettings/guestban
+	const SERVER_CONNECTION_TIMEOUT = 3; // Dedicated server connection timeout in second
+	const COOKIE_EXPIRE = 90; // Expiration time for cookies, in days
+	
+	/* FILES AND FOLDERS */
+	public static $MAPS_HIDDEN_FOLDERS = array('MatchSettings', 'Replays'); // Folders to be hidden in maps page
+	public static $MATCHSET_HIDDEN_FOLDERS = array('Campaigns', 'Replays'); // Folders to be hidden in matchsettings page
+	public static $MAP_EXTENSION = array('map.gbx', 'challenge.gbx', 'gbx'); // Double extensions used in maps page
+	public static $MATCHSET_EXTENSION = array('txt'); // MatchSettings extensions used in matchsettings page
+	public static $PLAYLIST_EXTENSION = array('playlist.txt'); // Playlist extensions used in guestban page
+	
+	/* UPLOAD */
+	public static $ALLOWED_EXTENSIONS = array('gbx'); // Extensions allowed for upload
+	const SIZE_LIMIT = 'auto'; // Limit size per file in MB. If auto, the limit size in php.ini config file is used
+	const UPLOAD_ONLINE_FOLDER = 'AdminServ/'; // Path from "Maps" folder for upload online mode
+	
+	/* LOGS */
+	public static $LOGS = array(
+		'access' => true,
+		'action' => true,
+		'error' => true
+	);
+	
+	/* MULTI ADMINSERV */
+	const MULTI_ADMINSERV = false; // Use many instances of AdminServ
+	public static $PATH_RESOURCES = './resources/'; // You can change the folders location
+	public static $PATH_PLUGINS = './plugins/';
+	
+	/* PLUGINS */
+	const PLUGINS_LIST = ''; // The filename for alternative plugin configuration. In the file: $PLUGINS = array('pluginfoldername', 'etc');
+	const PLUGINS_LIST_TYPE = 'replace'; // add or replace method
+}
+
+class DataBaseConfig {
+	/********************* DATABASE CONFIGURATION *********************/
+	
+	const DB_HOST = '';
+	const DB_PORT = '';
+	const DB_USER = '';
+	const DB_PASS = '';
+	const DB_NAME = '';
+	const DB_DRIVER = '';
+	const DB_TABLE_PREFIX = '';
+}
+
+class FTPConfig {
+	/********************* FTP CONFIGURATION *********************/
+	
+	const FTP_HOST = '';
+	const FTP_USER = '';
+	const FTP_PASS = '';
+	const FTP_PORT = 21;
+}
+?>
\ No newline at end of file
diff --git a/config/extension.cfg.php b/config/extension.cfg.php
new file mode 100644
index 0000000..46be140
--- /dev/null
+++ b/config/extension.cfg.php
@@ -0,0 +1,83 @@
+<?php
+class ExtensionConfig {
+	/********************* EXTENSION CONFIGURATION *********************/
+	
+	// Plugins list installed
+	public static $PLUGINS = array(
+		'planets',
+		'coppers',
+	);
+	
+	
+	// Themes color list
+	public static $THEMES = array(
+		'red' => array(
+			'#ea4f4f',
+			'#ffc0c0'
+		),
+		'blue' => array(
+			'#5e9cd5',
+			'#d9e8ff'
+		),
+		'green' => array(
+			'#8aca1b',
+			'#d1e9a8'
+		),
+		'orange' => array(
+			'#ffa600',
+			'#ffe3b0'
+		),
+		'purple' => array(
+			'#b15cd5',
+			'#e5c4f3'
+		),
+		'black' => array(
+			'#727272',
+			'#dedede'
+		)
+	);
+	
+	
+	// Available language list
+	public static $LANG = array(
+		'fr' => 'Français',
+		'en' => 'English',
+		'de' => 'Deutsch',
+		'es' => 'Español',
+		'no' => 'Norsk',
+		'dk' => 'Danish',
+		'pl' => 'Polish',
+		'nl' => 'Dutch'
+	);
+	
+	
+	// Game modes list
+	public static $GAMEMODES = array(
+		0 => 'Script',
+		1 => 'Rounds',
+		2 => 'TimeAttack',
+		3 => 'Team',
+		4 => 'Laps',
+		5 => 'Cup',
+		6 => 'Stunts'
+	);
+	public static $TEAMSCRIPTS = array(
+		'Elite',
+		'Battle',
+		'Siege',
+		'Heroes',
+		'SpeedBall'
+	);
+	
+	
+	// Menu list in maps page
+	public static $MAPSMENU = array(
+		'maps-list' => 'List',
+		'maps-local' => 'Local',
+		'maps-upload' => 'Send',
+		'maps-order' => 'Order',
+		'maps-matchset' => 'MatchSettings',
+		'maps-creatematchset' => 'Create a MatchSettings'
+	);
+}
+?>
\ No newline at end of file
diff --git a/config/index.php b/config/index.php
new file mode 100644
index 0000000..cbe74a3
--- /dev/null
+++ b/config/index.php
@@ -0,0 +1,115 @@
+<?php
+	session_start();
+	require_once './adminserv.cfg.php';
+	if( file_exists('./servers.cfg.php') ){
+		require_once './servers.cfg.php';
+	}
+	AdminServConfig::$PATH_RESOURCES = '../'.AdminServConfig::$PATH_RESOURCES;
+	require_once AdminServConfig::$PATH_RESOURCES .'core/adminserv.php';
+	AdminServ::getClass();
+	AdminServUI::lang();
+	
+	// On vérifie qu'une configuration existe
+	if( class_exists('ServerConfig') ){
+		// Si on autorise la configuration en ligne
+		if( OnlineConfig::ACTIVATE === true ){
+			// Si il y a déjà un serveur configuré
+			if( AdminServServerConfig::hasServer() ){
+				$allowRedirect = false;
+				if( OnlineConfig::ADDRESS == null && OnlineConfig::PASSWORD == null ){
+					$allowRedirect = true;
+				}
+				else{
+					// Test adresse IP
+					if(OnlineConfig::ADDRESS != null){
+						if(OnlineConfig::ADDRESS === 'localhost'){
+							if( Utils::isLocalhostIP() ){
+								$allowRedirect = true;
+							}
+							else{
+								$allowRedirect = false;
+							}
+						}
+						else{
+							if( $_SERVER['REMOTE_ADDR'] === OnlineConfig::ADDRESS ){
+								$allowRedirect = true;
+							}
+							else{
+								$allowRedirect = false;
+							}
+						}
+					}
+					// Test password
+					if(OnlineConfig::PASSWORD != null){
+						if( isset($_POST['configcheckpassword']) ){
+							if(md5($_POST['checkPassword']) === OnlineConfig::PASSWORD){
+								$allowRedirect = true;
+							}
+							else{
+								$allowRedirect = false;
+							}
+						}
+						else{
+							// Suppression des sessions existante et démarrage d'une nouvelle
+							session_unset();
+							session_destroy();
+							session_start();
+							
+							// Demande de password
+							$_SESSION['adminserv']['check_password'] = true;
+							Utils::redirection(false, '..');
+						}
+					}
+				}
+			
+				// Redirection vers les pages
+				if($allowRedirect){
+					session_unset();
+					session_destroy();
+					session_start();
+					$_SESSION['adminserv']['allow_config_servers'] = true;
+					
+					if( OnlineConfig::ADD_ONLY === true || AdminServServerConfig::hasServer() === false ){
+						Utils::redirection(false, '../?p=config-addserver');
+					}
+					else{
+						Utils::redirection(false, '../?p=config-servers');
+					}
+				}
+				else{
+					AdminServ::error( Utils::t('You are not allowed to configure the servers') );
+					Utils::redirection(false, '..');
+				}
+			}
+			// Sinon on créer le mot de passe
+			else{
+				if( isset($_POST['configsavepassword']) ){
+					$password = md5($_POST['savePassword']);
+					if( ($result = AdminServServerConfig::savePasswordConfig('./adminserv.cfg.php', $password)) !== true ){
+						AdminServ::error( Utils::t('Unable to save password.').' ('.$result.')');
+						Utils::redirection(false, '..');
+					}
+					else{
+						session_unset();
+						session_destroy();
+						session_start();
+						$_SESSION['adminserv']['allow_config_servers'] = true;
+						Utils::redirection(false, '../?p=config-addserver');
+					}
+				}
+				else{
+					// Création du mot de passe
+					$_SESSION['adminserv']['get_password'] = true;
+					Utils::redirection(false, '..');
+				}
+			}
+		}
+		else{
+			AdminServ::info( Utils::t('The online configuration is disabled. Use "./config/servers.cfg.php" file.') );
+			Utils::redirection(false, '..');
+		}
+	}
+	else{
+		Utils::redirection(false, '../?error='.urlencode( Utils::t('The servers configuration file isn\'t recognized by AdminServ.') ) );
+	}
+?>
\ No newline at end of file
diff --git a/config/servers.cfg.php b/config/servers.cfg.php
new file mode 100644
index 0000000..a06adf6
--- /dev/null
+++ b/config/servers.cfg.php
@@ -0,0 +1,18 @@
+<?php
+class ServerConfig {
+    public static $SERVERS = array(
+        /********************* SERVER CONFIGURATION *********************/
+
+        /*
+        'new server name' => array(
+            'address'		=> 'localhost',
+            'port'			=> 5000,
+            'mapsbasepath'	=> '',
+            'matchsettings'	=> 'MatchSettings/',
+            'adminlevel'	=> array('SuperAdmin' => 'all', 'Admin' => 'all', 'User' => 'all'),
+            'ds_pw'         => 'User'
+        ),
+        */
+    );
+}
+?>
\ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..5f329fc
--- /dev/null
+++ b/index.php
@@ -0,0 +1,72 @@
+<?php
+    // FIX FOR MAPBROWSER BY TOFFE
+    foreach ($_GET as $key => $value) { if(stristr($value, "../")) $_GET[$key] = str_replace("../", "", $value); }
+    foreach ($_POST as $key => $value) { if(stristr($value, "../")) $_POST[$key] = str_replace("../", "", $value); }
+	// INCLUDES
+	session_start();
+	require_once 'config/adminserv.cfg.php';
+	require_once 'config/servers.cfg.php';
+	require_once 'config/extension.cfg.php';
+	require_once 'config/adminlevel.cfg.php';
+	require_once AdminServConfig::$PATH_RESOURCES .'core/adminserv.php';
+	
+	// LOAD TIMER
+	if(ADMINSERV_TIMER){
+		AdminServ::startTimer();
+	}
+	
+	// INITIALIZE
+	AdminServ::checkPHPVersion('5.3.0');
+	define('PATH_ROOT', basename(__DIR__).'/');
+	$_SESSION['adminserv']['path'] = (AdminServConfig::MULTI_ADMINSERV) ? PATH_ROOT : null;
+	AdminServ::getClass();
+	
+	// GLOBALS
+	AdminServEvent::getArgs();
+	
+	// THEME
+	define('USER_THEME', AdminServUI::theme($args['theme']));
+	
+	// LANG
+	define('USER_LANG', AdminServUI::lang($args['lang']));
+	
+	// VÉRIFICATION DES DROITS
+	$checkRightsList = array(
+		'./config/adminserv.cfg.php' => 666,
+		'./config/servers.cfg.php' => 666,
+		'./config/adminlevel.cfg.php' => 666,
+	);
+	if( in_array(true, AdminServConfig::$LOGS) ){
+		if (!Utils::isWinServer()) {
+			$checkRightsList['./logs/'] = 777;
+		}
+	}
+	AdminServ::checkRights($checkRightsList);
+	
+	// LOGOUT
+	AdminServEvent::logout();
+	
+	// LOGS
+	AdminServLogs::initialize();
+	
+	// PLUGINS
+	define('USER_PLUGIN', AdminServPlugin::getCurrent());
+	
+	// INDEX
+	unset($args['theme'], $args['lang']);
+	if( AdminServEvent::isLoggedIn() ){
+		
+		// SWITCH SERVER
+		AdminServEvent::switchServer();
+		
+		// SERVER CONNECTION
+		if (AdminServ::initialize()) {
+			// PAGES BACKOFFICE
+			AdminServUI::initBackPage();
+		}
+	}
+	else{
+		// PAGES FRONTOFFICE
+		AdminServUI::initFrontPage();
+	}
+?>
diff --git a/plugins/_newplugin/config.ini b/plugins/_newplugin/config.ini
new file mode 100644
index 0000000..240ffcd
--- /dev/null
+++ b/plugins/_newplugin/config.ini
@@ -0,0 +1,7 @@
+; Name and version of plugin
+name = 'New plugin'
+version = '1.0'
+; Game compatibiliy : TmForever, ManiaPlanet or all
+game = 'all'
+; Minimum access level
+adminlevel = 'User'
\ No newline at end of file
diff --git a/plugins/_newplugin/script.php b/plugins/_newplugin/script.php
new file mode 100644
index 0000000..15c5adc
--- /dev/null
+++ b/plugins/_newplugin/script.php
@@ -0,0 +1,3 @@
+<?php
+
+?>
\ No newline at end of file
diff --git a/plugins/_newplugin/view.php b/plugins/_newplugin/view.php
new file mode 100644
index 0000000..e69de29
diff --git a/plugins/coppers/config.ini b/plugins/coppers/config.ini
new file mode 100644
index 0000000..ea4935d
--- /dev/null
+++ b/plugins/coppers/config.ini
@@ -0,0 +1,7 @@
+; Name and version of plugin
+name = 'Coppers'
+version = '1.0'
+; Game compatibiliy : TmForever, ManiaPlanet or all
+game = 'TmForever'
+; Minimum access level
+adminlevel = 'Admin'
\ No newline at end of file
diff --git a/plugins/coppers/js/event.js b/plugins/coppers/js/event.js
new file mode 100644
index 0000000..b71a0a1
--- /dev/null
+++ b/plugins/coppers/js/event.js
@@ -0,0 +1,23 @@
+$(document).ready(function(){
+	// Default values
+	$('#serverToServerLogin, #serverToPlayerMessage, #serverToPlayerLogin2').click(function(){
+		if( $(this).val() == $(this).data('default-value') ){
+			$(this).val('');
+		}
+	});
+	$('#serverToServerLogin, #serverToPlayerMessage, #serverToPlayerLogin2').blur(function(){
+		if( $(this).val() == '' ){
+			$(this).val( $(this).data('default-value') );
+		}
+	});
+	
+	// Server > Player
+	$('#serverToPlayerLogin').change(function(){
+		if( $(this).val() == 'more' ){
+			$(this).fadeOut('fast');
+			$('#serverToPlayerLogin2').fadeIn('fast');
+			$(this).attr('hidden', true);
+			$('#serverToPlayerLogin2').removeAttr('hidden');
+		}
+	});
+});
\ No newline at end of file
diff --git a/plugins/coppers/lang/fr.php b/plugins/coppers/lang/fr.php
new file mode 100644
index 0000000..91e3bc8
--- /dev/null
+++ b/plugins/coppers/lang/fr.php
@@ -0,0 +1,14 @@
+<?php
+	$translate['Optionnal'] = 'Optionnel';
+	$translate['Transfered by AdminServ'] = 'Transferé par AdminServ';
+	$translate['Confirmation of the transfer by AdminServ'] = 'Confirmation de transfert par AdminServ';
+	$translate['Transaction'] = 'Transaction';
+	$translate['No transfer made.'] = 'Aucun transfert effectué.';
+	$translate['Infos'] = 'Infos';
+	$translate['Number of coppers:'] = 'Nombre de coppers :';
+	$translate['Transfer state:'] = 'Statut du transfert :';
+	$translate['Transfers'] = 'Transferts';
+	$translate['Amount'] = 'Somme';
+	$translate['Confirmation from a player on the server is necessary.'] = 'Nécessite une confirmation du joueur sur le serveur.';
+	$translate['Transfer'] = 'Transférer';
+?>
\ No newline at end of file
diff --git a/plugins/coppers/script.php b/plugins/coppers/script.php
new file mode 100644
index 0000000..8e94cb1
--- /dev/null
+++ b/plugins/coppers/script.php
@@ -0,0 +1,106 @@
+<?php
+	/* INCLUDES */
+	$path = AdminServPlugin::getPluginPath();
+	$langFile = $path.'lang/'. USER_LANG .'.php';
+	if( file_exists($langFile) ){
+		include_once $langFile;
+	}
+	
+	
+	/* ACTIONS */
+	if( isset($_POST['transfercoppers']) ){
+		// Server > Server
+		if( isset($_POST['serverToServerAmout']) && isset($_POST['serverToServerLogin']) ){
+			$serverToServerAmout = intval($_POST['serverToServerAmout']);
+			$serverToServerLogin = trim($_POST['serverToServerLogin']);
+			
+			if($serverToServerAmout > 0 && $serverToServerLogin != Utils::t('Server login') ){
+				if( !$client->query('Pay', $serverToServerLogin, $serverToServerAmout, Utils::t('Transfered by AdminServ')) ){
+					AdminServ::error();
+				}
+				else{
+					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
+					AdminServLogs::add('action', 'Transfer '.$serverToServerAmout.' coppers to '.$serverToServerLogin.' server login');
+				}
+			}
+		}
+		
+		// Server > Player
+		if( isset($_POST['serverToPlayerAmount']) && isset($_POST['serverToPlayerLogin']) ){
+			$serverToPlayerAmount = intval($_POST['serverToPlayerAmount']);
+			$serverToPlayerMessage = trim($_POST['serverToPlayerMessage']);
+			$serverToPlayerLogin = trim($_POST['serverToPlayerLogin']);
+			$serverToPlayerLogin2 = trim($_POST['serverToPlayerLogin2']);
+			
+			if( $serverToPlayerAmount > 0 ){
+				// Message
+				if($serverToPlayerMessage == Utils::t('Optionnal') ){
+					$serverToPlayerMessage = Utils::t('Transfered by AdminServ');
+				}
+				// Player login
+				if($serverToPlayerLogin2 != Utils::t('Player login') ){
+					$serverToPlayerLogin = $serverToPlayerLogin2;
+				}
+				
+				// Pay
+				if( !$client->query('Pay', $serverToPlayerLogin2, $serverToPlayerAmount, $serverToPlayerMessage) ){
+					AdminServ::error();
+				}
+				else{
+					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
+					AdminServLogs::add('action', 'Transfer '.$serverToPlayerAmount.' coppers to '.$serverToPlayerLogin2.' player login');
+				}
+			}
+		}
+		
+		// Server < Player
+		if( isset($_POST['playerToServerAmount']) && isset($_POST['playerToServerLogin']) ){
+			$playerToServerAmount = intval($_POST['playerToServerAmount']);
+			$playerToServerLogin = trim($_POST['playerToServerLogin']);
+			
+			if( $playerToServerAmount > 0 ){
+				if( !$client->query('SendBill', $playerToServerLogin, $playerToServerAmount, Utils::t('Confirmation of the transfer by AdminServ'), SERVER_LOGIN) ){
+					AdminServ::error();
+				}
+				else{
+					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
+					AdminServLogs::add('action', 'Transfer '.$playerToServerAmount.' coppers from to '.$playerToServerLogin.' player login');
+				}
+			}
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE);
+	}
+	
+	
+	/* GET */
+	$client->addCall('GetServerCoppers');
+	if( isset($_SESSION['adminserv']['transfer_billid']) && $_SESSION['adminserv']['transfer_billid'] != null){
+		$client->addCall('GetBillState', array($_SESSION['adminserv']['transfer_billid']) );
+	}
+	
+	if( !$client->multiquery() ){
+		AdminServ::error();
+	}
+	else{
+		$queriesData = $client->getMultiqueryResponse();
+		
+		// Coppers number
+		$nbCoppers = $queriesData['GetServerCoppers'];
+		
+		// Transfer status
+		if( isset($queriesData['GetBillState']) ){
+			$billState = $queriesData['GetBillState'];
+			$transferState = Utils::t('Transaction').' #'.$billState['TransactionId'].' : '.$billState['StateName'];
+		}
+		else{
+			$transferState = '<i>'.Utils::t('No transfer made.').'</i>';
+		}
+	}
+	
+	// Players
+	$playerCount = AdminServ::getNbPlayers();
+	$getPlayerListUI = AdminServUI::getPlayerList();
+	
+	$client->Terminate();
+?>
\ No newline at end of file
diff --git a/plugins/coppers/styles/coppers.css b/plugins/coppers/styles/coppers.css
new file mode 100644
index 0000000..6075650
--- /dev/null
+++ b/plugins/coppers/styles/coppers.css
@@ -0,0 +1,9 @@
+.plugin-coppers .width2 {
+	width: 45%;
+}
+.plugin-coppers input.width1 {
+	width: 83%;
+}
+.plugin-coppers select.width1 {
+	width: 88%;
+}
\ No newline at end of file
diff --git a/plugins/coppers/view.php b/plugins/coppers/view.php
new file mode 100644
index 0000000..3a5458d
--- /dev/null
+++ b/plugins/coppers/view.php
@@ -0,0 +1,99 @@
+<link rel="stylesheet" href="<?php echo $path; ?>styles/coppers.css" />
+<script src="<?php echo $path; ?>js/event.js"></script>
+
+<h2><?php echo Utils::t('Infos'); ?></h2>
+<div class="content">
+	<p><?php echo Utils::t('Number of coppers:'); ?> <b><?php echo $nbCoppers; ?></b></p>
+	<p><?php echo Utils::t('Transfer state:').' '.$transferState; ?></p>
+</div>
+
+<h2><?php echo Utils::t('Transfers'); ?></h2>
+<form method="post" action="">
+<div class="content">
+	<fieldset>
+		<legend><?php echo Utils::t('Server').' &gt; '.Utils::t('Server'); ?></legend>
+		<table>
+			<tr>
+				<td class="key">
+					<label for="serverToServerAmout"><?php echo Utils::t('Amount'); ?></label>
+				</td>
+				<td class="value">
+					<input class="text width2" type="number" min="0" name="serverToServerAmout" id="serverToServerAmout" value="" />
+				</td>
+			</tr>
+			<tr>
+				<td class="key">
+					<label for="serverToServerLogin"><i><?php echo SERVER_LOGIN; ?></i> →</label>
+				</td>
+				<td class="value">
+					<input class="text width2" type="text" name="serverToServerLogin" id="serverToServerLogin" data-default-value="Login serveur" value="Login serveur" />
+				</td>
+			</tr>
+		</table>
+	</fieldset>
+	
+	<fieldset>
+		<legend><?php echo Utils::t('Server').' &gt; '.Utils::t('Player'); ?></legend>
+		<table>
+			<tr>
+				<td class="key">
+					<label for="serverToPlayerAmount"><?php echo Utils::t('Amount'); ?></label>
+				</td>
+				<td class="value">
+					<input class="text width2" type="number" min="0" name="serverToPlayerAmount" id="serverToPlayerAmount" value="" />
+				</td>
+			</tr>
+			<tr>
+				<td class="key">
+					<label for="serverToPlayerMessage"><?php echo Utils::t('Message'); ?></label>
+				</td>
+				<td class="value">
+					<input class="text width2" type="text" name="serverToPlayerMessage" id="serverToPlayerMessage" data-default-value="<?php echo Utils::t('Optionnal'); ?>" value="<?php echo Utils::t('Optionnal'); ?>" />
+				</td>
+			</tr>
+			<tr>
+				<td class="key">
+					<label for="serverToPlayerLogin"><i><?php echo SERVER_LOGIN; ?></i> →</label>
+				</td>
+				<td class="value">
+					<select class="width2" name="serverToPlayerLogin" id="serverToPlayerLogin"<?php if($playerCount == 0){ echo ' hidden="hidden"'; } ?>>
+						<?php echo $getPlayerListUI; ?>
+						<option value="more"><?php echo Utils::t('Enter another login'); ?></option>
+					</select>
+					<input class="text width2" type="text" name="serverToPlayerLogin2" id="serverToPlayerLogin2" data-default-value="<?php echo Utils::t('Player login'); ?>" value="<?php echo Utils::t('Player login'); ?>"<?php if($playerCount != 0){ echo ' hidden="hidden"'; } ?> />
+				</td>
+			</tr>
+		</table>
+	</fieldset>
+	
+	<fieldset>
+		<legend><?php echo Utils::t('Server').' &lt; '.Utils::t('Player'); ?></legend>
+		<table>
+			<tr>
+				<td class="key">
+					<label for="playerToServerAmount"><?php echo Utils::t('Amount'); ?></label>
+				</td>
+				<td class="value">
+					<input class="text width1" type="number" min="0" name="playerToServerAmount" id="playerToServerAmount" value="" />
+				</td>
+			</tr>
+			<tr>
+				<td class="key">
+					<label for="playerToServerLogin"><i><?php echo SERVER_LOGIN; ?></i> ←</label>
+				</td>
+				<td class="value">
+					<select class="width1" name="playerToServerLogin" id="playerToServerLogin">
+						<?php echo $getPlayerListUI; ?>
+					</select>
+				</td>
+				<td class="info">
+					<?php echo Utils::t('Confirmation from a player on the server is necessary.'); ?>
+				</td>
+			</tr>
+		</table>
+	</fieldset>
+</div>
+<div class="fright save">
+	<input class="button light" type="submit" name="transfercoppers" id="transfercoppers" value="<?php echo Utils::t('Transfer'); ?>" />
+</div>
+</form>
\ No newline at end of file
diff --git a/plugins/planets/config.ini b/plugins/planets/config.ini
new file mode 100644
index 0000000..ce59e78
--- /dev/null
+++ b/plugins/planets/config.ini
@@ -0,0 +1,7 @@
+; Name and version of plugin
+name = 'Planets'
+version = '1.0'
+; Game compatibiliy : TmForever, ManiaPlanet or all
+game = 'ManiaPlanet'
+; Minimum access level
+adminlevel = 'Admin'
\ No newline at end of file
diff --git a/plugins/planets/js/event.js b/plugins/planets/js/event.js
new file mode 100644
index 0000000..b71a0a1
--- /dev/null
+++ b/plugins/planets/js/event.js
@@ -0,0 +1,23 @@
+$(document).ready(function(){
+	// Default values
+	$('#serverToServerLogin, #serverToPlayerMessage, #serverToPlayerLogin2').click(function(){
+		if( $(this).val() == $(this).data('default-value') ){
+			$(this).val('');
+		}
+	});
+	$('#serverToServerLogin, #serverToPlayerMessage, #serverToPlayerLogin2').blur(function(){
+		if( $(this).val() == '' ){
+			$(this).val( $(this).data('default-value') );
+		}
+	});
+	
+	// Server > Player
+	$('#serverToPlayerLogin').change(function(){
+		if( $(this).val() == 'more' ){
+			$(this).fadeOut('fast');
+			$('#serverToPlayerLogin2').fadeIn('fast');
+			$(this).attr('hidden', true);
+			$('#serverToPlayerLogin2').removeAttr('hidden');
+		}
+	});
+});
\ No newline at end of file
diff --git a/plugins/planets/lang/fr.php b/plugins/planets/lang/fr.php
new file mode 100644
index 0000000..bb59fcf
--- /dev/null
+++ b/plugins/planets/lang/fr.php
@@ -0,0 +1,14 @@
+<?php
+	$translate['Optionnal'] = 'Optionnel';
+	$translate['Transfered by AdminServ'] = 'Transferé par AdminServ';
+	$translate['Confirmation of the transfer by AdminServ'] = 'Confirmation de transfert par AdminServ';
+	$translate['Transaction'] = 'Transaction';
+	$translate['No transfer made.'] = 'Aucun transfert effectué.';
+	$translate['Infos'] = 'Infos';
+	$translate['Number of planets:'] = 'Nombre de planets :';
+	$translate['Transfer state:'] = 'Statut du transfert :';
+	$translate['Transfers'] = 'Transferts';
+	$translate['Amount'] = 'Somme';
+	$translate['Confirmation from a player on the server is necessary.'] = 'Nécessite une confirmation du joueur sur le serveur.';
+	$translate['Transfer'] = 'Transférer';
+?>
\ No newline at end of file
diff --git a/plugins/planets/script.php b/plugins/planets/script.php
new file mode 100644
index 0000000..9cac07d
--- /dev/null
+++ b/plugins/planets/script.php
@@ -0,0 +1,106 @@
+<?php
+	/* INCLUDES */
+	$path = AdminServPlugin::getPluginPath();
+	$langFile = $path.'lang/'. USER_LANG .'.php';
+	if( file_exists($langFile) ){
+		include_once $langFile;
+	}
+	
+	
+	/* ACTIONS */
+	if( isset($_POST['transferplanets']) ){
+		// Server > Server
+		if( isset($_POST['serverToServerAmout']) && isset($_POST['serverToServerLogin']) ){
+			$serverToServerAmout = intval($_POST['serverToServerAmout']);
+			$serverToServerLogin = trim($_POST['serverToServerLogin']);
+			
+			if($serverToServerAmout > 0 && $serverToServerLogin != Utils::t('Server login') ){
+				if( !$client->query('Pay', $serverToServerLogin, $serverToServerAmout, Utils::t('Transfered by AdminServ')) ){
+					AdminServ::error();
+				}
+				else{
+					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
+					AdminServLogs::add('action', 'Transfer '.$serverToServerAmout.' planets to '.$serverToServerLogin.' server login');
+				}
+			}
+		}
+		
+		// Server > Player
+		if( isset($_POST['serverToPlayerAmount']) && isset($_POST['serverToPlayerLogin']) ){
+			$serverToPlayerAmount = intval($_POST['serverToPlayerAmount']);
+			$serverToPlayerMessage = trim($_POST['serverToPlayerMessage']);
+			$serverToPlayerLogin = trim($_POST['serverToPlayerLogin']);
+			$serverToPlayerLogin2 = trim($_POST['serverToPlayerLogin2']);
+			
+			if( $serverToPlayerAmount > 0 ){
+				// Message
+				if($serverToPlayerMessage == Utils::t('Optionnal') ){
+					$serverToPlayerMessage = Utils::t('Transfered by AdminServ');
+				}
+				// Player login
+				if($serverToPlayerLogin2 != Utils::t('Player login') ){
+					$serverToPlayerLogin = $serverToPlayerLogin2;
+				}
+				
+				// Pay
+				if( !$client->query('Pay', $serverToPlayerLogin, $serverToPlayerAmount, $serverToPlayerMessage) ){
+					AdminServ::error();
+				}
+				else{
+					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
+					AdminServLogs::add('action', 'Transfer '.$serverToPlayerAmount.' planets to '.$serverToPlayerLogin.' player login');
+				}
+			}
+		}
+		
+		// Server < Player
+		if( isset($_POST['playerToServerAmount']) && isset($_POST['playerToServerLogin']) ){
+			$playerToServerAmount = intval($_POST['playerToServerAmount']);
+			$playerToServerLogin = trim($_POST['playerToServerLogin']);
+			
+			if( $playerToServerAmount > 0 ){
+				if( !$client->query('SendBill', $playerToServerLogin, $playerToServerAmount, Utils::t('Confirmation of the transfer by AdminServ'), SERVER_LOGIN) ){
+					AdminServ::error();
+				}
+				else{
+					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
+					AdminServLogs::add('action', 'Transfer '.$playerToServerAmount.' planets from to '.$playerToServerLogin.' player login');
+				}
+			}
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE);
+	}
+	
+	
+	/* GET */
+	$client->addCall('GetServerPlanets');
+	if( isset($_SESSION['adminserv']['transfer_billid']) && $_SESSION['adminserv']['transfer_billid'] != null){
+		$client->addCall('GetBillState', array($_SESSION['adminserv']['transfer_billid']) );
+	}
+	
+	if( !$client->multiquery() ){
+		AdminServ::error();
+	}
+	else{
+		$queriesData = $client->getMultiqueryResponse();
+		
+		// Planets number
+		$nbPlanets = $queriesData['GetServerPlanets'];
+		
+		// Transfer status
+		if( isset($queriesData['GetBillState']) ){
+			$billState = $queriesData['GetBillState'];
+			$transferState = Utils::t('Transaction').' #'.$billState['TransactionId'].' : '.$billState['StateName'];
+		}
+		else{
+			$transferState = '<i>'.Utils::t('No transfer made.').'</i>';
+		}
+	}
+	
+	// Players
+	$playerCount = AdminServ::getNbPlayers();
+	$getPlayerListUI = AdminServUI::getPlayerList();
+	
+	$client->Terminate();
+?>
\ No newline at end of file
diff --git a/plugins/planets/styles/planets.css b/plugins/planets/styles/planets.css
new file mode 100644
index 0000000..4806ed3
--- /dev/null
+++ b/plugins/planets/styles/planets.css
@@ -0,0 +1,9 @@
+.plugin-planets .width2 {
+	width: 45%;
+}
+.plugin-planets input.width1 {
+	width: 83%;
+}
+.plugin-planets select.width1 {
+	width: 88%;
+}
\ No newline at end of file
diff --git a/plugins/planets/view.php b/plugins/planets/view.php
new file mode 100644
index 0000000..b221570
--- /dev/null
+++ b/plugins/planets/view.php
@@ -0,0 +1,99 @@
+<link rel="stylesheet" href="<?php echo $path; ?>styles/planets.css" />
+<script src="<?php echo $path; ?>js/event.js"></script>
+
+<h2><?php echo Utils::t('Infos'); ?></h2>
+<div class="content">
+	<p><?php echo Utils::t('Number of planets:'); ?> <b><?php echo $nbPlanets; ?></b></p>
+	<p><?php echo Utils::t('Transfer state:').' '.$transferState; ?></p>
+</div>
+
+<h2><?php echo Utils::t('Transfers'); ?></h2>
+<form method="post" action="">
+<div class="content">
+	<fieldset>
+		<legend><?php echo Utils::t('Server').' &gt; '.Utils::t('Server'); ?></legend>
+		<table>
+			<tr>
+				<td class="key">
+					<label for="serverToServerAmout"><?php echo Utils::t('Amount'); ?></label>
+				</td>
+				<td class="value">
+					<input class="text width2" type="number" min="0" name="serverToServerAmout" id="serverToServerAmout" value="" />
+				</td>
+			</tr>
+			<tr>
+				<td class="key">
+					<label for="serverToServerLogin"><i><?php echo SERVER_LOGIN; ?></i> →</label>
+				</td>
+				<td class="value">
+					<input class="text width2" type="text" name="serverToServerLogin" id="serverToServerLogin" data-default-value="Login serveur" value="Login serveur" />
+				</td>
+			</tr>
+		</table>
+	</fieldset>
+	
+	<fieldset>
+		<legend><?php echo Utils::t('Server').' &gt; '.Utils::t('Player'); ?></legend>
+		<table>
+			<tr>
+				<td class="key">
+					<label for="serverToPlayerAmount"><?php echo Utils::t('Amount'); ?></label>
+				</td>
+				<td class="value">
+					<input class="text width2" type="number" min="0" name="serverToPlayerAmount" id="serverToPlayerAmount" value="" />
+				</td>
+			</tr>
+			<tr>
+				<td class="key">
+					<label for="serverToPlayerMessage"><?php echo Utils::t('Message'); ?></label>
+				</td>
+				<td class="value">
+					<input class="text width2" type="text" name="serverToPlayerMessage" id="serverToPlayerMessage" data-default-value="<?php echo Utils::t('Optionnal'); ?>" value="<?php echo Utils::t('Optionnal'); ?>" />
+				</td>
+			</tr>
+			<tr>
+				<td class="key">
+					<label for="serverToPlayerLogin"><i><?php echo SERVER_LOGIN; ?></i> →</label>
+				</td>
+				<td class="value">
+					<select class="width2" name="serverToPlayerLogin" id="serverToPlayerLogin"<?php if($playerCount == 0){ echo ' hidden="hidden"'; } ?>>
+						<?php echo $getPlayerListUI; ?>
+						<option value="more"><?php echo Utils::t('Enter another login'); ?></option>
+					</select>
+					<input class="text width2" type="text" name="serverToPlayerLogin2" id="serverToPlayerLogin2" data-default-value="<?php echo Utils::t('Player login'); ?>" value="<?php echo Utils::t('Player login'); ?>"<?php if($playerCount != 0){ echo ' hidden="hidden"'; } ?> />
+				</td>
+			</tr>
+		</table>
+	</fieldset>
+	
+	<fieldset>
+		<legend><?php echo Utils::t('Server').' &lt; '.Utils::t('Player'); ?></legend>
+		<table>
+			<tr>
+				<td class="key">
+					<label for="playerToServerAmount"><?php echo Utils::t('Amount'); ?></label>
+				</td>
+				<td class="value">
+					<input class="text width1" type="number" min="0" name="playerToServerAmount" id="playerToServerAmount" value="" />
+				</td>
+			</tr>
+			<tr>
+				<td class="key">
+					<label for="playerToServerLogin"><i><?php echo SERVER_LOGIN; ?></i> ←</label>
+				</td>
+				<td class="value">
+					<select class="width1" name="playerToServerLogin" id="playerToServerLogin">
+						<?php echo $getPlayerListUI; ?>
+					</select>
+				</td>
+				<td class="info">
+					<?php echo Utils::t('Confirmation from a player on the server is necessary.'); ?>
+				</td>
+			</tr>
+		</table>
+	</fieldset>
+</div>
+<div class="fright save">
+	<input class="button light" type="submit" name="transferplanets" id="transferplanets" value="<?php echo Utils::t('Transfer'); ?>" />
+</div>
+</form>
\ No newline at end of file
diff --git a/resources/ajax/add_chatserverline.php b/resources/ajax/add_chatserverline.php
new file mode 100644
index 0000000..811c910
--- /dev/null
+++ b/resources/ajax/add_chatserverline.php
@@ -0,0 +1,31 @@
+<?php
+	// INCLUDES
+	session_start();
+	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminlevel.cfg.php';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once $configPath.'extension.cfg.php';
+	require_once $configPath.'servers.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	
+	// ISSET
+	if( isset($_POST['nic']) ){ $nickname = $_POST['nic']; }else{ $nickname = null; }
+	if( isset($_POST['clr']) ){ $color = $_POST['clr']; }else{ $color = null; }
+	if( isset($_POST['msg']) ){ $message = $_POST['msg']; }else{ $message = null; }
+	if( isset($_POST['dst']) ){ $destination = $_POST['dst']; }else{ $destination = null; }
+	
+	// DATA
+	$out = null;
+	if($message != null && $destination != null){
+		if( AdminServ::initialize(false) ){
+			$out = AdminServ::addChatServerLine($message, $nickname, $color, $destination, true);
+		}
+		$client->Terminate();
+	}
+	
+	// OUT
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/ds_getservers.php b/resources/ajax/ds_getservers.php
new file mode 100644
index 0000000..1e00e79
--- /dev/null
+++ b/resources/ajax/ds_getservers.php
@@ -0,0 +1 @@
+<?php	// AUTHENTICATION	$LEVEL = 'User';	// ISSET	if( isset($_GET['cfg']) ){ $path_cfg = $_GET['cfg']; }else{ $path_cfg = null; }	if( isset($_GET['rsc']) ){ $path_rsc = $_GET['rsc']; }else{ $path_rsc = null; }	// INCLUDES    if(preg_match('/\.cfg\.php$/', $path_cfg)){        $serverConfig = '../../'.str_replace('../', '', $path_cfg);        if(file_exists($serverConfig)){            require_once $serverConfig;        }    }else{        header("HTTP/1.1 400 Bad Request");        die("Specified file is not a config.");    }	require_once '../class/GbxRemote.inc.php';	require_once '../class/tmnick.class.php';	require_once '../class/utils.class.php';	$langCode = Utils::getLang();	$langFile = '../lang/'.$langCode.'.php';	if( file_exists($langFile) ){		require_once $langFile;	}	// FUNCTIONS	function sortByTeam($a, $b){		// Modification		if($a['teamId'] == 0){			$a['teamId'] = 'blue';		}else if($a['teamId'] == 1){			$a['teamId'] = 'red';		}else{			$a['teamId'] = 'spectator';		}		if($b['teamId'] == 0){			$b['teamId'] = 'blue';		}else if($b['teamId'] == 1){			$b['teamId'] = 'red';		}else{			$b['teamId'] = 'spectator';		}		// Comparaison		if($a['teamId'] == $b['teamId']){			return 0;		}		if($a['teamId'] < $b['teamId']){			return -1;		}else{			return 1;		}	}	// DATA	$out = array();	if( class_exists('ServerConfig') ){		if( isset(ServerConfig::$SERVERS) && count(ServerConfig::$SERVERS) > 0 && !isset(ServerConfig::$SERVERS['new server name']) && !isset(ServerConfig::$SERVERS['']) ){			$serverId = 0;			foreach(ServerConfig::$SERVERS as $serverName => $serverValues){				// Connexion				$client = new IXR_ClientMulticall_Gbx;				if( !$client->InitWithIp($serverValues['address'], $serverValues['port']) ){					$out['servers'][$serverId]['error'] = Utils::t('Offline server.');				}				else{					if( !$client->query('Authenticate', $LEVEL, $serverValues['ds_pw']) ){						$out['servers'][$serverId]['error'] = Utils::t('Authentication error.');					}					else{						// Connecté sur						$client->query('GetVersion');						$version = $client->getResponse();						$out['servers'][$serverId]['version']['name'] = $version['Name'];						// Protocole : tmtp ou maniaplanet						$linkProtocol = 'maniaplanet';						if($version['Name'] == 'TmForever'){							$linkProtocol = 'tmtp';						}						$out['servers'][$serverId]['version']['protocol'] = $linkProtocol;						// Jeu						if($version['Name'] == 'TmForever'){							$queryName = array(								'getMapInfo' => 'GetCurrentChallengeInfo',							);						}						else{							$queryName = array(								'getMapInfo' => 'GetCurrentMapInfo',							);						}						// Requêtes						$client->addCall('GetServerName');						$client->addCall('GetSystemInfo');						$client->addCall('GetStatus');						$client->addCall('GetGameMode');						$client->addCall($queryName['getMapInfo']);						$client->addCall('GetPlayerList', array(50, 0) );						$client->addCall('GetMaxPlayers');						$client->multiquery();						$queriesData = $client->getMultiqueryResponse();						// Nom						$out['servers'][$serverId]['name'] = TmNick::toHtml($queriesData['GetServerName'], 10, true, false, '#999');						// Login						$system = $queriesData['GetSystemInfo'];						$out['servers'][$serverId]['serverlogin'] =  $system['ServerLogin'];						// Title						$title = null;						if($version['Name'] != 'TmForever'){							$title = $system['TitleId'];						}						$out['servers'][$serverId]['version']['title'] = $title;						// Statut						$status = $queriesData['GetStatus'];						$out['servers'][$serverId]['status'] = $status['Name'];						// GameMode						$gameMode = $queriesData['GetGameMode'];						$gameModeListName = array(							'Script',							'Rounds',							'TimeAttack',							'Team',							'Laps',							'Laps',							'Stunts',							'Cup'						);						if($version['Name'] == 'TmForever'){							$gameMode++;						}						$gameModeName = $gameModeListName[$gameMode];                        if($gameModeName == 'Script') {                            $client->addCall('GetScriptName');                            $client->multiquery();                            $scriptname = $client->getMultiqueryResponse();                            $out['servers'][$serverId]['gamemode'] = $gameModeName." (".str_replace('.Script.txt','',$scriptname['GetScriptName']['CurrentValue']).")";                        } else {						    $out['servers'][$serverId]['gamemode'] = $gameModeName;                        }						// Map						$currentMapInfo = $queriesData[$queryName['getMapInfo']];						$currentMapEnv = $currentMapInfo['Environnement'];						if($currentMapEnv == 'Speed'){							$currentMapEnv = 'Desert';						}						else if($currentMapEnv == 'Alpine'){							$currentMapEnv = 'Snow';						}						$currentMapEnvFile = null;						$pathToEnvFile = $path_rsc.'images/env/'.strtolower($currentMapEnv).'.png';						if( file_exists('../../'.$pathToEnvFile) ){							$currentMapEnvFile = $pathToEnvFile;						}						$out['servers'][$serverId]['map']['name'] = TmNick::toHtml(htmlspecialchars($currentMapInfo['Name'], ENT_QUOTES, 'UTF-8'), 10, true, false, '#999');						$out['servers'][$serverId]['map']['env']['name'] = $currentMapEnv;						$out['servers'][$serverId]['map']['env']['filename'] = $currentMapEnvFile;						// Players						$playerList = $queriesData['GetPlayerList'];						$countPlayerList = count($playerList);						if( $countPlayerList > 0 ){							$playerId = 0;							foreach($playerList as $player){								if($player['IsSpectator'] != 0){ $playerStatus = Utils::t('Spectator'); }else{ $playerStatus = Utils::t('Player'); }								if($player['TeamId'] == 0){ $teamName = Utils::t('Blue'); }else if($player['TeamId'] == 1){ $teamName = Utils::t('Red'); }else{ $teamName = Utils::t('Spectator'); }								$out['players'][$serverId]['list'][$playerId] = array(									'name' => TmNick::toHtml(htmlspecialchars($player['NickName'], ENT_QUOTES, 'UTF-8'), 10, true),									'status' => $playerStatus,									'teamId' => $player['TeamId'],									'teamName' => $teamName								);								$playerId++;							}						}						else{							$out['players'][$serverId]['list'] = Utils::t('No player');						}						// Tri mode team						if($gameModeName == 'Team' && $countPlayerList > 0){							uasort($out['players'][$serverId]['list'], 'sortByTeam');						}						// Count players						$maxPlayers = $queriesData['GetMaxPlayers'];						$out['players'][$serverId]['count']['current'] = $countPlayerList;						$out['players'][$serverId]['count']['max'] = $maxPlayers['NextValue'];					}				}				// Déconnexion				$client->Terminate();				$serverId++;			}		}	}	// Retour	echo json_encode($out);?>
\ No newline at end of file
diff --git a/resources/ajax/ds_initialize.php b/resources/ajax/ds_initialize.php
new file mode 100644
index 0000000..1cb88ad
--- /dev/null
+++ b/resources/ajax/ds_initialize.php
@@ -0,0 +1,43 @@
+<?php
+	// ISSET
+	if( isset($_GET['cfg']) ){ $path_cfg = $_GET['cfg']; }else{ $path_cfg = null; }
+
+	// INCLUDES
+	require_once '../class/utils.class.php';
+
+    if(preg_match('/\.cfg\.php$/', $path_cfg)){
+        $serverConfig = '../../'.str_replace('../', '', $path_cfg);
+        if(file_exists($serverConfig)){
+            require_once $serverConfig;
+        }
+    }else{
+        header("HTTP/1.1 400 Bad Request");
+        die("Specified file is not a config.");
+    }
+
+	$langCode = Utils::getLang();
+	$langFile = '../lang/'.$langCode.'.php';
+	if( file_exists($langFile) ){
+		require_once $langFile;
+	}
+
+	// DATA
+	$out = array();
+	if( class_exists('ServerConfig') ){
+		if( isset(ServerConfig::$SERVERS) && count(ServerConfig::$SERVERS) > 0 && !isset(ServerConfig::$SERVERS['new server name']) && !isset(ServerConfig::$SERVERS['']) ){
+			$out['servers'] = count(ServerConfig::$SERVERS);
+			$out['label']['server'] = Utils::t('Server');
+			$out['label']['name'] = Utils::t('Server name');
+			$out['label']['login'] = Utils::t('Server login');
+			$out['label']['connect'] = Utils::t('Connected on');
+			$out['label']['status'] = Utils::t('Status');
+			$out['label']['gamemode'] = Utils::t('Game mode');
+			$out['label']['currentmap'] = Utils::t('Current map');
+			$out['label']['players'] = Utils::t('Players');
+			$out['label']['accessserverplayer'] = Utils::t('Access as player');
+			$out['label']['accessserverspectate'] = Utils::t('Access as spectator');
+			$out['label']['addfavourite'] = Utils::t('Add to favourite');
+		}
+	}
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/get_chatserverlines.php b/resources/ajax/get_chatserverlines.php
new file mode 100644
index 0000000..9caade0
--- /dev/null
+++ b/resources/ajax/get_chatserverlines.php
@@ -0,0 +1,27 @@
+<?php
+	// INCLUDES
+	session_start();
+	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminlevel.cfg.php';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once $configPath.'extension.cfg.php';
+	require_once $configPath.'servers.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	AdminServUI::lang();
+	
+	// ISSET
+	if( isset($_GET['s']) ){ $hideServerLines = $_GET['s']; }else{ $hideServerLines = false; }
+	
+	// DATA
+	$out = null;
+	if( AdminServ::initialize(false) ){
+		$out = AdminServ::getChatServerLines($hideServerLines);
+	}
+	
+	// OUT
+	$client->Terminate();
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/get_colorstr.php b/resources/ajax/get_colorstr.php
new file mode 100644
index 0000000..7b896ee
--- /dev/null
+++ b/resources/ajax/get_colorstr.php
@@ -0,0 +1,16 @@
+<?php
+	// INCLUDES
+	require_once '../class/tmnick.class.php';
+	
+	// ISSET
+	if( isset($_GET['t']) ){ $text = stripslashes($_GET['t']); }else{ $text = null; }
+	
+	// DATA
+	$out = null;
+	if($text != null){
+		$out['str'] = TmNick::toHtml( nl2br($text), 10, false, false, '#666');
+	}
+	
+	// OUT
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/get_current_serverinfo.php b/resources/ajax/get_current_serverinfo.php
new file mode 100644
index 0000000..29908a2
--- /dev/null
+++ b/resources/ajax/get_current_serverinfo.php
@@ -0,0 +1,30 @@
+<?php
+	// INCLUDES
+	session_start();
+	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminlevel.cfg.php';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once $configPath.'extension.cfg.php';
+	require_once $configPath.'servers.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	AdminServUI::lang();
+	
+	// ISSET
+	if( isset($_GET['mode']) ){ $mode = addslashes($_GET['mode']); }else{ $mode = null; }
+	if( isset($_GET['sort']) ){ $sort = addslashes($_GET['sort']); }else{ $sort = null; }
+	if($mode){
+		$_SESSION['adminserv']['mode']['general'] = $mode;
+	}
+	
+	// DATA
+	if( AdminServ::initialize() ){
+		$out = AdminServ::getCurrentServerInfo($sort);
+	}
+	
+	// OUT
+	$client->Terminate();
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/get_directory_list.php b/resources/ajax/get_directory_list.php
new file mode 100644
index 0000000..6c4bcce
--- /dev/null
+++ b/resources/ajax/get_directory_list.php
@@ -0,0 +1,24 @@
+<?php
+	// INCLUDES
+	session_start();
+	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminlevel.cfg.php';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once $configPath.'extension.cfg.php';
+	require_once $configPath.'servers.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	
+	// DATA
+	$out = array();
+	if( AdminServ::initialize() ){
+		$path = AdminServ::getMapsDirectoryPath();
+		$out = Folder::getArborescence($path, AdminServConfig::$MAPS_HIDDEN_FOLDERS, substr_count($path, '/'));
+	}
+	
+	// OUT
+	$client->Terminate();
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/get_maplist.php b/resources/ajax/get_maplist.php
new file mode 100644
index 0000000..2add34f
--- /dev/null
+++ b/resources/ajax/get_maplist.php
@@ -0,0 +1,30 @@
+<?php
+	// INCLUDES
+	session_start();
+	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminlevel.cfg.php';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once $configPath.'extension.cfg.php';
+	require_once $configPath.'servers.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	AdminServUI::lang();
+	
+	// ISSET
+	if( isset($_GET['mode']) ){ $mode = addslashes($_GET['mode']); }else{ $mode = null; }
+	if( isset($_GET['sort']) ){ $sort = addslashes($_GET['sort']); }else{ $sort = null; }
+	if($mode){
+		$_SESSION['adminserv']['mode']['maps'] = $mode;
+	}
+	
+	// DATA
+	if( AdminServ::initialize() ){
+		$out = AdminServ::getMapList($sort);
+	}
+	
+	// OUT
+	$client->Terminate();
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/get_matchset_fileexists.php b/resources/ajax/get_matchset_fileexists.php
new file mode 100644
index 0000000..8fab51b
--- /dev/null
+++ b/resources/ajax/get_matchset_fileexists.php
@@ -0,0 +1,34 @@
+<?php
+	// INCLUDES
+	session_start();
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	
+	// ISSET
+	if( isset($_GET['path']) ){ $path = $_GET['path']; }else{ $path = null; }
+	if( isset($_GET['name']) ){ $name = $_GET['name']; }else{ $name = null; }
+	
+	// CHECKING
+	$out = false;
+	if($path && $name){
+		$struct = Folder::read($path);
+		if( !strstr($name, '.txt') ){
+			$name = $name.'.txt';
+		}
+		
+		if( count($struct['files']) > 0 ){
+			foreach($struct['files'] as $fileName => $fileValues){
+				if($name == $fileName){
+					$out = true;
+					break;
+				}
+			}
+		}
+	}
+	
+	// OUT
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/get_matchset_mapimport.php b/resources/ajax/get_matchset_mapimport.php
new file mode 100644
index 0000000..e534d7d
--- /dev/null
+++ b/resources/ajax/get_matchset_mapimport.php
@@ -0,0 +1,65 @@
+<?php
+	// INCLUDES
+	session_start();
+	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminlevel.cfg.php';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once $configPath.'extension.cfg.php';
+	require_once $configPath.'servers.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	AdminServUI::lang();
+	
+	// ISSET
+	if( isset($_GET['path']) ){ $path = addslashes($_GET['path']); }else{ $path = null; }
+	if( isset($_GET['d']) ){ $directory = addslashes($_GET['d']); }else{ $directory = null; }
+	if( isset($_GET['op']) ){ $operation = addslashes($_GET['op']); }else{ $operation = null; }
+	if( isset($_GET['select']) ){ $selection = $_GET['select']; }else{ $selection = null; }
+	
+	// DATA
+	$out = null;
+	if( AdminServ::initialize() && $path != null ){
+		// Maps
+		if($path == 'currentServerSelection'){
+			$mapsImport = AdminServ::getMapList();
+		}
+		else{
+			$currentDir = Folder::read($path, AdminServConfig::$MATCHSET_HIDDEN_FOLDERS, AdminServConfig::$MATCHSET_EXTENSION, intval(AdminServConfig::RECENT_STATUS_PERIOD * 3600) );
+			$mapsImport = AdminServ::getLocalMapList($currentDir, $directory);
+		}
+		
+		// Faire une sélection
+		if($operation == 'setSelection'){
+			// On supprime les maps non sélectionnées
+			if( $selection != null && count($selection) > 0 ){
+				foreach($mapsImport['lst'] as $id => $values){
+					if( !in_array($id, $selection) ){
+						unset($mapsImport['lst'][$id]);
+					}
+				}
+			}
+			else{
+				foreach($mapsImport['lst'] as $id => $values){
+					unset($mapsImport['lst'][$id]);
+				}
+			}
+		}
+		
+		// Enregistrement de la sélection du MatchSettings
+		if($operation != 'getSelection'){
+			AdminServ::saveMatchSettingSelection($mapsImport);
+		}
+		
+		$client->Terminate();
+	}
+	
+	// OUT
+	if($operation == 'getSelection'){
+		echo json_encode($mapsImport);
+	}
+	else{
+		echo json_encode($_SESSION['adminserv']['matchset_maps_selected']);
+	}
+?>
\ No newline at end of file
diff --git a/resources/ajax/get_matchset_mapselection.php b/resources/ajax/get_matchset_mapselection.php
new file mode 100644
index 0000000..510f8cf
--- /dev/null
+++ b/resources/ajax/get_matchset_mapselection.php
@@ -0,0 +1,38 @@
+<?php
+	// INCLUDES
+	session_start();
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	AdminServUI::lang();
+	
+	// DATA
+	if( !isset($_SESSION['adminserv']['matchset_maps_selected']) ){
+		// Retourne "Aucune map"
+		AdminServ::saveMatchSettingSelection();
+	}
+	else{
+		// Enlever une map de la sélection
+		if( isset($_GET['remove']) ){
+			$removeSelection = intval($_GET['remove']);
+			$mapsSelection = $_SESSION['adminserv']['matchset_maps_selected'];
+			
+			// Liste
+			if( isset($mapsSelection['lst']) && is_array($mapsSelection['lst']) && count($mapsSelection['lst']) > 0 ){
+				foreach($mapsSelection['lst'] as $id => $values){
+					if($id == $removeSelection){
+						unset($mapsSelection['lst'][$id]);
+						break;
+					}
+				}
+			}
+			
+			$_SESSION['adminserv']['matchset_maps_selected'] = $mapsSelection;
+			AdminServ::saveMatchSettingSelection();
+		}
+	}
+	
+	echo json_encode($_SESSION['adminserv']['matchset_maps_selected']);
+?>
\ No newline at end of file
diff --git a/resources/ajax/get_server_adminlevel.php b/resources/ajax/get_server_adminlevel.php
new file mode 100644
index 0000000..5be220b
--- /dev/null
+++ b/resources/ajax/get_server_adminlevel.php
@@ -0,0 +1,21 @@
+<?php
+	// INCLUDES
+	session_start();
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminlevel.cfg.php';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once $configPath.'servers.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	
+	// ISSET
+	if( isset($_GET['srv']) ){ $serverName = $_GET['srv']; }else{ $serverName = null; }
+	
+	$out = array();
+	if($serverName != null){
+		$out = AdminServAdminLevel::getServerList($serverName);
+	}
+	
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/mapsorder_sort.php b/resources/ajax/mapsorder_sort.php
new file mode 100644
index 0000000..7188813
--- /dev/null
+++ b/resources/ajax/mapsorder_sort.php
@@ -0,0 +1,46 @@
+<?php
+	// INCLUDES
+	session_start();
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	
+	// ISSET
+ 	if( isset($_POST['srt']) ){ $sort = $_POST['srt']; }else{ $sort = null; }
+	if( isset($_POST['ord']) ){ $order = $_POST['ord']; }else{ $order = 'asc'; }
+	if( isset($_POST['lst']) ){ $list = $_POST['lst']; }else{ $list = null; }
+	
+	// DATA
+	$out = null;
+	if($sort != null && $list != null){
+		$list = json_decode($list, true);
+		
+		switch($sort){
+			case 'name':
+				usort($list['lst'], 'AdminServSort::sortByName');
+				break;
+			case 'env':
+				usort($list['lst'], 'AdminServSort::sortByEnviro');
+				break;
+			case 'author':
+				usort($list['lst'], 'AdminServSort::sortByAuthor');
+				break;
+			case 'rand':
+				shuffle($list['lst']);
+				break;
+		}
+		if($order == 'desc'){
+			$list['lst'] = array_reverse($list['lst']);
+		}
+		$out = array(
+			'cid' => $list['cid'],
+			'lst' => $list['lst'],
+			'nbm' => $list['nbm'],
+		);
+	}
+	
+	// OUT
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/script_settings.php b/resources/ajax/script_settings.php
new file mode 100644
index 0000000..4a2e6b8
--- /dev/null
+++ b/resources/ajax/script_settings.php
@@ -0,0 +1,51 @@
+<?php
+	// INCLUDES
+	session_start();
+	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminlevel.cfg.php';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once $configPath.'extension.cfg.php';
+	require_once $configPath.'servers.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	
+	// ISSET
+	if( isset($_POST['method']) ){ $method = $_POST['method']; }else{ $method = null; }
+	if( isset($_POST['params']) ){ $params = $_POST['params']; }else{ $params = null; }
+	
+	// DATA
+	$out = null;
+	if( AdminServ::initialize() ){
+		if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+			if($method == 'set' && $params != null){
+				$scriptSettings = array();
+				if( count($params) > 0 ){
+					foreach($params as $param){
+						$scriptSettings[$param['name']] = Str::setValueType($param['value'], $param['type']);
+					}
+				}
+				
+				if( !$client->query('SetModeScriptSettings', $scriptSettings) ){
+					$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+				}
+				else{
+					$out = true;
+				}
+			}
+			else{
+				if( !$client->query('GetModeScriptInfo') ){
+					$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+				}
+				else{
+					$out = $client->getResponse();
+				}
+			}
+		}
+	}
+	
+	// OUT
+	$client->Terminate();
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/speed_admin.php b/resources/ajax/speed_admin.php
new file mode 100644
index 0000000..c8dea70
--- /dev/null
+++ b/resources/ajax/speed_admin.php
@@ -0,0 +1,28 @@
+<?php
+	// INCLUDES
+	session_start();
+	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
+	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
+	require_once $configPath.'adminlevel.cfg.php';
+	require_once $configPath.'adminserv.cfg.php';
+	require_once $configPath.'extension.cfg.php';
+	require_once $configPath.'servers.cfg.php';
+	require_once '../core/adminserv.php';
+	AdminServConfig::$PATH_RESOURCES = '../';
+	AdminServ::getClass();
+	
+	// ISSET
+	if( isset($_POST['cmd']) ){ $cmd = addslashes( htmlspecialchars($_POST['cmd']) ); }else{ $cmd = null; }
+	
+	// SPEED ADMIN
+	$out = false;
+	if($cmd != null){
+		if( AdminServ::initialize() ){
+			$out = AdminServ::speedAdmin($cmd);
+		}
+	}
+	
+	// OUT
+	$client->Terminate();
+	echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/resources/ajax/upload.php b/resources/ajax/upload.php
new file mode 100644
index 0000000..4605274
--- /dev/null
+++ b/resources/ajax/upload.php
@@ -0,0 +1 @@
+<?php	// INCLUDES	session_start();	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';	require_once $configPath.'adminlevel.cfg.php';	require_once $configPath.'adminserv.cfg.php';	require_once $configPath.'extension.cfg.php';	require_once $configPath.'servers.cfg.php';	require_once '../core/adminserv.php';	AdminServConfig::$PATH_RESOURCES = '../';	AdminServ::getClass();	AdminServUI::lang();	// ISSET	if( isset($_GET['path']) ){ $path = $_GET['path']; }else{ $path = null; }	if( isset($_GET['gtlm']) ){ $gtlm = $_GET['gtlm']; }else{ $gtlm = null; }	if( isset($_GET['mset']) ){ $mset = $_GET['mset']; }else{ $mset = null; }	if( isset($_GET['type']) ){ $type = $_GET['type']; }else{ $type = null; }	// DATA	if( AdminServ::initialize() ){		// Path		$mapDirectoryPath = AdminServ::getMapsDirectoryPath();		if(preg_match('/^\//', $path)){            header("HTTP/1.1 400 Bad Request");            die("Absolute paths are not allowed.");        }		if($path === null){			$path = $mapDirectoryPath;		}		if( substr($path, -1, 1) != '/'){			$path = $path.'/';		}		if( !file_exists($path) ){			$path = null;			if( defined('AdminServConfig::UPLOAD_ONLINE_FOLDER') && AdminServConfig::UPLOAD_ONLINE_FOLDER != null ){				$path = AdminServConfig::UPLOAD_ONLINE_FOLDER;			}		}		// Fonction de rappel pour le remplacement des caractères spéciaux		function replaceFilename($str){			return Str::replaceChars($str);		}		// Jeu		if(SERVER_VERSION_NAME == 'TmForever'){			$queries = array(				'insert' => 'InsertChallenge',				'add' => 'AddChallenge',				'type' => $type			);		}		else{			$queries = array(				'insert' => 'InsertMap',				'add' => 'AddMap',				'type' => $type			);		}		// Taille max		if(AdminServConfig::SIZE_LIMIT == 'auto'){			$sizeLimit1 = (intval(ini_get('post_max_size')) * 1024 * 1024);			$sizeLimit2 = (intval(ini_get('upload_max_filesize')) * 1024 * 1024);			$sizeLimit = min($sizeLimit1, $sizeLimit2);		}		else{			$sizeLimit = (intval(AdminServConfig::SIZE_LIMIT) * 1024 * 1024);		}		// Enregistrement du fichier		$result = FileUploader::saveUploadedFileToManiaPlanetServer($client, $path, $queries, AdminServConfig::$ALLOWED_EXTENSIONS, $sizeLimit, 'replaceFilename');		// Sauvegarde du MatchSettings		if($mset && SERVER_MATCHSET && $type != 'local' && isset($result['success']) && $result['success'] == true){			if( !$client->query('SaveMatchSettings', $mapDirectoryPath.SERVER_MATCHSET) ){				$result['error'] = '['.$client->getErrorCode().'] '.$client->getErrorMessage();			}		}	}	$client->Terminate();	echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);?>
\ No newline at end of file
diff --git a/resources/cache/mapslist-DtrackmaniadedicatedUserDataMaps.json b/resources/cache/mapslist-DtrackmaniadedicatedUserDataMaps.json
new file mode 100644
index 0000000..61c2ca2
--- /dev/null
+++ b/resources/cache/mapslist-DtrackmaniadedicatedUserDataMaps.json
@@ -0,0 +1 @@
+{"4x4-off-road.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#663300\">4x4 off road<\/span><\/span>","Environment":"Canyon","FileName":"4x4-off-road.Map.Gbx","UId":"Qv3k5wnovhc5WbbEmUMsXXao3A1","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"8-defonce.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#006666\">8 d\u00e9fonc\u00e9<\/span><\/span>","Environment":"Canyon","FileName":"8-defonce.Map.Gbx","UId":"hYenoR7LZzdVSgaux_pSEYNwu45","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Attention-au-frein.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc33\">Attention au frein<\/span><\/span>","Environment":"Canyon","FileName":"Attention-au-frein.Map.Gbx","UId":"a0pRKdQoPI5zLmADzIGZLzHwdPh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Attraction.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">Attraction<\/span><\/span>","Environment":"Canyon","FileName":"Attraction.Map.Gbx","UId":"M42mf_WR3zKFGngLdv4dl_WkSkf","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Autoroute.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#009900\">Autoroute<\/span><\/span>","Environment":"Canyon","FileName":"Autoroute.Map.Gbx","UId":"sZ9IeicBn4KAq28YmjmstwEYjv0","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Boite.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0066\">Boite<\/span><\/span>","Environment":"Canyon","FileName":"Boite.Map.Gbx","UId":"LjZ10Y1fpp9OUIuX7O71Mb7PZ01","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Canada---Etape-1.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">Canada <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 1<\/span><\/span>","Environment":"Canyon","FileName":"Canada---Etape-1.Map.Gbx","UId":"04Bc42Q79i87E8kAQz6_kdX7tQj","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Canada---Etape-2.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">Canada <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 2<\/span><\/span>","Environment":"Canyon","FileName":"Canada---Etape-2.Map.Gbx","UId":"b81vfeiBo9am2NxJTZmGr39pjW8","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Canada---Etape-3.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">Canada <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 3<\/span><\/span>","Environment":"Canyon","FileName":"Canada---Etape-3.Map.Gbx","UId":"y5onnQXohjAB0IM5R4RAdaitTKe","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Canada---Etape-4.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">Canada <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 4<\/span><\/span>","Environment":"Canyon","FileName":"Canada---Etape-4.Map.Gbx","UId":"NK37fOQJaYX7TFrnBV3uQnZ8S93","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"CreationSkin.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:white\">Cr\u00e9ationSkin<\/span><\/span>","Environment":"Canyon","FileName":"CreationSkin.Map.Gbx","UId":"4JUUciJTt4pXA31rhzziUnMsW31","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Race"}},"Egypte---Etape-1.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc00\">Egypte <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 1<\/span><\/span>","Environment":"Canyon","FileName":"Egypte---Etape-1.Map.Gbx","UId":"FbRbV3sLZgvSPOa2cgpFssfmsYe","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Egypte---Etape-2.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc00\">Egypte <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 2<\/span><\/span>","Environment":"Canyon","FileName":"Egypte---Etape-2.Map.Gbx","UId":"wgmbpGVJ4YDN1rWnv3rQgK1OzJg","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Egypte---Etape-3.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc00\">Egypte <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 3<\/span><\/span>","Environment":"Canyon","FileName":"Egypte---Etape-3.Map.Gbx","UId":"2OWdjMFiLnIKTDPbLIaKEoY4pu0","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Egypte---Etape-4.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc00\">Egypte <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 4<\/span><\/span>","Environment":"Canyon","FileName":"Egypte---Etape-4.Map.Gbx","UId":"kERIXFivYyDC48EokcdoMHNMa24","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Elite---ArchWays.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite - <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff2200\">Ar<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff3311\">ch<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff4422\">Wa<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff5533\">ys<\/span><\/span>","Environment":"Storm","FileName":"Elite---ArchWays.Map.Gbx","UId":"SKFHlXwDZnJiau2r2iRMMur7BC5","Author":"nadeolive","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---Collided.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite - <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff2200\">Co<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff3311\">lli<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff4422\">de<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff5533\">d<\/span><\/span>","Environment":"Storm","FileName":"Elite---Collided.Map.Gbx","UId":"03K2a6a0q9WihtbQmEodDXsQZE9","Author":"nadeolive","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---ESL_Tilt.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite - <\/span><span class=\"tmnick_italic tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">ESL|<\/span><span class=\"\" style=\"font-size: 10pt;color:white\"> Tilt<\/span><\/span>","Environment":"Storm","FileName":"Elite---ESL_Tilt.Map.Gbx","UId":"MG5o8ZAHgcD4zZtrnzScizCjFZd","Author":"kyb","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---Fortress.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite - <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff2200\">Fo<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff3311\">rt<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff4422\">re<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff5533\">ss<\/span><\/span>","Environment":"Storm","FileName":"Elite---Fortress.Map.Gbx","UId":"6niuYlVqoCIkDlCdFTpEZTh7LF8","Author":"nadeolive","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---Isolated-.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:white\">Elite - Isolated <\/span><\/span>","Environment":"Storm","FileName":"Elite---Isolated-.Map.Gbx","UId":"0kJYrghOkWOUBV2Ym1o_GbqIjfl","Author":"skoonyz","Recent":0,"Type":{"Name":"SiegeArena","FullName":"ShootMania\\SiegeArena"}},"Elite---Paladin.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite<\/span><span class=\"tmnick_bold\" style=\"font-size: 10pt;color:white\"> - <\/span><span class=\"tmnick_bold\" style=\"font-size: 10pt;color:#ffff55\">Paladin<\/span><\/span>","Environment":"Storm","FileName":"Elite---Paladin.Map.Gbx","UId":"M50azStIw1KWYPAJOGitLV4msYk","Author":"kryw","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---Quick.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:white\">Elite - Quick<\/span><\/span>","Environment":"Storm","FileName":"Elite---Quick.Map.Gbx","UId":"lD4uGyw8OGFTJgUxpfVEAREnBA3","Author":"skoonyz","Recent":0,"Type":{"Name":"SiegeArena","FullName":"ShootMania\\SiegeArena"}},"Elite---Swift.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite<\/span><span class=\"tmnick_bold\" style=\"font-size: 10pt;color:white\"> - <\/span><span class=\"tmnick_bold tmnick_italic\" style=\"font-size: 10pt;color:#004499\">Swift<\/span><\/span>","Environment":"Storm","FileName":"Elite---Swift.Map.Gbx","UId":"48FyaLm__ft12cQ6i96KrmoRuwi","Author":"ph0enix","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---TheCastle.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite - <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff2200\">Th<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff3311\">eC<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff4422\">as<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff5533\">tl<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff6644\">e<\/span><\/span>","Environment":"Storm","FileName":"Elite---TheCastle.Map.Gbx","UId":"Lx2Ik2GEcSObirozQvio6bRRWHj","Author":"nadeolive","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Finlande---Etape-1.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#003399\">Finlande <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 1<\/span><\/span>","Environment":"Canyon","FileName":"Finlande---Etape-1.Map.Gbx","UId":"Jjv2bS9bSAhPDo0ddGQ65IuHahh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Finlande---Etape-2.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#003399\">Finlande <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 2<\/span><\/span>","Environment":"Canyon","FileName":"Finlande---Etape-2.Map.Gbx","UId":"VN5iYuP5oYx0PnvDKHbM09TKPL1","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Finlande---Etape-3.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#003399\">Finlande <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 3<\/span><\/span>","Environment":"Canyon","FileName":"Finlande---Etape-3.Map.Gbx","UId":"Saa55CJ4euzzNo8sYf1BhwwhEN8","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Finlande---Etape-4.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#003399\">Finlande <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 4<\/span><\/span>","Environment":"Canyon","FileName":"Finlande---Etape-4.Map.Gbx","UId":"ub3X0hFop3dyIdJXV_SeZID27Dh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Free-way.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#99ff33\">Free way<\/span><\/span>","Environment":"Canyon","FileName":"Free-way.Map.Gbx","UId":"ftaKnDEO7zyYIH0Irdxn6wonXD0","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Hummm.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0099cc\">Hummm<\/span><\/span>","Environment":"Canyon","FileName":"Hummm.Map.Gbx","UId":"4yRQq_90nR47IxnaHu1evHDIDm3","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"In-the-sky.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#66ffff\">In the sky<\/span><\/span>","Environment":"Canyon","FileName":"In-the-sky.Map.Gbx","UId":"dEu6pX1lC02z7sgIh8L3PXmIAhh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Jouissance-saccadee.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#996600\">Jou\u00efssance saccad\u00e9e<\/span><\/span>","Environment":"Canyon","FileName":"Jouissance-saccadee.Map.Gbx","UId":"l4ZFhAq_iVFEwcWOnUqShYcxZok","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Jump-and-jump-and....Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#000033\">Jump and jump and...<\/span><\/span>","Environment":"Canyon","FileName":"Jump-and-jump-and....Map.Gbx","UId":"IlA6Gk99GLAhmlRiyhA6EttoXW3","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Jump-around.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc00\">Jump around<\/span><\/span>","Environment":"Canyon","FileName":"Jump-around.Map.Gbx","UId":"AxYOLDm_yHl8Vpr2OTKPrjjNWic","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Labyrinthe.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ccff00\">Labyrinthe<\/span><\/span>","Environment":"Canyon","FileName":"Labyrinthe.Map.Gbx","UId":"qjhyktiuJbyuYe1WmeU5cEhFrSb","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Looping-en-folie.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0000cc\">Looping en folie<\/span><\/span>","Environment":"Canyon","FileName":"Looping-en-folie.Map.Gbx","UId":"4fTM17a8FfjhYK7eTczAWbp5Rzl","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Micromania-1.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#990033\">Micromania <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">#1<\/span><\/span>","Environment":"Canyon","FileName":"Micromania-1.Map.Gbx","UId":"RiP6EIEzDXeDpoyeDW46Nd5AFY3","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Mountain.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:white\">Mountain<\/span><\/span>","Environment":"Canyon","FileName":"Mountain.Map.Gbx","UId":"aiYLZv1Rfye5oyortcvA2xLfzSd","Author":"dangmaar","Recent":0,"Type":{"Name":"Race","FullName":"Race"}},"Multi-track.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#cc6600\">Multi track<\/span><\/span>","Environment":"Canyon","FileName":"Multi-track.Map.Gbx","UId":"J5mYHM7toOpf02a84rxqDgHz74","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Pilot-only.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#9933cc\">Pilot only<\/span><\/span>","Environment":"Canyon","FileName":"Pilot-only.Map.Gbx","UId":"hV5F90irAgT8KCItlA98lffhI_i","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Propulsion-arride.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#990000\">Propulsion arride<\/span><\/span>","Environment":"Canyon","FileName":"Propulsion-arride.Map.Gbx","UId":"JoGkfMUfcPbFwJlEcEF3YDUiiQ1","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Race-building.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#000000\">Race building<\/span><\/span>","Environment":"Canyon","FileName":"Race-building.Map.Gbx","UId":"anbrAYil1kFI0RRPfHwGdzzjeNh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Razmotte.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#99ff00\">Razmotte<\/span><\/span>","Environment":"Canyon","FileName":"Razmotte.Map.Gbx","UId":"a9zuQJgfKHz20kAsYSQlDMxGxfk","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"TrackMania\\Race"}},"Routes-de-corse.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#cc5500\">Routes de corse<\/span><\/span>","Environment":"Canyon","FileName":"Routes-de-corse.Map.Gbx","UId":"npVglWKptFQoczmEBB7fkbvYJjj","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Suede---Etape-1.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0088cc\">Su\u00e8de <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffff00\">Etape 1<\/span><\/span>","Environment":"Canyon","FileName":"Suede---Etape-1.Map.Gbx","UId":"0JSJchwnoPLXs7E0kSREdRVxAR1","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Suede---Etape-2.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0088cc\">Su\u00e8de <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffff00\">Etape 2<\/span><\/span>","Environment":"Canyon","FileName":"Suede---Etape-2.Map.Gbx","UId":"aQYVgcAnWd8W6o4yOXx8HHEDPS9","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Suede---Etape-3.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0088cc\">Su\u00e8de <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffff00\">Etape 3<\/span><\/span>","Environment":"Canyon","FileName":"Suede---Etape-3.Map.Gbx","UId":"8VX6HVIT_wCCBhgWIOKcMwm5O_2","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Suede---Etape-4.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0088cc\">Su\u00e8de <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffff00\">Etape 4<\/span><\/span>","Environment":"Canyon","FileName":"Suede---Etape-4.Map.Gbx","UId":"pirzLg0bV7owjst4AG6Yu2Qtphh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Tmeless..Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#000000\">T<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">!<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#000000\">meless<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">.<\/span><\/span>","Environment":"Stadium","FileName":"Tmeless..Map.Gbx","UId":"UoU7guI2ww_P5cWCRwUMfSej3w1","Author":"unholy79","Recent":0,"Type":{"Name":"Race","FullName":"TrackMania\\Race"}}}
\ No newline at end of file
diff --git a/resources/class/GbxRemote.inc.php b/resources/class/GbxRemote.inc.php
new file mode 100644
index 0000000..3366424
--- /dev/null
+++ b/resources/class/GbxRemote.inc.php
@@ -0,0 +1,880 @@
+<?php
+/* vim: set noexpandtab tabstop=2 softtabstop=2 shiftwidth=2: */
+
+/*
+	IXR - The Incutio XML-RPC Library - (c) Incutio Ltd 2002
+	Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
+	Site:   http://scripts.incutio.com/xmlrpc/
+	Manual: http://scripts.incutio.com/xmlrpc/manual.php
+	Errors: http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
+	Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php
+
+	Modified to support protocol 'GbxRemote 2' ('GbxRemote 1')
+	This version is for LittleEndian (e.g. Intel PC) machines.  For BegEndian
+	machines use GbxRemote.bem.php as GbxRemote.inc.php instead.
+
+	Release 2007-09-22 - Slig:
+		Modified to support >256KB received data (and now >2MB data produce a specific error message)
+		Modified readCB() to wait the initial timeout only before first read packet
+		Modified readCB() to return true if there is data to get with getCBResponses()
+		Modified to support amd64 (for $recvhandle)
+		Modified IXR_ClientMulticall_Gbx::addCall() to fit Aseco 0.6.1
+		Added IXR_Client_Gbx::bytes_sent & bytes_received counters
+		Fix for a changed feature since php5.1.1 about reference parameter assignment (was used in stream_select)
+		Workaround for stream_select return value bug with amd64
+
+	Release 2008-01-20 - Slig / Xymph / Assembler Maniac:
+		Workaround for fread delay bug in some cases
+		Added IXR_Client_Gbx::resetError() method (by Xymph)
+		Some comments and strings code cleanup (by Xymph)
+		Fix stream_set_timeout($this->socket,...) (thx to CavalierDeVache)
+		Added a default timeout value to IXR_Client_Gbx::readCB($timeout)
+		Changed calls with timeout on a stream to use microseconds instead of seconds (by AM)
+		Removed IXR_Client_Gbx::bytes_sent & bytes_received counters - not used (by AM)
+
+	Release 2008-02-05 - Slig:
+		Changed some socket read/write timeouts back to seconds to avoid 'transport error'
+		Changed max data received from 2MB to 4MB
+
+	Release 2008-05-20 - Xymph:
+		Prevented unpack() warnings in IXR_Client_Gbx::query() when the connection dies
+		Changed IXR_Client_Gbx::resetError() to assign 'false' for correct isError()
+		Tweaked some 'transport error' messages
+
+	Release 2009-04-08 - Gou1:
+		Added method IXR_Client_Gbx::queryIgnoreResult()
+		Added methods IXR_Client_Gbx::sendRequest() & IXR_Client_Gbx::getResult()
+		IXR_Client_Gbx::queryIgnoreResult checks if the request is larger than 512KB to avoid errors
+		If larger than 512KB and method is system.multicall, try to divide the request into
+		two separate requests with two separate IXR_Client_Gbx::queryIgnoreResult() calls
+
+	Release 2009-06-03 - Xymph:
+		Suppress possible repetitive CRT warning at stream_select
+
+	Release 2011-04-09 - Xymph / La beuze:
+		Added optional timeout mechanism to IXR_Client_Gbx::InitWithIp()
+
+	Release 2011-05-22 - Xymph:
+		Added non-error (true) return status to IXR_Client_Gbx::queryIgnoreResult()
+		Updated status codes and messages for transport/endian errors
+		Prevented possible PHP warning in IXR_Client_Gbx::getErrorCode() and getErrorMessage()
+
+	Release 2011-12-04 - Xymph:
+		Prevented possible PHP warning in IXR_Value::calculateType
+*/
+
+if (!defined('LF')) {
+	define('LF', "\n");
+}
+
+class IXR_Value {
+	public $data;
+	public $type;
+
+	function IXR_Value ($data, $type = false) {
+		$this->data = $data;
+		if (!$type) {
+			$type = $this->calculateType();
+		}
+		$this->type = $type;
+		if ($type == 'struct') {
+			// Turn all the values in the array into new IXR_Value objects
+			foreach ($this->data as $key => $value) {
+				$this->data[$key] = new IXR_Value($value);
+			}
+		}
+		if ($type == 'array') {
+			for ($i = 0, $j = count($this->data); $i < $j; $i++) {
+				$this->data[$i] = new IXR_Value($this->data[$i]);
+			}
+		}
+	}
+
+	function calculateType() {
+		if ($this->data === true || $this->data === false) {
+			return 'boolean';
+		}
+		if (is_integer($this->data)) {
+			return 'int';
+		}
+		if (is_double($this->data)) {
+			return 'double';
+		}
+		// Deal with IXR object types base64 and date
+		if (is_object($this->data) && ($this->data instanceof IXR_Date)) {
+			return 'date';
+		}
+		if (is_object($this->data) && ($this->data instanceof IXR_Base64)) {
+			return 'base64';
+		}
+		// If it is a normal PHP object convert it into a struct
+		if (is_object($this->data)) {
+			$this->data = get_object_vars($this->data);
+			return 'struct';
+		}
+		if (!is_array($this->data)) {
+			return 'string';
+		}
+		// We have an array - is it an array or a struct?
+		if ($this->isStruct($this->data)) {
+			return 'struct';
+		} else {
+			return 'array';
+		}
+	}
+
+	function getXml() {
+		// Return XML for this value
+		switch ($this->type) {
+			case 'boolean':
+				return '<boolean>' . ($this->data ? '1' : '0') . '</boolean>';
+				break;
+			case 'int':
+				return '<int>' . $this->data . '</int>';
+				break;
+			case 'double':
+				return '<double>' . $this->data . '</double>';
+				break;
+			case 'string':
+				return '<string>' . htmlspecialchars($this->data) . '</string>';
+				break;
+			case 'array':
+				$return = '<array><data>' . LF;
+				foreach ($this->data as $item) {
+					$return .= '	<value>' . $item->getXml() . '</value>' . LF;
+				}
+				$return .= '</data></array>';
+				return $return;
+				break;
+			case 'struct':
+				$return = '<struct>' . LF;
+				foreach ($this->data as $name => $value) {
+					$return .= '	<member><name>' . $name . '</name><value>';
+					$return .= $value->getXml() . '</value></member>' . LF;
+				}
+				$return .= '</struct>';
+				return $return;
+				break;
+			case 'date':
+			case 'base64':
+				return $this->data->getXml();
+				break;
+		}
+		return false;
+	}
+
+	function isStruct($array) {
+		// Nasty function to check if an array is a struct or not
+		$expected = 0;
+		foreach ($array as $key => $value) {
+			if ((string)$key != (string)$expected) {
+				return true;
+			}
+			$expected++;
+		}
+		return false;
+	}
+}
+
+
+class IXR_Message {
+	public $message;
+	public $messageType;  // methodCall / methodResponse / fault
+	public $faultCode;
+	public $faultString;
+	public $methodName;
+	public $params;
+	// Current variable stacks
+	protected $_arraystructs = array();  // Stack to keep track of the current array/struct
+	protected $_arraystructstypes = array();  // Stack to keep track of whether things are structs or array
+	protected $_currentStructName = array();  // A stack as well
+	protected $_param;
+	protected $_value;
+	protected $_currentTag;
+	protected $_currentTagContents;
+	// The XML parser
+	protected $_parser;
+
+	function IXR_Message ($message) {
+		$this->message = $message;
+	}
+
+	function parse() {
+		// first remove the XML declaration
+		$this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message);
+		if (trim($this->message) == '') {
+			return false;
+		}
+		$this->_parser = xml_parser_create();
+		// Set XML parser to take the case of tags into account
+		xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
+		// Set XML parser callback functions
+		xml_set_object($this->_parser, $this);
+		xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
+		xml_set_character_data_handler($this->_parser, 'cdata');
+		if (!xml_parse($this->_parser, $this->message)) {
+			/* die(sprintf('GbxRemote XML error: %s at line %d',
+			               xml_error_string(xml_get_error_code($this->_parser)),
+			               xml_get_current_line_number($this->_parser))); */
+			return false;
+		}
+		xml_parser_free($this->_parser);
+		// Grab the error messages, if any
+		if ($this->messageType == 'fault') {
+			$this->faultCode = $this->params[0]['faultCode'];
+			$this->faultString = $this->params[0]['faultString'];
+		}
+		return true;
+	}
+
+	function tag_open($parser, $tag, $attr) {
+		$this->currentTag = $tag;
+		switch ($tag) {
+			case 'methodCall':
+			case 'methodResponse':
+			case 'fault':
+				$this->messageType = $tag;
+				break;
+			// Deal with stacks of arrays and structs
+			case 'data':  // data is to all intents and purposes more interesting than array
+				$this->_arraystructstypes[] = 'array';
+				$this->_arraystructs[] = array();
+				break;
+			case 'struct':
+				$this->_arraystructstypes[] = 'struct';
+				$this->_arraystructs[] = array();
+				break;
+		}
+	}
+
+	function cdata($parser, $cdata) {
+		$this->_currentTagContents .= $cdata;
+	}
+
+	function tag_close($parser, $tag) {
+		$valueFlag = false;
+		switch ($tag) {
+			case 'int':
+			case 'i4':
+				$value = (int)trim($this->_currentTagContents);
+				$this->_currentTagContents = '';
+				$valueFlag = true;
+				break;
+			case 'double':
+				$value = (double)trim($this->_currentTagContents);
+				$this->_currentTagContents = '';
+				$valueFlag = true;
+				break;
+			case 'string':
+				$value = (string)trim($this->_currentTagContents);
+				$this->_currentTagContents = '';
+				$valueFlag = true;
+				break;
+			case 'dateTime.iso8601':
+				$value = new IXR_Date(trim($this->_currentTagContents));
+				// $value = $iso->getTimestamp();
+				$this->_currentTagContents = '';
+				$valueFlag = true;
+				break;
+			case 'value':
+				// If no type is indicated, the type is string
+				if (trim($this->_currentTagContents) != '') {
+					$value = (string)$this->_currentTagContents;
+					$this->_currentTagContents = '';
+					$valueFlag = true;
+				}
+				break;
+			case 'boolean':
+				$value = (boolean)trim($this->_currentTagContents);
+				$this->_currentTagContents = '';
+				$valueFlag = true;
+				break;
+			case 'base64':
+				$value = base64_decode($this->_currentTagContents);
+				$this->_currentTagContents = '';
+				$valueFlag = true;
+				break;
+				// Deal with stacks of arrays and structs
+			case 'data':
+			case 'struct':
+				$value = array_pop($this->_arraystructs);
+				array_pop($this->_arraystructstypes);
+				$valueFlag = true;
+				break;
+			case 'member':
+				array_pop($this->_currentStructName);
+				break;
+			case 'name':
+				$this->_currentStructName[] = trim($this->_currentTagContents);
+				$this->_currentTagContents = '';
+				break;
+			case 'methodName':
+				$this->methodName = trim($this->_currentTagContents);
+				$this->_currentTagContents = '';
+				break;
+		}
+
+		if ($valueFlag) {
+			/*
+			if (!is_array($value) && !is_object($value)) {
+				$value = trim($value);
+			}
+			*/
+			if (count($this->_arraystructs) > 0) {
+				// Add value to struct or array
+				if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') {
+					// Add to struct
+					$this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value;
+				} else {
+					// Add to array
+					$this->_arraystructs[count($this->_arraystructs)-1][] = $value;
+				}
+			} else {
+				// Just add as a paramater
+				$this->params[] = $value;
+			}
+		}
+	}
+}
+
+
+class IXR_Request {
+	public $method;
+	public $args;
+	public $xml;
+
+	function IXR_Request($method, $args) {
+		$this->method = $method;
+		$this->args = $args;
+		$this->xml = '<?xml version="1.0" encoding="utf-8" ?><methodCall><methodName>' . $this->method . '</methodName><params>';
+		foreach ($this->args as $arg) {
+			$this->xml .= '<param><value>';
+			$v = new IXR_Value($arg);
+			$this->xml .= $v->getXml();
+			$this->xml .= '</value></param>' . LF;
+		}
+		$this->xml .= '</params></methodCall>';
+	}
+
+	function getLength() {
+		return strlen($this->xml);
+	}
+
+	function getXml() {
+		return $this->xml;
+	}
+}
+
+
+class IXR_Error {
+	public $code;
+	public $message;
+
+	function IXR_Error($code, $message) {
+		$this->code = $code;
+		$this->message = $message;
+	}
+
+	function getXml() {
+		$xml = <<<EOD
+<methodResponse>
+	<fault>
+		<value>
+			<struct>
+				<member>
+					<name>faultCode</name>
+					<value><int>{$this->code}</int></value>
+				</member>
+				<member>
+					<name>faultString</name>
+					<value><string>{$this->message}</string></value>
+				</member>
+			</struct>
+		</value>
+	</fault>
+</methodResponse>
+EOD;
+		return $xml;
+	}
+}
+
+
+class IXR_Date {
+	public $year;
+	public $month;
+	public $day;
+	public $hour;
+	public $minute;
+	public $second;
+
+	function IXR_Date($time) {
+		// $time can be a PHP timestamp or an ISO one
+		if (is_numeric($time)) {
+			$this->parseTimestamp($time);
+		} else {
+			$this->parseIso($time);
+		}
+	}
+
+	function parseTimestamp($timestamp) {
+		$this->year = date('Y', $timestamp);
+		$this->month = date('Y', $timestamp);
+		$this->day = date('Y', $timestamp);
+		$this->hour = date('H', $timestamp);
+		$this->minute = date('i', $timestamp);
+		$this->second = date('s', $timestamp);
+	}
+
+	function parseIso($iso) {
+		$this->year = substr($iso, 0, 4);
+		$this->month = substr($iso, 4, 2);
+		$this->day = substr($iso, 6, 2);
+		$this->hour = substr($iso, 9, 2);
+		$this->minute = substr($iso, 12, 2);
+		$this->second = substr($iso, 15, 2);
+	}
+
+	function getIso() {
+		return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second;
+	}
+
+	function getXml() {
+		return '<dateTime.iso8601>'.$this->getIso().'</dateTime.iso8601>';
+	}
+
+	function getTimestamp() {
+		return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
+	}
+}
+
+
+class IXR_Base64 {
+	public $data;
+
+	function IXR_Base64($data) {
+		$this->data = $data;
+	}
+
+	function getXml() {
+		return '<base64>'.base64_encode($this->data).'</base64>';
+	}
+}
+
+
+//////////////////////////////////////////////////////////
+// Nadeo modifications                                  //
+//  (many thanks to slig for adding callback support)   //
+//////////////////////////////////////////////////////////
+class IXR_Client_Gbx {
+	public $socket;
+	public $message = false;
+	public $cb_message = array();
+	public $reqhandle;
+	public $protocol = 0;
+	// Storage place for an error message
+	public $error = false;
+
+	function bigEndianTest() {
+		list($endiantest) = array_values(unpack('L1L', pack('V', 1)));
+		if ($endiantest != 1) {
+			echo "Machine reports itself as BigEndian, float handling must be altered\r\n";
+			echo "Overwrite GbxRemote.inc.php with GbxRemote.bem.php\r\n";
+			die('App Terminated');
+			return false;
+		}
+		return true;
+	}  // bigEndianTest
+
+	function IXR_Client_Gbx() {
+		$this->socket = false;
+		$this->reqhandle = 0x80000000;
+	}
+
+	function InitWithIp($ip, $port, $timeout = null) {
+
+		if (!$this->bigEndianTest()) {
+			$this->error = new IXR_Error(-31999, 'endian error - script doesn\'t match machine type');
+			return false;
+		}
+
+		// open connection, with timeout if specified
+		if (!isset($timeout)) {
+			$this->socket = @fsockopen($ip, $port, $errno, $errstr);
+		} else {
+			$init_time = microtime(true);
+			$init_timeout = 5; // retry every 5s
+			while (true) {
+				$this->socket = @fsockopen($ip, $port, $errno, $errstr, $init_timeout);
+				if ($this->socket || (microtime(true) - $init_time >= $timeout))
+					break;
+			}
+		}
+		if (!$this->socket) {
+			$this->error = new IXR_Error(-32300, "transport error - could not open socket (error: $errno, $errstr)");
+			return false;
+		}
+		// handshake
+		$array_result = unpack('Vsize', fread($this->socket, 4));
+		$size = $array_result['size'];
+		if ($size > 64) {
+			$this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol header');
+			return false;
+		}
+		$handshake = fread($this->socket, $size);
+		if ($handshake == 'GBXRemote 1') {
+			$this->protocol = 1;
+		} else if ($handshake == 'GBXRemote 2') {
+			$this->protocol = 2;
+		} else {
+			$this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol version');
+			return false;
+		}
+		return true;
+	}
+
+	function Init($port) {
+		return $this->InitWithIp('localhost', $port);
+	}
+
+	function Terminate() {
+		if ($this->socket) {
+			fclose($this->socket);
+			$this->socket = false;
+		}
+	}
+
+	protected function sendRequest(IXR_Request $request) {
+		$xml = $request->getXml();
+
+		@stream_set_timeout($this->socket, 20);  // timeout 20s (to write the request)
+		// send request
+		$this->reqhandle++;
+		if ($this->protocol == 1) {
+			$bytes = pack('Va*', strlen($xml), $xml);
+		} else {
+			$bytes = pack('VVa*', strlen($xml), $this->reqhandle, $xml);
+		}
+
+		$bytes_to_write = strlen($bytes);
+		while ($bytes_to_write > 0) {
+			$r = @fwrite($this->socket, $bytes);
+			if ($r === false || $r == 0) {
+				// connection interrupted
+				return false; // or die?
+			}
+
+			$bytes_to_write -= $r;
+			if ($bytes_to_write == 0)
+				break;
+
+			$bytes = substr($bytes, $r);
+		}
+
+		return true;
+	}
+
+	protected function getResult() {
+		$contents = '';
+		$contents_length = 0;
+		do {
+			$size = 0;
+			$recvhandle = 0;
+			@stream_set_timeout($this->socket, 20);  // timeout 20s (to read the reply header)
+			// Get result
+			if ($this->protocol == 1) {
+				$contents = fread($this->socket, 4);
+				if (strlen($contents) == 0) {
+					$this->error = new IXR_Error(-32300, 'transport error - cannot read size');
+					return false;
+				}
+				$array_result = unpack('Vsize', $contents);
+				$size = $array_result['size'];
+				$recvhandle = $this->reqhandle;
+			} else {
+				$contents = fread($this->socket, 8);
+				if (strlen($contents) == 0) {
+					$this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle');
+					return false;
+				}
+				$array_result = unpack('Vsize/Vhandle', $contents);
+				$size = $array_result['size'];
+				$recvhandle = $array_result['handle'];
+				// -- amd64 support --
+				$bits = sprintf('%b', $recvhandle);
+				if (strlen($bits) == 64) {
+					$recvhandle = bindec(substr($bits, 32));
+				}
+			}
+
+			if ($recvhandle == 0 || $size == 0) {
+				$this->error = new IXR_Error(-32300, 'transport error - connection interrupted!');
+				return false;
+			}
+			if ($size > 4096*1024) {
+				$this->error = new IXR_Error(-32300, "transport error - response too large ($size)");
+				return false;
+			}
+
+			$contents = '';
+			$contents_length = 0;
+			@stream_set_timeout($this->socket, 0, 10000);  // timeout 10 ms (for successive reads until end)
+			while ($contents_length < $size) {
+				$contents .= fread($this->socket, $size-$contents_length);
+				$contents_length = strlen($contents);
+			}
+
+			if (($recvhandle & 0x80000000) == 0) {
+				// this is a callback, not our answer! handle= $recvhandle, xml-rpc= $contents
+				// just add it to the message list for the user to read
+				$new_cb_message = new IXR_Message($contents);
+				if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') {
+					array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params));
+				}
+			}
+		} while ((int)$recvhandle != (int)$this->reqhandle);
+
+		$this->message = new IXR_Message($contents);
+		if (!$this->message->parse()) {
+			// XML error
+			$this->error = new IXR_Error(-32700, 'parse error. not well formed');
+			return false;
+		}
+		// Is the message a fault?
+		if ($this->message->messageType == 'fault') {
+			$this->error = new IXR_Error($this->message->faultCode, $this->message->faultString);
+			return false;
+		}
+		// Message must be OK
+		return true;
+	}
+
+
+	function query() {
+		$args = func_get_args();
+		$method = array_shift($args);
+
+		if (!$this->socket || $this->protocol == 0) {
+			$this->error = new IXR_Error(-32300, 'transport error - client not initialized');
+			return false;
+		}
+
+		$request = new IXR_Request($method, $args);
+
+		// Check if request is larger than 512 Kbytes
+		if (($size = $request->getLength()) > 1024*1024-8) {
+			$this->error = new IXR_Error(-32300, "transport error - request too large ($size)");
+			return false;
+		}
+
+		// Send request
+		$ok = $this->sendRequest($request);
+		if (!$ok) {
+			$this->error = new IXR_Error(-32300, 'transport error - connection interrupted!');
+			return false;
+		}
+
+		// Get result
+		return $this->getResult();
+	}
+
+	// Non-blocking query method: doesn't read the response
+	function queryIgnoreResult() {
+		$args = func_get_args();
+		$method = array_shift($args);
+
+		if (!$this->socket || $this->protocol == 0) {
+			$this->error = new IXR_Error(-32300, 'transport error - client not initialized');
+			return false;
+		}
+
+		$request = new IXR_Request($method, $args);
+
+		// Check if the request is greater than 512 Kbytes to avoid errors
+		// If the method is system.multicall, make two calls (possibly recursively)
+		if (($size = $request->getLength()) > 1024*1024-8) {
+			if ($method = 'system.multicall' && isset($args[0])) {
+				$count = count($args[0]);
+				// If count is 1, query cannot be reduced
+				if ($count < 2) {
+					$this->error = new IXR_Error(-32300, "transport error - request too large ($size)");
+					return false;
+				}
+				$length = floor($count/2);
+				$args1 = array_slice($args[0], 0, $length);
+				$args2 = array_slice($args[0], $length, ($count-$length));
+
+				$res1 = $this->queryIgnoreResult('system.multicall', $args1);
+				$res2 = $this->queryIgnoreResult('system.multicall', $args2);
+				return ($res1 && $res2);
+			}
+			// If the method is not a multicall, just stop
+			else {
+				$this->error = new IXR_Error(-32300, "transport error - request too large ($size)");
+				return false;
+			}
+		}
+
+		// Send request
+		$ok = $this->sendRequest($request);
+		if (!$ok) {
+			$this->error = new IXR_Error(-32300, 'transport error - connection interrupted!');
+			return false;
+		}
+		return true;
+	}
+
+	function readCB($timeout = 2000) {  // timeout 2 ms
+		if (!$this->socket || $this->protocol == 0) {
+			$this->error = new IXR_Error(-32300, 'transport error - client not initialized');
+			return false;
+		}
+		if ($this->protocol == 1)
+			return false;
+
+		$something_received = count($this->cb_message)>0;
+		$contents = '';
+		$contents_length = 0;
+
+		@stream_set_timeout($this->socket, 0, 10000);  // timeout 10 ms (to read available data)
+		// (assignment in arguments is forbidden since php 5.1.1)
+		$read = array($this->socket);
+		$write = NULL;
+		$except = NULL;
+		$nb = @stream_select($read, $write, $except, 0, $timeout);
+		// workaround for stream_select bug with amd64
+		if ($nb !== false)
+			$nb = count($read);
+
+		while ($nb !== false && $nb > 0) {
+			$timeout = 0;  // we don't want to wait for the full time again, just flush the available data
+
+			$size = 0;
+			$recvhandle = 0;
+			// Get result
+			$contents = fread($this->socket, 8);
+			if (strlen($contents) == 0) {
+				$this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle');
+				return false;
+			}
+			$array_result = unpack('Vsize/Vhandle', $contents);
+			$size = $array_result['size'];
+			$recvhandle = $array_result['handle'];
+
+			if ($recvhandle == 0 || $size == 0) {
+				$this->error = new IXR_Error(-32300, 'transport error - connection interrupted!');
+				return false;
+			}
+			if ($size > 4096*1024) {
+				$this->error = new IXR_Error(-32300, "transport error - response too large ($size)");
+				return false;
+			}
+
+			$contents = '';
+			$contents_length = 0;
+			while ($contents_length < $size) {
+				$contents .= fread($this->socket, $size-$contents_length);
+				$contents_length = strlen($contents);
+			}
+
+			if (($recvhandle & 0x80000000) == 0) {
+				// this is a callback. handle= $recvhandle, xml-rpc= $contents
+				//echo 'CALLBACK('.$contents_length.')[ '.$contents.' ]' . LF;
+				$new_cb_message = new IXR_Message($contents);
+				if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') {
+					array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params));
+				}
+				$something_received = true;
+			}
+
+			// (assignment in arguments is forbidden since php 5.1.1)
+			$read = array($this->socket);
+			$write = NULL;
+			$except = NULL;
+			$nb = @stream_select($read, $write, $except, 0, $timeout);
+			// workaround for stream_select bug with amd64
+			if ($nb !== false)
+				$nb = count($read);
+		}
+		return $something_received;
+	}
+
+	function getResponse() {
+		// methodResponses can only have one param - return that
+		return $this->message->params[0];
+	}
+
+	function getCBResponses() {
+		// (look at the end of basic.php for an example)
+		$messages = $this->cb_message;
+		$this->cb_message = array();
+		return $messages;
+	}
+
+	function isError() {
+		return is_object($this->error);
+	}
+
+	function resetError() {
+		$this->error = false;
+	}
+
+	function getErrorCode() {
+		if ($this->isError())
+			return $this->error->code;
+		else
+			return 0;
+	}
+
+	function getErrorMessage() {
+		if ($this->isError())
+			return $this->error->message;
+		else
+			return '';
+	}
+}
+
+
+class IXR_ClientMulticall_Gbx extends IXR_Client_Gbx {
+	public $calls = array();
+
+	function addCall($methodName, $args = array() ) {
+		$this->calls[] = array('methodName' => $methodName, 'params' => $args);
+		
+		return (count($this->calls) - 1);
+	}
+
+	function multiquery($ignoreResult = false) {
+		// Prepare multicall, then call the parent::query() (or queryIgnoreResult) method
+		if ($ignoreResult) {
+			$result = parent::queryIgnoreResult('system.multicall', $this->calls);
+		} else {
+			$result = parent::query('system.multicall', $this->calls);
+		}
+		return $result;
+	}
+
+	function getMultiqueryResponse() {
+		$out = array();
+		
+		if (!empty($this->calls)) {
+			$result = $this->getResponse();
+			foreach ($this->calls as $i => $method) {
+				if (isset($result[$i]['faultCode'])) {
+					$out[$method['methodName']] = array();
+				}
+				else {
+					if (count($result[$i]) == 1 && isset($result[$i][0])) {
+						$out[$method['methodName']] = $result[$i][0];
+					}
+					else {
+						$out[$method['methodName']] = $result[$i];
+					}
+				}
+			}
+		}
+		
+		$this->calls = array();
+		return $out;
+	}
+}
+?>
diff --git a/resources/class/file.class.php b/resources/class/file.class.php
new file mode 100644
index 0000000..e7d3633
--- /dev/null
+++ b/resources/class/file.class.php
@@ -0,0 +1,227 @@
+<?php
+/**
+* Class File
+*
+* Méthodes de traitement de fichier
+*/
+abstract class File {
+	
+	/**
+	* Récupère l'extension d'un fichier
+	*
+	* @param  string $filename -> Le chemin ou nom du fichier
+	* @return string "php"
+	*/
+	public static function getExtension($filename){
+		$out = null;
+		
+		$pathinfo = pathinfo($filename);
+		if( isset($pathinfo['extension']) ){
+			$out = strtolower($pathinfo['extension']);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère une double extension
+	*
+	* @param string $filename -> Le chemin ou nom du fichier
+	* @return string "class.php"
+	*/
+	public static function getDoubleExtension($filename){
+		$out = null;
+		$filenameEx = explode('.', $filename);
+		$countFilenameEx = count($filenameEx);
+		
+		if( $countFilenameEx > 2 ){
+			$out = $filenameEx[$countFilenameEx - 2];
+			$out .= '.'.$filenameEx[$countFilenameEx - 1];
+		}
+		
+		return strtolower($out);
+	}
+	
+	
+	/**
+	* Créer ou ajoute des données à un fichier
+	*
+	* @param  string $filename -> Le chemin ou nom du fichier
+	* @param  string $data     -> Données à écrire
+	* @return true si réussi, sinon erreur string
+	*/
+	public static function save($filename, $data = null, $appendData = true){
+		$out = null;
+		
+		if( file_exists($filename) ){
+			$append = ($appendData) ? FILE_APPEND : 0;
+			
+			if( file_put_contents($filename, $data, $append) ){
+				$out = true;
+			}
+			else{
+				$out = 'No such file or file is not writable';
+			}
+		}
+		else{
+			if( $handle = fopen($filename, 'w') ){
+				$out = true;
+				fclose($handle);
+			}
+			else{
+				$out = 'No such file or file is not writable';
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Enregistre les données dans un fichier au pointeur
+	*
+	* @param  string $filename -> Le chemin ou nom du fichier
+	* @param  string $data     -> Données à écrire
+	* @param  string $seek     -> Le pointeur pour l'endroit à écrire
+	*/
+	public static function saveAtSeek($filename, $data, $seek = 0){
+		$out = null;
+		
+		if( file_exists($filename) && is_writable($filename) ){
+			$handle = fopen($filename, 'r+');
+			fseek($handle, $seek, SEEK_CUR);
+			if( fwrite($handle, $data) ){
+				$out = true;
+			}
+			fclose($handle);
+		}
+		else{
+			$out = 'No such file or file is not writable';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le pointeur à partir d'une chaine de caractère dans un fichier
+	*
+	* @param string $filename -> Le chemin du fichier
+	* @param string $string   -> La chaine à rechercher
+	* @param bool   $lastChar -> Retourner le pointer à partir du dernier caractère de la chaine recherchée
+	* @return int or text error
+	*/
+	public static function getSeekFromString($filename, $string, $lastChar = false){
+		$out = null;
+		
+		if( file_exists($filename) && is_writable($filename) ){
+			$handle = fopen($filename, 'r');
+			$content = fread($handle, filesize($filename) );
+			$out = strpos($content, $string);
+			if($lastChar){
+				$out += strlen($string);
+			}
+			fclose($handle);
+		}
+		else{
+			$out = 'No such file or file is not writable';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Renomme un fichier
+	*
+	* @param string $filename    -> Chemin du fichier à renommer
+	* @param string $newfilename -> Chemin du nouveau fichier renommé
+	*/
+	public static function rename($filename, $newfilename){
+		$out = null;
+		
+		if( file_exists($filename) ){
+			if( @rename($filename, $newfilename) ){
+				$out = true;
+			}
+			else{
+				$out = 'Unable to rename file';
+			}
+		}
+		else{
+			$out = 'No such file';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Supprime un fichier
+	*
+	* @param string $filename -> Chemin du fichier à supprimer
+	*/
+	public static function delete($filename){
+		$out = null;
+		
+		if( file_exists($filename) ){
+			if( @unlink($filename) ){
+				$out = true;
+			}
+			else{
+				$out = 'Unable to delete file';
+			}
+		}
+		else{
+			$out = 'No such file';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Envoi les headers pour télécharger un fichier
+	*
+	* @param string $pathToFile -> Le chemin du fichier à télécharger
+	* @param int    $fileSize   -> Taille du fichier, si null = automatique
+	*/
+	public static function sendDownloadHeaders($pathToFile, $fileSize = null){
+		$path_parts = pathinfo($pathToFile);
+		$filename = htmlspecialchars( trim($path_parts['basename']), ENT_QUOTES, 'UTF-8');
+		$path = $path_parts['dirname'].'/';
+		
+		header('Content-Disposition: attachment; filename="'.$filename);
+		header('Content-Type: application/force-download');
+		header('Content-Transfer-Encoding: binary');
+		if($fileSize != null){
+			header('Content-Length: '.$fileSize);
+		}
+		else{
+			header('Content-Length: '.filesize($pathToFile));
+		}
+		header('Pragma: no-cache');
+		if( preg_match('/MSIE/i', $_SERVER['HTTP_USER_AGENT']) ){
+			header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+		}
+		else{
+			header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
+		}
+		header('Expires: 0');
+	}
+	
+	
+	/**
+	* Permet de télécharger un fichier
+	*
+	* @param string $pathToFile -> Le chemin du fichier à télécharger
+	* @param int    $fileSize   -> Taille du fichier, si null = automatique
+	*/
+	public static function download($pathToFile, $fileSize = null){
+		self::sendDownloadHeaders($pathToFile, $fileSize);
+		flush();
+		readfile($pathToFile);
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/class/folder.class.php b/resources/class/folder.class.php
new file mode 100644
index 0000000..94b5361
--- /dev/null
+++ b/resources/class/folder.class.php
@@ -0,0 +1,376 @@
+<?php
+/**
+* Class Folder
+*
+* Méthodes de traitement de dossier
+*/
+abstract class Folder {
+	
+	/**
+	* Liste les dossiers et fichiers d'un répertoire
+	*
+	* @param  string $path                 -> Le chemin du répertoire à lister
+	* @param  mixed  $hidden_folders       -> Les dossiers à masquer : array('dossier1', 'dossier2); ou 'all' pour ne pas charger les dossiers
+	* @param  mixed  $hidden_files         -> Les fichiers ou extension à masquer : array('Thumbs.db', 'index.php', 'exe');  ou 'all' pour ne pas charger les fichiers
+	* @param  int    $recent_status_period -> Période pour afficher le statut "récent"
+	* @return array ['folders'], ['files']
+	*/
+	public static function read($path = '.', $hiddenFolders = array(), $hiddenFiles = array(), $recentStatusPeriod = 86400){
+		$out = array();
+		$midnight = time() - (date('H') * 3600) - (date('i') * 60);
+		if( substr($path, -1, 1) != '/'){ $path .= '/'; }
+		
+		if( !class_exists('File') && !class_exists('Str') ){
+			$out = 'Class "File" or "Str" not exists';
+		}
+		else{
+			if( !is_dir($path) ){
+				$out = 'Not directory';
+			}
+			else{
+				$dir = scandir($path);
+				foreach($dir as $entry){
+					$entry = utf8_encode($entry);
+					if($entry != '.' && $entry != '..'){
+						$pathToEntry = $path.'/'.$entry;
+						
+						if($hiddenFolders !== 'all' && is_dir($pathToEntry) ){
+							if( !in_array($entry, $hiddenFolders) ){
+								$out['folders'][$entry]['size'] = Str::formatSize(self::getSize($pathToEntry));
+								$out['folders'][$entry]['nb_file'] = self::countFiles($pathToEntry, $hiddenFiles);
+							}
+						}
+						else if($hiddenFiles !== 'all' && !in_array($entry, $hiddenFiles) ){
+							$extension = File::getExtension($entry);
+							
+							if( !in_array($extension, $hiddenFiles) ){
+								$out['files'][$entry] = @array_slice(@stat($pathToEntry), 20, 3);
+								$out['files'][$entry]['size'] = Str::formatSize($out['files'][$entry]['size']);
+								$out['files'][$entry]['filename'] = $entry;
+								$out['files'][$entry]['extension'] = $extension;
+								$out['files'][$entry]['recent'] = (isset($out['files'][$entry]['mtime']) && ($out['files'][$entry]['mtime'] > ($midnight - $recentStatusPeriod))) ? 1 : 0;
+							}
+						}
+					}
+				}
+				
+				if( empty($out['folders']) ){
+					$out['folders'] = null;
+				}
+				if( empty($out['files']) ){
+					$out['files'] = null;
+				}
+			}
+		}
+		return $out;
+	}
+	
+	
+	/**
+	* Créer un dossier
+	*
+	* @param string $dirname -> Chemin du dossier à créer
+	* @return true si réussi sinon message d'erreur
+	*/
+	public static function create($dirname){
+		$out = null;
+		
+		if( !file_exists($dirname) ){
+			umask(0000);
+			if( mkdir($dirname, 0777, true) ){
+				$out = true;
+			}
+			else{
+				$out = 'Create folder failed';
+			}
+		}
+		else{
+			$out = 'Folder already exists';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Renomme un dossier
+	*
+	* @param string $oldname -> Chemin de l'ancien dossier
+	* @param string $newname -> Chemin du nouveau dossier
+	* @return true si réussi sinon message d'erreur
+	*/
+	public static function rename($oldname, $newname){
+		$out = null;
+		
+		if( file_exists($oldname) ){
+			if( is_dir($oldname) ){
+				if( rename($oldname, $newname) ){
+					$out = true;
+				}
+				else{
+					$out = 'Rename '.$oldname.' failed';
+				}
+			}
+			else{
+				$out = 'Not directory';
+			}
+		}
+		else{
+			$out = 'Folder no exists';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Supprime un dossier avec son contenu (dossiers + fichiers)
+	*
+	* @param string $dirname -> Chemin du dossier à supprimer
+	* @return true si réussi sinon message d'erreur
+	*/
+	public static function delete($dirname){
+		$out = null;
+		if( substr($dirname, -1, 1) != '/'){ $dirname .= '/'; }
+		
+		if( class_exists('File') ){
+			if( file_exists($dirname) ){
+				$dir = scandir($dirname);
+				foreach($dir as $file){
+					if($file != '.' && $file != '..'){
+						$pathToFile = $dirname.$file;
+						
+						if( is_dir($pathToFile) ){
+							self::delete($pathToFile);
+						}
+						else{
+							File::delete($pathToFile);
+						}
+					}
+				}
+				
+				if( @rmdir($dirname) !== true ){
+					$out = 'Unable to delete '.$dirname;
+				}
+				else{
+					$out = true;
+				}
+			}
+			else{
+				$out = 'Dir not exists';
+			}
+		}
+		else{
+			$out = 'Class "File" not exists';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Compte le nombre de fichier présent dans un dossier
+	*
+	* @param string $path        -> Le chemin du dossier
+	* @param array  $hiddenFiles -> Les fichiers ou extensions à ne pas prendre en compte
+	* @return int
+	*/
+	public static function countFiles($path, $hiddenFiles = array() ){
+		$out = 0;
+		if( substr($path, -1, 1) != '/'){ $path .= '/'; }
+		
+		if( class_exists('File') ){
+			if( file_exists($path) ){
+				$dir = scandir($path);
+				foreach($dir as $file){
+					$pathToFile = $path.$file;
+					
+					if( is_dir($pathToFile) && $file != '.' && $file != '..' ){
+						if( is_numeric( $result = self::countFiles($pathToFile, $hiddenFiles) ) ){
+							$out += $result;
+						}
+						else{
+							$out = $result;
+							break;
+						}
+					}
+					else{
+						if($file != '.' && $file != '..'){
+							if( !in_array($file, $hiddenFiles) ){
+								if( !in_array(File::getExtension($file), $hiddenFiles) ){
+									$out++;
+								}
+							}
+						}
+					}
+				}
+			}
+			else{
+				$out = 'Dir not exists';
+			}
+		}
+		else{
+			$out = 'Class "File" not exists';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Taille d'un dossier
+	*
+	* @param string $path -> Le chemin du dossier
+	* @return int
+	*/
+	public static function getSize($path){
+		$out = 0;
+		if( substr($path, -1, 1) != '/'){ $path .= '/'; }
+		
+		if( file_exists($path) ){
+			$dir = scandir($path);
+			foreach($dir as $file){
+				if( $file != '..' && $file != '.' ){
+					$pathToFile = $path.'/'.$file;
+					if( is_dir($pathToFile) ){
+						$out += self::getSize($pathToFile);
+					}
+					else{
+						$out += @filesize($pathToFile);
+					}
+				}
+			}
+		}
+		else{
+			$out = 'Dir not exists';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne l'arborescence complete du chemin avec un décalage du dossier
+	*
+	* @param string $path          -> Le chemin du dossier
+	* @param array  $hiddenFiles   -> Les fichiers ou extensions à ne pas prendre en compte
+	* @param int    $hidePathLevel -> Nombre de niveau du chemin à masquer pour l'affichage
+	* @return array
+	*/
+	public static function getArborescence($path = '.', $hiddenFolders = array(), $hidePathLevel = 0){
+		$out = array();
+		$struct = self::read($path, $hiddenFolders);
+		
+		// Décalage selon la profondeur de l'arborescence
+		$countSlash = substr_count($path, '/') - $hidePathLevel;
+		$pathLevel = null;
+		for($i = 0; $i < $countSlash; $i++){
+			$pathLevel .= '&#9474;&nbsp;';
+		}
+		$pathLevel .= '&#9500;&nbsp;';
+		
+		if( isset($struct['folders']) && count($struct['folders']) > 0 ){
+			foreach($struct['folders'] as $dir => $values){
+				$out[] = array(
+					'path' => $path.$dir.'/',
+					'name' => $dir,
+					'level' => $pathLevel
+				);
+				$out = array_merge($out, self::getArborescence($path.$dir.'/', $hiddenFolders, $hidePathLevel) );
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Vérifie les droits par rapport au chmod
+	*/
+	public static function checkRights($path, $minChmod){
+		$out = array();
+		$chars = str_split($minChmod);
+		
+		$i = 0;
+		foreach($chars as $char){
+			if($i == 0){ $group = 'owner'; }
+			else if($i == 1){ $group = 'group'; }
+			else{ $group = 'other'; }
+			$out[$group]['request'] = $char;
+			
+			switch($char){
+				case 7:
+					$out[$group]['result']['r'] = is_readable($path);
+					$out[$group]['result']['w'] = is_writable($path);
+					$out[$group]['result']['x'] = is_executable($path);
+					break;
+				case 6:
+					$out[$group]['result']['r'] = is_readable($path);
+					$out[$group]['result']['w'] = is_writable($path);
+					break;
+				case 5:
+					$out[$group]['result']['r'] = is_readable($path);
+					$out[$group]['result']['x'] = is_executable($path);
+					break;
+				case 4:
+					$out[$group]['result']['r'] = is_readable($path);
+					break;
+				case 3:
+					$out[$group]['result']['w'] = is_writable($path);
+					$out[$group]['result']['x'] = is_executable($path);
+					break;
+				case 2:
+					$out[$group]['result']['w'] = is_writable($path);
+					break;
+				case 1:
+					$out[$group]['result']['x'] = is_executable($path);
+					break;
+				default:
+					$out[$group]['result']['r'] = false;
+					$out[$group]['result']['w'] = false;
+					$out[$group]['result']['x'] = false;
+			}
+			$i++;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Converti un chmod int (777) en string (rwxrwxrwx)
+	*/
+	public static function chmodToStr($chmod){
+		$out = null;
+		$chars = str_split($chmod);
+		
+		foreach($chars as $char){
+			switch($char){
+				case 7:
+					$out .= 'rwx';
+					break;
+				case 6:
+					$out .= 'rw-';
+					break;
+				case 5:
+					$out .= 'r-x';
+					break;
+				case 4:
+					$out .= 'r--';
+					break;
+				case 3:
+					$out .= '-wx';
+					break;
+				case 2:
+					$out .= '-w-';
+					break;
+				case 1:
+					$out .= '--x';
+					break;
+			}
+		}
+		
+		return $out;
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/class/gbxdatafetcher.inc.php b/resources/class/gbxdatafetcher.inc.php
new file mode 100644
index 0000000..5375b4c
--- /dev/null
+++ b/resources/class/gbxdatafetcher.inc.php
@@ -0,0 +1,1384 @@
+<?php
+/* vim: set noexpandtab tabstop=2 softtabstop=2 shiftwidth=2: */
+
+/**
+ * GBXDataFetcher - Fetch GBX challenge/map/replay/pack data for TrackMania (TM)
+ *                  & ManiaPlanet (MP) files
+ * Created by Xymph <tm@gamers.org>
+ * Thanks to Electron for additional input & prototyping
+ * Based on information at http://en.tm-wiki.org/wiki/GBX,
+ * http://www.tm-forum.com/viewtopic.php?p=192817#p192817
+ * and http://en.tm-wiki.org/wiki/PAK#Header_versions_8.2B
+ *
+ * v2.3: Add UTF-8 decoding of parsed XML chunk's elements; strip UTF-8 BOM
+ *       from various string fields
+ * v2.2: Add class GBXPackFetcher; limit loadGBXdata() to first 256KB
+ * v2.1: Add exception codes; add $thumbLen to GBXChallMapFetcher
+ * v2.0: Complete rewrite
+ */
+
+/**
+ * @class GBXBaseFetcher
+ * @brief The base GBX class with all common functionality
+ */
+class GBXBaseFetcher
+{
+	public $parseXml, $xml, $xmlParsed;
+
+	public $authorVer, $authorLogin, $authorNick, $authorZone, $authorEInfo;
+
+	private $_gbxdata, $_gbxlen, $_gbxptr, $_debug, $_error, $_endianess,
+	        $_lookbacks, $_parsestack;
+
+	// supported class ID's
+	const GBX_CHALLENGE_TMF = 0x03043000;
+	const GBX_AUTOSAVE_TMF  = 0x03093000;
+	const GBX_CHALLENGE_TM  = 0x24003000;
+	const GBX_AUTOSAVE_TM   = 0x2403F000;
+	const GBX_REPLAY_TM     = 0x2407E000;
+
+	const MACHINE_ENDIAN_ORDER = 0;
+	const LITTLE_ENDIAN_ORDER  = 1;
+	const BIG_ENDIAN_ORDER     = 2;
+
+	const LOAD_LIMIT = 256;  // KBs to read in loadGBXdata()
+
+	// initialise new instance
+	public function __construct()
+	{
+		$this->parseXml = false;
+		$this->xml = '';
+		$this->xmlParsed = array();
+		$this->_debug = false;
+		$this->_error = '';
+
+		list($endiantest) = array_values(unpack('L1L', pack('V', 1)));
+		if ($endiantest != 1)
+			$this->_endianess = self::BIG_ENDIAN_ORDER;
+		else
+			$this->_endianess = self::LITTLE_ENDIAN_ORDER;
+
+		$this->clearGBXdata();
+		$this->clearLookbacks();
+		$this->_parsestack = array();
+
+		$this->authorVer   = 0;
+		$this->authorLogin = '';
+		$this->authorNick  = '';
+		$this->authorZone  = '';
+		$this->authorEInfo = '';
+	}
+
+	// enable debug logging
+	protected function enableDebug()
+	{
+		$this->_debug = true;
+	}
+
+	// disable debug logging
+	protected function disableDebug()
+	{
+		$this->_debug = false;
+	}
+
+	// print message to stderr if debugging
+	protected function debugLog($msg)
+	{
+		if ($this->_debug)
+			fwrite(STDERR, $msg."\n");
+	}
+
+	// set error message prefix
+	protected function setError($prefix)
+	{
+		$this->_error = (string)$prefix;
+	}
+
+	// exit with error exception
+	protected function errorOut($msg, $code = 0)
+	{
+		$this->clearGBXdata();
+		throw new Exception($this->_error . $msg, $code);
+	}
+
+	// read in raw GBX data
+	protected function loadGBXdata($filename)
+	{
+		$gbxdata = @file_get_contents($filename, false, null, 0, self::LOAD_LIMIT * 1024);
+		if ($gbxdata !== false)
+			$this->storeGBXdata($gbxdata);
+		else
+			$this->errorOut('Unable to read GBX data from ' . $filename, 1);
+	}
+
+	// store raw GBX data
+	protected function storeGBXdata($gbxdata)
+	{
+		$this->_gbxdata = & $gbxdata;
+		$this->_gbxlen = strlen($gbxdata);
+		$this->_gbxptr = 0;
+	}
+
+	// clear GBX data (to avoid print_r problems & reduce memory usage)
+	protected function clearGBXdata()
+	{
+		$this->storeGBXdata('');
+	}
+
+	// get GBX pointer
+	protected function getGBXptr()
+	{
+		return $this->_gbxptr;
+	}
+
+	// set GBX pointer
+	protected function setGBXptr($ptr)
+	{
+		$this->_gbxptr = (int)$ptr;
+	}
+
+	// move GBX pointer
+	protected function moveGBXptr($len)
+	{
+		$this->_gbxptr += (int)$len;
+	}
+
+	// read $len bytes from GBX data
+	protected function readData($len)
+	{
+		if ($this->_gbxptr + $len > $this->_gbxlen)
+			$this->errorOut(sprintf('Insufficient data for %d bytes at pos 0x%04X',
+			                        $len, $this->_gbxptr), 2);
+		$data = '';
+		while ($len-- > 0)
+			$data .= $this->_gbxdata[$this->_gbxptr++];
+		return $data;
+	}
+
+	// read signed byte from GBX data
+	protected function readInt8()
+	{
+		$data = $this->readData(1);
+		list(, $int8) = unpack('c*', $data);
+		return $int8;
+	}
+
+	// read signed short from GBX data
+	protected function readInt16()
+	{
+		$data = $this->readData(2);
+		if ($this->_endianess == self::BIG_ENDIAN_ORDER)
+			$data = strrev($data);
+		list(, $int16) = unpack('s*', $data);
+		return $int16;
+	}
+
+	// read signed long from GBX data
+	protected function readInt32()
+	{
+		$data = $this->readData(4);
+		if ($this->_endianess == self::BIG_ENDIAN_ORDER)
+			$data = strrev($data);
+		list(, $int32) = unpack('l*', $data);
+		return $int32;
+	}
+
+	// read string from GBX data
+	protected function readString()
+	{
+		$gbxptr = $this->getGBXptr();
+		$len = $this->readInt32();
+		$len &= 0x7FFFFFFF;
+		if ($len <= 0 || $len >= 0x12000) {  // for large XML & Data blocks
+			if ($len != 0)
+				$this->errorOut(sprintf('Invalid string length %d (0x%04X) at pos 0x%04X',
+				                        $len, $len, $gbxptr), 3);
+		}
+		$data = $this->readData($len);
+		return $data;
+	}
+
+	// strip UTF-8 BOM from string
+	protected function stripBOM($str)
+	{
+		return str_replace("\xEF\xBB\xBF", '', $str);
+	}
+
+	// clear lookback strings
+	protected function clearLookbacks()
+	{
+		$this->_lookbacks = array();
+	}
+
+	// read lookback string from GBX data
+	protected function readLookbackString()
+	{
+		if (empty($this->_lookbacks)) {
+			$version = $this->readInt32();
+			if ($version != 3)
+				$this->errorOut('Unknown lookback strings version: ' . $version, 4);
+		}
+
+		// check index
+		$index = $this->readInt32();
+		if ($index == -1) {
+			// unassigned (empty) string
+			$str = '';
+		} elseif (($index & 0xC0000000) == 0) {
+			// use external reference string
+			switch ($index) {
+				case 0xC:
+					$str = 'Canyon';
+					break;
+				case 0xCA:
+					$str = 'Storm';
+					break;
+				default:
+					$str = 'UNKNOWN';
+			}
+		} elseif (($index & 0x3FFFFFFF) == 0) {
+			// read string & add to lookbacks
+			$str = $this->readString();
+			$this->_lookbacks[] = $str;
+		} else {
+			// use string from lookbacks
+			$str = $this->_lookbacks[($index & 0x3FFFFFFF) - 1];
+		}
+
+		return $str;
+	}
+
+	// XML parser functions
+	private function startTag($parser, $name, $attribs)
+	{
+		foreach ($attribs as $key => &$val)
+			$val = utf8_decode($val);
+		//echo 'startTag: ' . $name . "\n"; print_r($attribs);
+		array_push($this->_parsestack, $name);
+		if ($name == 'DEP') {
+			$this->xmlParsed['DEPS'][] = $attribs;
+		} elseif (count($this->_parsestack) <= 2) {
+			// HEADER, IDENT, DESC, TIMES, CHALLENGE/MAP, DEPS, CHECKPOINTS
+			$this->xmlParsed[$name] = $attribs;
+		}
+	}
+
+	private function charData($parser, $data)
+	{
+		//echo 'charData: ' . $data . "\n";
+		if (count($this->_parsestack) == 3)
+			$this->xmlParsed[$this->_parsestack[1]][$this->_parsestack[2]] = $data;
+		elseif (count($this->_parsestack) > 3)
+			$this->debugLog('XML chunk nested too deeply: ', print_r($this->_parsestack, true));
+	}
+
+	private function endTag($parser, $name)
+	{
+		//echo 'endTag: ' . $name . "\n";
+		array_pop($this->_parsestack);
+	}
+
+	protected function parseXMLstring()
+	{
+		// define a dedicated parser to handle the attributes
+		$xml_parser = xml_parser_create();
+		xml_set_object($xml_parser, $this);
+		xml_set_element_handler($xml_parser, 'startTag', 'endTag');
+		xml_set_character_data_handler($xml_parser, 'charData');
+
+		// escape '&' characters unless already a known entity
+		$xml = preg_replace('/&(?!(?:amp|quot|apos|lt|gt);)/', '&amp;', $this->xml);
+
+		if (!xml_parse($xml_parser, utf8_encode($xml), true))
+			$this->errorOut(sprintf('XML chunk parse error: %s at line %d',
+			                        xml_error_string(xml_get_error_code($xml_parser)),
+			                        xml_get_current_line_number($xml_parser)), 12);
+
+		xml_parser_free($xml_parser);
+	}
+
+	/**
+	 * Check GBX header, main class ID & header block
+	 * @param Array $classes
+	 *              The main class IDs accepted for this GBX
+	 * @return Size of GBX header block
+	*/
+	protected function checkHeader(array $classes)
+	{
+		// check magic header
+		$data = $this->readData(3);
+		$version = $this->readInt16();
+		if ($data != 'GBX' || $version != 6)
+			$this->errorOut('No magic GBX header', 5);
+
+		// check header block (un)compression
+		$data = $this->readData(4);
+		if ($data[1] != 'U')
+			$this->errorOut('Compressed GBX header block not supported', 6);
+
+		// check main class ID
+		$mainClass = $this->readInt32();
+		if (!in_array($mainClass, $classes))
+			$this->errorOut(sprintf('Main class ID %08X not supported', $mainClass), 7);
+		$this->debugLog(sprintf('GBX main class ID: %08X', $mainClass));
+
+		// get header size
+		$headerSize = $this->readInt32();
+		if ($headerSize == 0)
+			$this->errorOut('No GBX header block', 8);
+
+		$this->debugLog(sprintf('GBX header block size: %d (%.1f KB)',
+		                        $headerSize, $headerSize / 1024));
+		return $headerSize;
+	}  // checkHeader
+
+	/**
+	 * Get list of chunks from GBX header block
+	 * @param Int $headerSize
+	 *        Size of header block (chunks list & chunks data)
+	 * @param array $chunks
+	 *        List of chunk IDs & names
+	 * @return List of chunk offsets & sizes
+	 */
+	protected function getChunksList($headerSize, array $chunks)
+	{
+		// get number of chunks
+		$numChunks = $this->readInt32();
+		if ($numChunks == 0)
+			$this->errorOut('No GBX header chunks', 9);
+
+		$this->debugLog('GBX number of header chunks: ' . $numChunks);
+		$chunkStart = $this->getGBXptr();
+		$this->debugLog(sprintf('GBX start of chunk list: 0x%04X', $chunkStart));
+		$chunkOffset = $chunkStart + $numChunks * 8;
+
+		// get list of all chunks
+		$chunksList = array();
+		for ($i = 0; $i < $numChunks; $i++)
+		{
+			$chunkId = $this->readInt32();
+			$chunkSize = $this->readInt32();
+
+			$chunkId &= 0x00000FFF;
+			$chunkSize &= 0x7FFFFFFF;
+
+			if (array_key_exists($chunkId, $chunks)) {
+				$name = $chunks[$chunkId];
+				$chunksList[$name] = array(
+					'off' => $chunkOffset,
+					'size' => $chunkSize
+				);
+			} else {
+				$name = 'UNKNOWN';
+			}
+			$this->debugLog(sprintf('GBX chunk %2d  %-8s  Id  0x%03X  Offset  0x%06X  Size %6d',
+			                        $i, $name, $chunkId, $chunkOffset, $chunkSize));
+			$chunkOffset += $chunkSize;
+		}
+
+		//$this->debugLog(print_r($chunksList, true));
+		$totalSize = $chunkOffset - $chunkStart + 4;  // numChunks
+		if ($headerSize != $totalSize)
+			$this->errorOut(sprintf('Chunk list size mismatch: %d <> %d',
+			                        $headerSize, $totalSize), 10);
+
+		return $chunksList;
+	}  // getChunksList
+
+	/**
+	 * Initialize for a new chunk
+	 * @param int $offset
+	 */
+	protected function initChunk($offset)
+	{
+		$this->setGBXptr($offset);
+		$this->clearLookbacks();
+	}
+
+	/**
+	 * Get XML chunk from GBX header block & optionally parse it
+	 * @param array $chunksList
+	 *        List of chunk offsets & sizes
+	 */
+	protected function getXMLChunk(array $chunksList)
+	{
+		if (!isset($chunksList['XML'])) return;
+
+		$this->initChunk($chunksList['XML']['off']);
+		$this->xml = $this->readString();
+
+		if ($chunksList['XML']['size'] != strlen($this->xml) + 4)
+			$this->errorOut(sprintf('XML chunk size mismatch: %d <> %d',
+			                        $chunksList['XML']['size'], strlen($this->xml) + 4), 11);
+
+		if ($this->parseXml && $this->xml != '')
+			$this->parseXMLstring();
+	}  // getXMLChunk
+
+	/**
+	 * Get Author fields from GBX header block
+	 */
+	protected function getAuthorFields()
+	{
+		$this->authorVer   = $this->readInt32();
+		$this->authorLogin = $this->readString();
+		$this->authorNick  = $this->stripBOM($this->readString());
+		$this->authorZone  = $this->stripBOM($this->readString());
+		$this->authorEInfo = $this->readString();
+	}  // getAuthorFields
+
+	/**
+	 * Get Author chunk from GBX header block
+	 * @param array $chunksList
+	 *        List of chunk offsets & sizes
+	 */
+	protected function getAuthorChunk(array $chunksList)
+	{
+		if (!isset($chunksList['Author'])) return;
+
+		$this->initChunk($chunksList['Author']['off']);
+		$version = $this->readInt32();
+		$this->debugLog('GBX Author chunk version: ' . $version);
+
+		$this->getAuthorFields();
+	}  // getAuthorChunk
+
+}  // class GBXBaseFetcher
+
+
+/**
+ * @class GBXChallMapFetcher
+ * @brief The class that fetches all GBX challenge/map info
+ */
+class GBXChallMapFetcher extends GBXBaseFetcher
+{
+	public $tnImage;
+
+	public $headerVersn, $bronzeTime, $silverTime, $goldTime, $authorTime,
+	       $cost, $multiLap, $type, $typeName, $authorScore, $simpleEdit,
+	       $nbChecks, $nbLaps;
+	public $uid, $envir, $author, $name, $kind, $kindName, $password,
+	       $mood, $envirBg, $authorBg, $mapType, $mapStyle, $lightmap, $titleUid;
+	public $xmlVer, $exeVer, $exeBld, $validated, $songFile, $songUrl,
+	       $modName, $modFile, $modUrl;
+	public $thumbLen, $thumbnail, $comment;
+
+	const IMAGE_FLIP_HORIZONTAL = 1;
+	const IMAGE_FLIP_VERTICAL   = 2;
+	const IMAGE_FLIP_BOTH       = 3;
+
+	/**
+	 * Mirror (flip) an image across horizontal, vertical or both axis
+	 * Source: http://www.php.net/manual/en/function.imagecopy.php#85992
+	 * @param String $imgsrc
+	 *        Source image data
+	 * @param Int $dir
+	 *        Flip direction from the constants above
+	 * @return Flipped image data if successful, otherwise source image data
+	 */
+	private function imageFlip($imgsrc, $dir)
+	{
+		$width      = imagesx($imgsrc);
+		$height     = imagesy($imgsrc);
+		$src_x      = 0;
+		$src_y      = 0;
+		$src_width  = $width;
+		$src_height = $height;
+
+		switch ((int)$dir) {
+			case self::IMAGE_FLIP_HORIZONTAL:
+				$src_y      =  $height;
+				$src_height = -$height;
+				break;
+			case self::IMAGE_FLIP_VERTICAL:
+				$src_x      =  $width;
+				$src_width  = -$width;
+				break;
+			case self::IMAGE_FLIP_BOTH:
+				$src_x      =  $width;
+				$src_y      =  $height;
+				$src_width  = -$width;
+				$src_height = -$height;
+				break;
+			default:
+				return $imgsrc;
+		}
+
+		$imgdest = imagecreatetruecolor($width, $height);
+		if (imagecopyresampled($imgdest, $imgsrc, 0, 0, $src_x, $src_y,
+		                       $width, $height, $src_width, $src_height)) {
+			return $imgdest;
+		}
+		return $imgsrc;
+	}  // imageFlip
+
+	/**
+	 * Instantiate GBX challenge/map fetcher
+	 *
+	 * @param Boolean $parsexml
+	 *        If true, the fetcher also parses the XML block
+	 * @param Boolean $tnimage
+	 *        If true, the fetcher also extracts the thumbnail image;
+	 *        if GD/JPEG libraries are present, image will be flipped upright,
+	 *        otherwise it will be in the original upside-down format
+	 *        Warning: this is binary data in JPEG format, 256x256 pixels for
+	 *        TMU/TMF or 512x512 pixels for MP
+	 * @param Boolean $debug
+	 *        If true, the fetcher prints debug logging to stderr
+	 * @return GBXChallMapFetcher
+	 *        If GBX data couldn't be extracted, an Exception is thrown with
+	 *        the error message & code
+	 */
+	public function __construct($parsexml = false, $tnimage = false, $debug = false)
+	{
+		parent::__construct();
+
+		$this->headerVersn = 0;
+		$this->bronzeTime  = 0;
+		$this->silverTime  = 0;
+		$this->goldTime    = 0;
+		$this->authorTime  = 0;
+
+		$this->cost        = 0;
+		$this->multiLap    = false;
+		$this->type        = 0;
+		$this->typeName    = '';
+
+		$this->authorScore = 0;
+		$this->simpleEdit  = false;
+		$this->nbChecks    = 0;
+		$this->nbLaps      = 0;
+
+		$this->uid       = '';
+		$this->envir     = '';
+		$this->author    = '';
+		$this->name      = '';
+		$this->kind      = 0;
+		$this->kindName  = '';
+
+		$this->password  = '';
+		$this->mood      = '';
+		$this->envirBg   = '';
+		$this->authorBg  = '';
+
+		$this->mapType   = '';
+		$this->mapStyle  = '';
+		$this->lightmap  = 0;
+		$this->titleUid  = '';
+
+		$this->xmlVer    = '';
+		$this->exeVer    = '';
+		$this->exeBld    = '';
+		$this->validated = false;
+		$this->songFile  = '';
+		$this->songUrl   = '';
+		$this->modName   = '';
+		$this->modFile   = '';
+		$this->modUrl    = '';
+
+		$this->thumbLen  = 0;
+		$this->thumbnail = '';
+		$this->comment   = '';
+
+		$this->parseXml = (bool)$parsexml;
+		$this->tnImage  = (bool)$tnimage;
+		if ((bool)$debug)
+			$this->enableDebug();
+
+		$this->setError('GBX map error: ');
+	}  // __construct
+
+	/**
+	 * Process GBX challenge/map file
+	 *
+	 * @param String $filename
+	 *        The challenge filename
+	 */
+	public function processFile($filename)
+	{
+		$this->loadGBXdata((string)$filename);
+
+		$this->processGBX();
+	}  // processFile
+
+	/**
+	 * Process GBX challenge/map data
+	 *
+	 * @param String $gbxdata
+	 *        The challenge/map data
+	 */
+	public function processData($gbxdata)
+	{
+		$this->storeGBXdata((string)$gbxdata);
+
+		$this->processGBX();
+	}  // processData
+
+	// process GBX data
+	private function processGBX()
+	{
+		// supported challenge/map class IDs
+		$challclasses = array(
+			self::GBX_CHALLENGE_TMF,
+			self::GBX_CHALLENGE_TM,
+		);
+
+		$headerSize = $this->checkHeader($challclasses);
+		$headerStart = $headerEnd = $this->getGBXptr();
+
+		// desired challenge/map chunk IDs
+		$chunks = array(
+			0x002 => 'Info',     // TM, MP
+			0x003 => 'String',   // TM, MP
+			0x004 => 'Version',  // TM, MP
+			0x005 => 'XML',      // TM, MP
+			0x007 => 'Thumbnl',  // TM, MP
+			0x008 => 'Author',   // MP
+		);
+
+		$chunksList = $this->getChunksList($headerSize, $chunks);
+
+		$this->getInfoChunk($chunksList);
+		$headerEnd = max($headerEnd, $this->getGBXptr());
+
+		$this->getStringChunk($chunksList);
+		$headerEnd = max($headerEnd, $this->getGBXptr());
+
+		$this->getVersionChunk($chunksList);
+		$headerEnd = max($headerEnd, $this->getGBXptr());
+
+		$this->getXMLChunk($chunksList);
+		$headerEnd = max($headerEnd, $this->getGBXptr());
+
+		$this->getThumbnlChunk($chunksList);
+		$headerEnd = max($headerEnd, $this->getGBXptr());
+
+		$this->getAuthorChunk($chunksList);
+		$headerEnd = max($headerEnd, $this->getGBXptr());
+
+		if ($headerSize != $headerEnd - $headerStart)
+			$this->errorOut(sprintf('Header size mismatch: %d <> %d',
+			                        $headerSize, $headerEnd - $headerStart), 16);
+
+		if ($this->parseXml) {
+			if (isset($this->xmlParsed['HEADER']['VERSION']))
+				$this->xmlVer = $this->xmlParsed['HEADER']['VERSION'];
+			if (isset($this->xmlParsed['HEADER']['EXEVER']))
+				$this->exeVer = $this->xmlParsed['HEADER']['EXEVER'];
+			if (isset($this->xmlParsed['HEADER']['EXEBUILD']))
+				$this->exeBld = $this->xmlParsed['HEADER']['EXEBUILD'];
+			if ($this->lightmap == 0 && isset($this->xmlParsed['HEADER']['LIGHTMAP']))
+				$this->lightmap = (int)$this->xmlParsed['HEADER']['LIGHTMAP'];
+			if ($this->authorZone == '' && isset($this->xmlParsed['IDENT']['AUTHORZONE']))
+				$this->authorZone = $this->xmlParsed['IDENT']['AUTHORZONE'];
+			if ($this->envir == 'UNKNOWN' && isset($this->xmlParsed['DESC']['ENVIR']))
+				$this->envir = $this->xmlParsed['DESC']['ENVIR'];
+			if ($this->nbLaps == 0 && isset($this->xmlParsed['DESC']['NBLAPS']))
+				$this->nbLaps = (int)$this->xmlParsed['DESC']['NBLAPS'];
+			if (isset($this->xmlParsed['DESC']['VALIDATED']))
+				$this->validated = (bool)$this->xmlParsed['DESC']['VALIDATED'];
+			if (isset($this->xmlParsed['DESC']['MOD']))
+				$this->modName = $this->xmlParsed['DESC']['MOD'];
+
+			// extract optional song & mod filenames
+			if (!empty($this->xmlParsed['DEPS'])) {
+				for ($i = 0; $i < count($this->xmlParsed['DEPS']); $i++) {
+					if (preg_match('/ChallengeMusics\\\\(.+)/', $this->xmlParsed['DEPS'][$i]['FILE'], $path)) {
+						$this->songFile = $path[1];
+						if (isset($this->xmlParsed['DEPS'][$i]['URL']))
+							$this->songUrl = $this->xmlParsed['DEPS'][$i]['URL'];
+					} elseif (preg_match('/.+\\\\Mod\\\\.+/', $this->xmlParsed['DEPS'][$i]['FILE'], $path)) {
+						$this->modFile = $path[0];
+						if (isset($this->xmlParsed['DEPS'][$i]['URL']))
+							$this->modUrl = $this->xmlParsed['DEPS'][$i]['URL'];
+					}
+				}
+			}
+		}
+
+		$this->clearGBXdata();
+	}  // processGBX
+
+	/**
+	 * Get Info chunk from GBX header block
+	 * @param array $chunksList
+	 *        List of chunk offsets & sizes
+	 */
+	protected function getInfoChunk(array $chunksList)
+	{
+		if (!isset($chunksList['Info'])) return;
+
+		$this->initChunk($chunksList['Info']['off']);
+		$version = $this->readInt8();
+		$this->debugLog('GBX Info chunk version: ' . $version);
+
+		if ($version >= 3) {
+			$zero = $this->readInt32();
+
+			$this->bronzeTime = $this->readInt32();
+
+			$this->silverTime = $this->readInt32();
+
+			$this->goldTime = $this->readInt32();
+
+			$this->authorTime = $this->readInt32();
+
+			if ($version >= 4) {
+				$this->cost = $this->readInt32();
+
+				if ($version >= 6) {
+					$this->multiLap = (bool)$this->readInt32();
+
+					$this->type = $this->readInt32();
+					switch ($this->type) {
+						case 0: $this->typeName = 'Race';
+						        break;
+						case 1: $this->typeName = 'Platform';
+						        break;
+						case 2: $this->typeName = 'Puzzle';
+						        break;
+						case 3: $this->typeName = 'Crazy';
+						        break;
+						case 4: $this->typeName = 'Shortcut';
+						        break;
+						case 5: $this->typeName = 'Stunts';
+						        break;
+						case 6: $this->typeName = 'Script';
+						        break;
+						default: $this->typeName = 'UNKNOWN';
+					}
+
+					if ($version >= 9) {
+						$zero = $this->readInt32();
+
+						if ($version >= 10) {
+							$this->authorScore = $this->readInt32();
+
+							if ($version >= 11) {
+								$this->simpleEdit = (bool)$this->readInt32();
+
+								if ($version >= 12) {
+									$zero = $this->readInt32();
+
+									if ($version >= 13) {
+										$this->nbChecks = $this->readInt32();
+
+										$this->nbLaps = $this->readInt32();
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}  // getInfoChunk
+
+	/**
+	 * Get String chunk from GBX header block
+	 * @param array $chunksList
+	 *        List of chunk offsets & sizes
+	 */
+	protected function getStringChunk(array $chunksList)
+	{
+		if (!isset($chunksList['String'])) return;
+
+		$this->initChunk($chunksList['String']['off']);
+		$version = $this->readInt8();
+		$this->debugLog('GBX String chunk version: ' . $version);
+
+		$this->uid = $this->readLookbackString();
+
+		$this->envir  = $this->readLookbackString();
+		$this->author = $this->readLookbackString();
+
+		$this->name = $this->stripBOM($this->readString());
+
+		$this->kind = $this->readInt8();
+		switch ($this->kind) {
+			case 0: $this->kindName = '(internal)EndMarker';
+			        break;
+			case 1: $this->kindName = '(old)Campaign';
+			        break;
+			case 2: $this->kindName = '(old)Puzzle';
+			        break;
+			case 3: $this->kindName = '(old)Retro';
+			        break;
+			case 4: $this->kindName = '(old)TimeAttack';
+			        break;
+			case 5: $this->kindName = '(old)Rounds';
+			        break;
+			case 6: $this->kindName = 'InProgress';
+			        break;
+			case 7: $this->kindName = 'Campaign';
+			        break;
+			case 8: $this->kindName = 'Multi';
+			        break;
+			case 9: $this->kindName = 'Solo';
+			        break;
+			case 10: $this->kindName = 'Site';
+			         break;
+			case 11: $this->kindName = 'SoloNadeo';
+			         break;
+			case 12: $this->kindName = 'MultiNadeo';
+			         break;
+			default: $this->kindName = 'UNKNOWN';
+		}
+
+		if ($version >= 1) {
+			$this->moveGBXptr(4);  // skip unknown
+
+			$this->password = $this->readString();
+
+			if ($version >= 2) {
+				$this->mood = $this->readLookbackString();
+
+				$this->envirBg  = $this->readLookbackString();
+				$this->authorBg = $this->readLookbackString();
+
+				if ($version >= 3) {
+					$this->moveGBXptr(8);  // skip mapOrigin
+
+					if ($version >= 4) {
+						$this->moveGBXptr(8);  // skip mapTarget
+
+						if ($version >= 5) {
+							$this->moveGBXptr(16);  // skip unknown
+
+							if ($version >= 9) {
+								$this->mapType  = $this->readString();
+								$this->mapStyle = $this->readString();
+
+								$this->moveGBXptr(8);  // skip lightmapCacheUID
+
+								$this->lightmap = $this->readInt8();
+
+								if ($version >= 11) {
+									$this->titleUid = $this->readLookbackString();
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}  // getStringChunk
+
+	/**
+	 * Get Version chunk from GBX header block
+	 * @param array $chunksList
+	 *        List of chunk offsets & sizes
+	 */
+	protected function getVersionChunk(array $chunksList)
+	{
+		if (!isset($chunksList['Version'])) return;
+
+		$this->initChunk($chunksList['Version']['off']);
+		$this->headerVersn = $this->readInt32();
+	}  // getVersionChunk
+
+	/**
+	 * Get Thumbnail/Comments chunk from GBX header block
+	 * @param array $chunksList
+	 *        List of chunk offsets & sizes
+	 */
+	protected function getThumbnlChunk(array $chunksList)
+	{
+		if (!isset($chunksList['Thumbnl'])) return;
+
+		$this->initChunk($chunksList['Thumbnl']['off']);
+		$version = $this->readInt32();
+		$this->debugLog('GBX Thumbnail chunk version: ' . $version);
+
+		if ($version == 1) {
+			$thumbSize = $this->readInt32();
+			$this->debugLog(sprintf('GBX Thumbnail size: %d (%.1f KB)',
+			                        $thumbSize, $thumbSize / 1024));
+
+			$this->moveGBXptr(strlen('<Thumbnail.jpg>'));
+			$this->thumbnail = $this->readData($thumbSize);
+			$this->thumbLen = strlen($this->thumbnail);
+			$this->moveGBXptr(strlen('</Thumbnail.jpg>'));
+
+			$this->moveGBXptr(strlen('<Comments>'));
+			$this->comment = $this->stripBOM($this->readString());
+			$this->moveGBXptr(strlen('</Comments>'));
+
+			// return extracted thumbnail image?
+			if ($this->tnImage) {
+				// check for GD/JPEG libraries
+				if (function_exists('imagecreatefromjpeg') &&
+				    function_exists('imagecopyresampled')) {
+					// flip thumbnail via temporary file
+					$tmp = tempnam(sys_get_temp_dir(), 'gbxflip');
+					if (@file_put_contents($tmp, $this->thumbnail) !== false) {
+						if ($tn = @imagecreatefromjpeg($tmp)) {
+							$tn = $this->imageFlip($tn, self::IMAGE_FLIP_HORIZONTAL);
+							if (@imagejpeg($tn, $tmp)) {
+								if (($tn = @file_get_contents($tmp)) !== false) {
+									$this->thumbnail = $tn;
+								}
+							}
+						}
+						unlink($tmp);
+					}
+				}
+			} else {
+				$this->thumbnail = '';
+			}
+		}
+	}  // getThumbnlChunk
+
+}  // class GBXChallMapFetcher
+
+
+/**
+ * @class GBXChallengeFetcher
+ * @brief Wrapper class for backwards compatibility with the old GBXChallengeFetcher
+ * @deprecated Do not use for new development, use GBXChallMapFetcher instead
+ */
+class GBXChallengeFetcher extends GBXChallMapFetcher
+{
+	public $authortm, $goldtm, $silvertm, $bronzetm, $ascore, $azone, $multi, $editor,
+	       $pub, $nblaps, $parsedxml, $xmlver, $exever, $exebld, $songfile, $songurl,
+         $modname, $modfile, $modurl;
+
+	/**
+	 * Fetches a hell of a lot of data about a GBX challenge
+	 *
+	 * @param String $filename
+	 *        The challenge filename (must include full path)
+	 * @param Boolean $parsexml
+	 *        If true, the script also parses the XML block
+	 * @param Boolean $tnimage
+	 *        If true, the script also extracts the thumbnail image; if GD/JPEG
+	 *        libraries are present, image will be flipped upright, otherwise
+	 *        it will be in the original upside-down format
+	 *        Warning: this is binary data in JPEG format, 256x256 pixels for
+   *        TMU/TMF or 512x512 pixels for MP
+	 * @return GBXChallengeFetcher
+	 *        If $uid is empty, GBX data couldn't be extracted
+	 */
+	public function __construct($filename, $parsexml = false, $tnimage = false)
+	{
+		parent::__construct($parsexml, $tnimage, false);
+
+		try
+		{
+			$this->processFile($filename);
+
+			$this->authortm  = $this->authorTime;
+			$this->goldtm    = $this->goldTime;
+			$this->silvertm  = $this->silverTime;
+			$this->bronzetm  = $this->bronzeTime;
+			$this->ascore    = $this->authorScore;
+			$this->azone     = $this->authorZone;
+			$this->multi     = $this->multiLap;
+			$this->editor    = $this->simpleEdit;
+			$this->pub       = $this->authorBg;
+			$this->nblaps    = $this->nbLaps;
+			$this->parsedxml = $this->xmlParsed;
+			$this->xmlver    = $this->xmlVer;
+			$this->exever    = $this->exeVer;
+			$this->exebld    = $this->exeBld;
+			$this->songfile  = $this->songFile;
+			$this->songurl   = $this->songUrl;
+			$this->modname   = $this->modName;
+			$this->modfile   = $this->modFile;
+			$this->modurl    = $this->modUrl;
+		}
+		catch (Exception $e)
+		{
+			$this->uid = '';
+		}
+	}
+
+}  // class GBXChallengeFetcher
+
+
+/**
+ * @class GBXReplayFetcher
+ * @brief The class that fetches all GBX replay info
+ * @note The interface for GBXReplayFetcher has changed compared to the old class,
+ *       but there is no wrapper because no third-party XASECO[2] plugins used that
+ */
+class GBXReplayFetcher extends GBXBaseFetcher
+{
+	public $uid, $envir, $author, $replay, $nickname, $login, $titleUid;
+	public $xmlVer, $exeVer, $exeBld, $respawns, $stuntScore, $validable,
+	       $cpsCur, $cpsLap;
+
+	/**
+	 * Instantiate GBX replay fetcher
+	 *
+	 * @param Boolean $parsexml
+	 *        If true, the fetcher also parses the XML block
+	 * @param Boolean $debug
+	 *        If true, the fetcher prints debug logging to stderr
+	 * @return GBXReplayFetcher
+	 *        If GBX data couldn't be extracted, an Exception is thrown with
+	 *        the error message & code
+	 */
+	public function __construct($parsexml = false, $debug = false)
+	{
+		parent::__construct();
+
+		$this->uid      = '';
+		$this->envir    = '';
+		$this->author   = '';
+		$this->replay   = 0;
+		$this->nickname = '';
+		$this->login    = '';
+		$this->titleUid = '';
+
+		$this->xmlVer     = '';
+		$this->exeVer     = '';
+		$this->exeBld     = '';
+		$this->respawns   = 0;
+		$this->stuntScore = 0;
+		$this->validable  = false;
+		$this->cpsCur     = 0;
+		$this->cpsLap     = 0;
+
+		$this->parseXml = (bool)$parsexml;
+		if ((bool)$debug)
+			$this->enableDebug();
+
+		$this->setError('GBX replay error: ');
+	}  // __construct
+
+	/**
+	 * Process GBX replay file
+	 *
+	 * @param String $filename
+	 *        The replay filename
+	 */
+	public function processFile($filename)
+	{
+		$this->loadGBXdata((string)$filename);
+
+		$this->processGBX();
+	}  // processFile
+
+	/**
+	 * Process GBX replay data
+	 *
+	 * @param String $gbxdata
+	 *        The replay data
+	 */
+	public function processData($gbxdata)
+	{
+		$this->storeGBXdata((string)$gbxdata);
+
+		$this->processGBX();
+	}  // processData
+
+	// process GBX data
+	private function processGBX()
+	{
+		// supported replay class IDs
+		$replayclasses = array(
+			self::GBX_AUTOSAVE_TMF,
+			self::GBX_AUTOSAVE_TM,
+			self::GBX_REPLAY_TM,
+		);
+
+		$headerSize = $this->checkHeader($replayclasses);
+		$headerStart = $headerEnd = $this->getGBXptr();
+
+		// desired replay chunk IDs
+		$chunks = array(
+			0x000 => 'String',  // TM, MP
+			0x001 => 'XML',     // TM, MP
+			0x002 => 'Author',  // MP
+		);
+
+		$chunksList = $this->getChunksList($headerSize, $chunks);
+
+		$this->getStringChunk($chunksList);
+		$headerEnd = max($headerEnd, $this->getGBXptr());
+
+		$this->getXMLChunk($chunksList);
+		$headerEnd = max($headerEnd, $this->getGBXptr());
+
+		$this->getAuthorChunk($chunksList);
+		$headerEnd = max($headerEnd, $this->getGBXptr());
+
+		if ($headerSize != $headerEnd - $headerStart)
+			$this->errorOut(sprintf('Header size mismatch: %d <> %d',
+			                        $headerSize, $headerEnd - $headerStart), 20);
+
+		if ($this->parseXml) {
+			if (isset($this->xmlParsed['HEADER']['VERSION']))
+				$this->xmlVer = $this->xmlParsed['HEADER']['VERSION'];
+			if (isset($this->xmlParsed['HEADER']['EXEVER']))
+				$this->exeVer = $this->xmlParsed['HEADER']['EXEVER'];
+			if (isset($this->xmlParsed['HEADER']['EXEBUILD']))
+				$this->exeBld = $this->xmlParsed['HEADER']['EXEBUILD'];
+			if (isset($this->xmlParsed['TIMES']['RESPAWNS']))
+				$this->respawns = (int)$this->xmlParsed['TIMES']['RESPAWNS'];
+			if (isset($this->xmlParsed['TIMES']['STUNTSCORE']))
+				$this->stuntScore = (int)$this->xmlParsed['TIMES']['STUNTSCORE'];
+			if (isset($this->xmlParsed['TIMES']['VALIDABLE']))
+				$this->validable = (bool)$this->xmlParsed['TIMES']['VALIDABLE'];
+			if (isset($this->xmlParsed['CHECKPOINTS']['CUR']))
+				$this->cpsCur = (int)$this->xmlParsed['CHECKPOINTS']['CUR'];
+			if (isset($this->xmlParsed['CHECKPOINTS']['ONELAP']))
+				$this->cpsLap = (int)$this->xmlParsed['CHECKPOINTS']['ONELAP'];
+		}
+
+		$this->clearGBXdata();
+	}  // processGBX
+
+	/**
+	 * Get String chunk from GBX header block
+	 * @param array $chunksList
+	 *        List of chunk offsets & sizes
+	 */
+	protected function getStringChunk(array $chunksList)
+	{
+		if (!isset($chunksList['String'])) return;
+
+		$this->initChunk($chunksList['String']['off']);
+		$version = $this->readInt32();
+		$this->debugLog('GBX String chunk version: ' . $version);
+
+		if ($version >= 2) {
+			$this->uid = $this->readLookbackString();
+
+			$this->envir  = $this->readLookbackString();
+			$this->author = $this->readLookbackString();
+
+			$this->replay = $this->readInt32();
+
+			$this->nickname = $this->stripBOM($this->readString());
+
+			if ($version >= 6) {
+				$this->login = $this->readString();
+
+				if ($version >= 8) {
+					$this->moveGBXptr(1);  // skip unknown
+
+					$this->titleUid = $this->readLookbackString();
+				}
+			}
+		}
+	}  // getStringChunk
+
+}  // class GBXReplayFetcher
+
+
+/**
+ * @class GBXPackFetcher
+ * @brief The class that fetches all GBX pack info
+ */
+class GBXPackFetcher extends GBXBaseFetcher
+{
+	public $headerVersn, $flags, $infoMlUrl, $creatDate, $comment, $titleId,
+	       $usageSubdir, $buildInfo, $authorUrl, $exeVer, $exeBld, $xmlDate;
+
+	/**
+	 * Read Windows FileTime and convert to Unix timestamp
+	 * Filetime = 64-bit value with the number of 100-nsec intervals since Jan 1, 1601 (UTC)
+	 * Based on http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/
+	 * @return Unix timestamp, or -1 on error
+	 */
+	private function readFiletime()
+	{
+		// Unix epoch (1970-01-01) - Windows epoch (1601-01-01) in 100ns units
+		$EPOCHDIFF = '116444735995904000';
+		$UINT32MAX = '4294967296';
+		$USEC2SEC  = 1000000;
+
+		$lo = $this->readInt32();
+		$hi = $this->readInt32();
+
+		// check for 64-bit platform
+		if (PHP_INT_SIZE >= 8) {
+			// use native math
+			if ($lo < 0) $lo += (1 << 32);
+			$date = ($hi << 32) + $lo;
+			$this->debugLog(sprintf('PAK CreationDate source: %016x', $date));
+			if ($date == 0) return -1;
+
+			// convert to Unix timestamp in usec
+			$stamp = ($date - (int)$EPOCHDIFF) / 10;
+			$this->debugLog(sprintf('PAK CreationDate 64-bit: %u.%06u',
+			                        $stamp / $USEC2SEC, $stamp % $USEC2SEC));
+			return (int)($stamp / $USEC2SEC);
+
+		// check for 32-bit platform
+		} elseif (PHP_INT_SIZE >= 4) {
+			$this->debugLog(sprintf('PAK CreationDate source: %08x%08x', $hi, $lo));
+			if ($lo == 0 && $hi == 0) return -1;
+
+			// workaround signed/unsigned braindamage on x32
+			$lo = sprintf('%u', $lo);
+			$hi = sprintf('%u', $hi);
+
+			// try and use GMP
+			if (function_exists('gmp_mul')) {
+				$date = gmp_add(gmp_mul($hi, $UINT32MAX), $lo);
+				// convert to Unix timestamp in usec
+				$stamp = gmp_div(gmp_sub($date, $EPOCHDIFF), 10);
+				$stamp = gmp_div_qr($stamp, $USEC2SEC);
+				$this->debugLog(sprintf('PAK CreationDate GNU MP: %u.%06u',
+				                        gmp_strval($stamp[0]), gmp_strval($stamp[1])));
+				return (int)gmp_strval($stamp[0]);
+			}
+
+			// try and use BC Math
+			if (function_exists('bcmul')) {
+				$date = bcadd(bcmul($hi, $UINT32MAX), $lo);
+				// convert to Unix timestamp in usec
+				$stamp = bcdiv(bcsub($date, $EPOCHDIFF), 10, 0);
+				$this->debugLog(sprintf('PAK CreationDate BCMath: %u.%06u',
+				                        bcdiv($stamp, $USEC2SEC), bcmod($stamp, $USEC2SEC)));
+				return (int)bcdiv($stamp, $USEC2SEC);
+			}
+
+			// compute everything manually
+			$a = substr($hi, 0, -5);
+			$b = substr($hi, -5);
+			// hope that float precision is enough
+			$ac = $a * 42949;
+			$bd = $b * 67296;
+			$adbc = $a * 67296 + $b * 42949;
+			$r4 = substr($bd, -5) + substr($lo, -5);
+			$r3 = substr($bd, 0, -5) + substr($adbc, -5) + substr($lo, 0, -5);
+			$r2 = substr($adbc, 0, -5) + substr($ac, -5);
+			$r1 = substr($ac, 0, -5);
+			while ($r4 >= 100000) { $r4 -= 100000; $r3++; }
+			while ($r3 >= 100000) { $r3 -= 100000; $r2++; }
+			while ($r2 >= 100000) { $r2 -= 100000; $r1++; }
+			$date = ltrim(sprintf('%d%05d%05d%05d', $r1, $r2, $r3, $r4), '0');
+
+			// convert to Unix timestamp in usec
+			$r3 = substr($date, -6)     - substr($EPOCHDIFF, -6);
+			$r2 = substr($date, -12, 6) - substr($EPOCHDIFF, -12, 6);
+			$r1 = substr($date, -18, 6) - substr($EPOCHDIFF, -18, 6);
+			if ($r3 < 0) { $r3 += 1000000; $r2--; }
+			if ($r2 < 0) { $r2 += 1000000; $r1--; }
+			$stamp = substr(sprintf('%d%06d%06d', $r1, $r2, $r3), 0, -1);
+			$this->debugLog(sprintf('PAK CreationDate manual: %s.%s',
+			                        substr($stamp, 0, -6), substr($stamp, -6)));
+			return (int)substr($stamp, 0, -6);
+		} else {
+			return -1;
+		}
+	}
+
+	/**
+	 * Instantiate GBX pack fetcher
+	 *
+	 * @param Boolean $parsexml
+	 *        If true, the fetcher also parses the XML block
+	 * @param Boolean $debug
+	 *        If true, the fetcher prints debug logging to stderr
+	 * @return GBXPackFetcher
+	 *        If GBX data couldn't be extracted, an Exception is thrown with
+	 *        the error message & code
+	 */
+	public function __construct($parsexml = false, $debug = false)
+	{
+		parent::__construct();
+
+		$this->headerVersn = 0;
+		$this->flags       = 0;
+		$this->infoMlUrl   = '';
+		$this->creatDate   = -1;
+		$this->comment     = '';
+		$this->titleId     = '';
+		$this->usageSubdir = '';
+		$this->buildInfo   = '';
+		$this->authorUrl   = '';
+		$this->exeVer      = '';
+		$this->exeBld      = '';
+		$this->xmlDate     = '';
+
+		$this->parseXml = (bool)$parsexml;
+		if ((bool)$debug)
+			$this->enableDebug();
+
+		$this->setError('GBX pack error: ');
+	}  // __construct
+
+	/**
+	 * Process GBX pack file
+	 *
+	 * @param String $filename
+	 *        The pack filename
+	 */
+	public function processFile($filename)
+	{
+		$this->loadGBXdata((string)$filename);
+
+		$this->processGBX();
+	}  // processFile
+
+	/**
+	 * Process GBX pack data
+	 *
+	 * @param String $gbxdata
+	 *        The pack data
+	 */
+	public function processData($gbxdata)
+	{
+		$this->storeGBXdata((string)$gbxdata);
+
+		$this->processGBX();
+	}  // processData
+
+	// process GBX data
+	private function processGBX()
+	{
+		// check magic header
+		$data = $this->readData(8);
+		if ($data != 'NadeoPak')
+			$this->errorOut('No magic NadeoPak header', 5);
+
+		$this->headerVersn = $this->readInt32();
+		if ($this->headerVersn < 8)
+			$this->errorOut(sprintf('Pack version %d not supported', $this->headerVersn), 24);
+
+		$this->moveGBXptr(32);  // skip ContentsChecksum
+
+		$this->flags = $this->readInt32();
+
+		$this->getAuthorFields();
+
+		$this->infoMlUrl = $this->readString();
+
+		$this->creatDate = $this->readFiletime();
+
+		$this->comment = $this->stripBOM($this->readString());
+
+		if ($this->headerVersn >= 12) {
+			$this->xml = $this->readString();
+			$this->titleId = $this->readString();
+			if ($this->parseXml && $this->xml != '') {
+				$this->parseXMLstring();
+
+				if (isset($this->xmlParsed['HEADER']['EXEVER']))
+					$this->exeVer = $this->xmlParsed['HEADER']['EXEVER'];
+				if (isset($this->xmlParsed['HEADER']['EXEBUILD']))
+					$this->exeBld = $this->xmlParsed['HEADER']['EXEBUILD'];
+				if (isset($this->xmlParsed['IDENT']['CREATIONDATE']))
+					$this->xmlDate = $this->xmlParsed['IDENT']['CREATIONDATE'];
+			}
+		}
+
+		$this->usageSubdir = $this->readString();
+
+		$this->buildInfo = $this->readString();
+
+		$this->authorUrl = $this->readString();
+
+		if ($this->headerVersn >= 10)
+			$this->moveGBXptr(16);  // skip unused
+
+		$this->clearGBXdata();
+	}  // processGBX
+
+}  // class GBXPackFetcher
+?>
diff --git a/resources/class/str.class.php b/resources/class/str.class.php
new file mode 100644
index 0000000..426bcb7
--- /dev/null
+++ b/resources/class/str.class.php
@@ -0,0 +1,183 @@
+<?php
+/**
+* Class Str
+*
+* Méthodes de traitement de chaines de caractères
+*/
+abstract class Str {
+	
+	/**
+	* Formatage de la taille
+	* 
+	* @param int $size -> Taille
+	* @return string
+	*/
+	public static function formatSize($size){
+		$u = array('octets', 'Ko', 'Mo', 'Go', 'To');
+		$i = 0;
+		$m = 0;
+		
+		while($size >= 1){
+			$m = $size;
+			$size /= 1024;
+			$i++;
+		}
+		if(!$i){
+			$i = 1;
+		}
+		$d = explode('.', $m);
+		
+		if($d[0] != $m){
+			$m = number_format($m, 1, ',', ' ');
+		}
+		
+		return $m.' '.$u[$i-1];
+	}
+	
+	
+	/**
+	* Modifie les antislashes d'un lien local en slashes pour usage web
+	*
+	* @param string $path -> Le chemin à modifier
+	* @return string
+	*/
+	public static function toSlash($path){
+		$out = null;
+		
+		if( strstr($path, '\\') ){
+			$newPath = explode('\\', $path);
+			foreach($newPath as $part){
+				$out .= $part.'/';
+			}
+			$out = substr($out, 0, -1);
+		}
+		else{
+			$out = $path;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Remplace ou supprime les caractères spéciaux
+	*
+	* @param string $str -> La chaine de caractères
+	*/
+	public static function replaceSpecialChars($str, $replaceSpace = true){
+		// Listes
+		$toRemove = array(
+			"'", '"', '&', '<', '>', '+', '=', '*', '/', '²', '~', '#', '{', '[', '(', '|', '`', '\\', '^', '@', ')', ']', '}', '¨', '$', '£', '¤',
+			'!', '%', '§', ':', ';', ',', '?', '«', '»', '“', '”', '„', '…', '¡', '¿', '‘', '’', 'ˆ', '˜', '¸', '·', '•', '¯', '‾', '—', '¦', '†',
+			'‡', '¶', '©', '®', '™', '◊', '♠', '♣', '♥', '♦', '←', '↑', '→', '↓', '↔', 'Γ', 'δ', 'Δ', 'ζ', 'θ', 'Θ', 'ι', 'Λ', 'ξ', 'Ξ', 'π', 'Π',
+			'σ', 'ς', 'Σ', 'φ', 'Φ', 'ψ', 'Ψ', 'ω', 'Ω', '°', '≤', '≥', '≈', '≠', '≡', '±', '×', '÷', '⁄', '‰', '¼', '½', '¾', '¹', '³', 'º', 'ª',
+			'′', '″', '∂', '∏', '∑', '√', '∞', '¬', '∩', '∫', '⇒', '⇔', '∀', '∃', '∇', '∈', '∋', '∝', '∠', '∧', '∨', '∴', '∼', '⊂', '⊃',
+			'⊆', '⊇', '⊥'
+		);
+		if($replaceSpace){
+			$toDash = array(
+				' ', '  '
+			);
+		}
+		
+		// Remplacement
+		$str = trim($str);
+		$str = str_replace($toRemove, '', $str);
+		if($replaceSpace){
+			$str = str_replace($toDash, '-', $str);
+		}
+		else{
+			$str = trim($str);
+		}
+		return $str;
+	}
+	
+	
+	/**
+	* Remplace les caractères accentués par leurs caractères normal
+	*
+	* @param string $str -> La chaine de caractères
+	*/
+	public static function replaceAccentChars($str){
+		$str = utf8_decode($str);
+		$str = strtr($str, utf8_decode('ÀÁÂÃÄÅΑλàáâãäåαβþÐÒÓÔÕÖØòóôõöøÈÉÊËèéêë€εƒÇç¢ÌÍÎÏìíîïÙÚÛÜ∪ùúûüµυÿýýŸÝ¥ÑñηŔŕρτ'), 'AAAAAAAAaaaaaaaBbDOOOOOOooooooEEEEeeeeEefCccIIIIiiiiUUUUUuuuuuuyyyYYYNnnRrpt');
+		return utf8_encode($str);
+	}
+	
+	
+	/**
+	* Remplace ou supprime les caractères spéciaux et remplace les caractères accentués
+	*
+	* @param string $str -> La chaine de caractères
+	*/
+	public static function replaceChars($str){
+		return self::replaceSpecialChars( self::replaceAccentChars($str) );
+	}
+	
+	
+	/**
+	* Récupère le type d'une valeur
+	*
+	* @param  mixed $val -> La valeur à analyser
+	* @return string
+	*/
+	public static function getValueType($val){
+		$out = null;
+		
+		if( is_string($val) ){
+			$out = 'string';
+		}
+		elseif( is_bool($val) ){
+			$out = 'bool';
+		}
+		elseif( is_float($val) ){
+			$out = 'float';
+		}
+		elseif( is_int($val) ){
+			$out = 'int';
+		}
+		elseif( is_array($val) ){
+			$out = 'array';
+		}
+		elseif( is_object($val) ){
+			$out = 'object';
+		}
+		elseif( is_resource($val) ){
+			$out = 'resource';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Converti le type d'une valeur
+	*
+	* @param mixed  $val  -> La valeur à convertir
+	* @param string $type -> Le type à affecter
+	*/
+	public static function setValueType($val, $type){
+		switch($type){
+			case 'array':
+				$val = (array)$val;
+				break;
+			case 'bool':
+			case 'boolean':
+				$val = (bool)$val;
+				break;
+			case 'float':
+			case 'double':
+				$val = (float)$val;
+				break;
+			case 'int':
+			case 'integer':
+				$val = (int)$val;
+				break;
+			default:
+				$val = (string)$val;
+		}
+		
+		return $val;
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/class/timedate.class.php b/resources/class/timedate.class.php
new file mode 100644
index 0000000..c675b1b
--- /dev/null
+++ b/resources/class/timedate.class.php
@@ -0,0 +1,313 @@
+<?php
+abstract class TimeDate {
+	
+	/**
+	* Retourne la date suivant la langue
+	*
+	* @param string $format    -> Le format de la fonction strftime()
+	* @param int    $timestamp -> Le temps en sec
+	* @param string $lang      -> La langue de la date retournée
+	* @return string
+	*/
+	public static function date($format, $timestamp = null, $lang = 'en'){
+		if($timestamp === null){
+			$timestamp = time();
+		}
+		setlocale(LC_ALL, $lang);
+		return strftime($format, $timestamp);
+	}
+	
+	
+	/**
+	* Rentourne la date au format INT
+	*
+	* @param string $date          -> La date sous la forme JJ/MM/AAAA, JJ.MM.AAAA, JJ-MM-AAAA ou JJ MM AAAA sinon mettre $use_strtotime sur true
+	* @param bool   $use_strtotime -> Utiliser la méthode php strtotime pour une date d'un autre format
+	* @return int
+	*/
+	public static function dateToTime($date, $use_strtotime = false){
+		$out = 0;
+		
+		if($date){
+			$date = trim($date);
+			if( strstr($date, '/') && !$use_strtotime){
+				$date_ex = explode('/', $date);
+			}
+			else if( strstr($date_ex, '.')  && !$use_strtotime){
+				$date_ex = explode('.', $date_ex);
+			}
+			else if( strstr($date_ex, '-')  && !$use_strtotime){
+				$date_ex = explode('-', $date_ex);
+			}
+			else if( strstr($date_ex, ' ')  && !$use_strtotime){
+				$date_ex = explode(' ', $date_ex);
+			}
+			
+			if( !$use_strtotime ){
+				$out = mktime(0, 0, 0, $date_ex[1], $date_ex[0], $date_ex[2]); 
+			}
+			else{
+				$out = strtotime($date);
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne un temps au format INT
+	*
+	* @param string $time          -> Le temps sous la forme HH:MM:SS, HH:MM.SS, HH.MM.SS, HH-MM-SS ou HH MM SS sinon mettre $use_strtotime sur true
+	* @param bool   $use_strtotime -> Utiliser la méthode php strtotime pour un temps d'un autre format
+	* @return int
+	*/
+	public static function timeToSec($time, $use_strtotime){
+		$out = 0;
+		$h = 3600;
+		$m = 60;
+		$s = 1;
+		
+		if($time){
+			$time = trim($time);
+			if( strstr($time, ':') && !strstr($time, '.') && !$use_strtotime){
+				$time_ex = explode(':', $time);
+			}
+			else if( strstr($time, ':') && strstr($time, '.') && !$use_strtotime){
+				$time_ex = explode(':', $time);
+				$time_ex2 = explode('.', $time);
+				$out = ($time_ex[0] * $h) + ($time_ex[1] * $m) + ($time_ex2[1] * $s); 
+			}
+			else if( strstr($time, '.') && !strstr($time, ':') && !$use_strtotime){
+				$time_ex = explode('.', $time);
+			}
+			else if( strstr($time, '-') && !$use_strtotime){
+				$time_ex = explode('-', $time);
+			}
+			else if( strstr($time, ' ') && !$use_strtotime){
+				$time_ex = explode(' ', $time);
+			}
+			
+			
+			if( !$use_strtotime && $out === 0){
+				$out = ($time_ex[0] * $h) + ($time_ex[1] * $m) + ($time_ex[2] * $s); 
+			}
+			else{
+				$out = strtotime($time);
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Formate une date pour une entrée MySQL
+	*
+	* @param string $type          -> Le type Mysql à retourner
+	* @param string $date          -> La date sous la forme JJ/MM/AAAA, JJ.MM.AAAA, JJ-MM-AAAA ou JJ MM AAAA sinon mettre $use_strtotime sur true
+	* @param string $time          -> Le temps sous la forme HH:MM:SS, HH:MM.SS, HH.MM.SS, HH-MM-SS ou HH MM SS
+	* @param bool   $use_strtotime -> Utiliser la méthode php strtotime pour une date d'un autre format
+	* @return string
+	*/
+	public static function formatDateForMySQL($type, $date, $time = '00:00:00', $use_strtotime = false){
+		$out = '000-00-00 00:00:00';
+		$type = strtoupper($type);
+		$date = trim($date);
+		
+		switch($type){
+			case 'DATE':
+				$out = date('Y-m-d', self::dateToTime($date, $use_strtotime));
+				break;
+			case 'DATETIME':
+				$datetotime = self::dateToTime($date, $use_strtotime);
+				$timetosec = self::timeToSec($time, $use_strtotime);
+				$out = date('Y-m-d H:i:s', $datetotime + $timetosec);
+				break;
+			case 'TIME':
+				$out = date('H:i:s', self::timeToSec($time, $use_strtotime));
+				break;
+			case 'YEAR':
+				$out = date('Y', self::dateToTime($date, $use_strtotime));
+				break;
+			default:
+				$out = self::formatDateForMySQL('DATETIME', $date, $time, $use_strtotime);
+		}
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère l'âge à partir de l'année de naissance
+	*
+	* @param string $birthday -> Sous la forme jj/mm/aaaa ou autre
+	*/
+	public static function getYearOld($birthday){
+		$out = null;
+		$birthdayDate = getdate( self::dateToTime($birthday) );
+		$currentDate = getdate();
+		
+		if( $birthdayDate['mon'] < $currentDate['mon'] || ($birthdayDate['mon'] == $currentDate['mon'] && $birthdayDate['mday'] <= $currentDate['mday']) ){
+			$out = $currentDate['year'] - $birthdayDate['year'];
+		}
+		else{
+			$out = $currentDate['year'] - $birthdayDate['year'] - 1;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne une date relative sous la forme il y a x jours/heures/minutes/secondes
+	*
+	* @param int $time -> Temps en seconde
+	* @return string
+	*/
+	public static function relativeTime($time){
+		$out = null;
+		$timeDifference = time() - $time;
+		
+		if($timeDifference > 0){
+			$seconds = $timeDifference;
+			$minutes = round($timeDifference/60);
+			$hours = round($timeDifference/3600);
+			$days = round($timeDifference/86400);
+			$weeks = round($timeDifference/604800);
+			$months = round($timeDifference/2419200);
+			$years = round($timeDifference/29030400);
+			
+			if($seconds < 60){
+				$out .= 'Il y a moins d\'une minute';
+			}
+			else if($minutes < 60){
+				$out .= 'Il y a '.$minutes.' minute'; if($minutes > 1){ $out .= 's'; }
+			}
+			else if($hours < 24){
+				$out .= 'Il y a '.$hours.' heure'; if($hours > 1){ $out .= 's'; }
+			}
+			else if($days < 7){
+				$out .= 'Il y a '.$days.' jour'; if($days > 1){ $out .= 's'; }
+			}
+			else if($weeks < 4){
+				$out .= 'Il y a '.$weeks.' semaine'; if($weeks > 1){ $out .= 's'; }
+			}
+			else if($months < 12){
+				$out .= 'Il y a '.$months.' mois';
+			}
+			else{
+				$out .= 'Il y a '.$years.' an'; if($years > 1){ $out .= 's'; }
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Transforme un temps en seconde sous forme 0 jour 0 heure 0 minute 0 seconde
+	*
+	* @param  int  $sec      -> Secondes à transformer
+	* @param  bool $fullText -> Retourner le texte en entier
+	* @return string
+	*/
+	public static function secToStringTime($sec, $fullText = true){
+		$out = null;
+		
+		$year = 1*60*60*24*365;
+		$day = 1*60*60*24;
+		$hour = 1*60*60;
+		$minute = 1*60;
+		$second = 1;
+		
+		$timeDifference = intval($sec);
+		$yearCount = floor($timeDifference / $year);
+		$timeDifference -= $yearCount * $year;
+		$dayCount = floor($timeDifference / $day);
+		$timeDifference -= $dayCount * $day;
+		$hourCount = floor($timeDifference / $hour);
+		$timeDifference -= $hourCount * $hour;
+		$minuteCount = floor($timeDifference / $minute);
+		$timeDifference -= $minuteCount * $minute;
+		$secondCount = floor($timeDifference / $second);
+		$timeDifference -= $secondCount * $second;
+		
+		$strDay = $dayCount.'d'; if($fullText){ $strDay .= 'day'; if($dayCount > 1){ $strDay .= 's'; } }
+		$strHour = $hourCount.'h'; if($fullText){ $strHour .= 'hour'; if($hourCount > 1){ $strHour .= 's'; } }
+		$strMinute = $minuteCount.'min'; if($fullText){ $strMinute .= 'minute'; if($minuteCount > 1){ $strMinute .= 's'; } }
+		$strSecond = $secondCount.'sec'; if($fullText){ $strSecond .= 'second'; if($secondCount > 1){ $strSecond .= 's'; } }
+		
+		if($dayCount != 0){
+			$out .= $strDay.', '.$strHour.' '.$strMinute.' '.$strSecond;
+		}
+		else if($dayCount == 0 && $hourCount != 0){
+			$out .= $strHour.' '.$strMinute.' '.$strSecond;
+		}
+		else if($dayCount == 0 && $hourCount == 0){
+			$out .= $strMinute.' '.$strSecond;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Forme le temps millisecondes en 00:00:00
+	*
+	* @param  string $millisec -> Temps en millisecondes
+	* @return string
+	*/
+	public static function format($millisec){
+		$cen = intval( ($millisec % 1000) / 10 );
+		if($cen < 10){
+			$cen = '0'.$cen;
+		}
+		$sec = intval( ($millisec / 1000) % 60 );
+		if($sec < 10){
+			$sec = '0'.$sec;
+		}
+		$min = intval($millisec / 60000);
+		if($min < 10){
+			$min = '0'.$min;
+		}
+		
+		return $min.':'.$sec.':'.$cen;
+	}
+	
+	
+	/**
+	* Méthodes de convertion du temps (Min, sec, millisec)
+	*/
+	public static function secToMillisec($sec){
+		$sec = intval( round($sec) );
+		$millisec = $sec * 1000;
+		if($millisec > 0){ return $millisec; }
+		else{ return 0; }
+	}
+	public static function millisecToSec($millisec){
+		$millisec = intval( round($millisec) );
+		$sec = $millisec / 1000;
+		if($sec > 0){ return $sec; }
+		else{ return 0; }
+	}
+	public static function secToMin($sec){
+		$sec = intval( round($sec) );
+		$min = $sec / 60;
+		if($min > 0){ return $min; }
+		else{ return 0; }
+	}
+	public static function minToSec($min){
+		$min = intval( round($min) );
+		$sec = $min * 60;
+		if($sec > 0){ return $sec; }
+		else{ return 0; }
+	}
+	public static function millisecToMin($millisec){
+		$millisec = intval( round($millisec) );
+		$sec = $millisec / 1000;
+		$min = $sec / 60;
+		if($min > 0){ return $min; }
+		else{ return 0; }
+	}
+}
+?>
diff --git a/resources/class/tmnick.class.php b/resources/class/tmnick.class.php
new file mode 100644
index 0000000..e08c2ac
--- /dev/null
+++ b/resources/class/tmnick.class.php
@@ -0,0 +1,960 @@
+<?php
+/**
+* Cette classe gère les chaines TMF, c'est à dire que cette classe permet de convertir une chaine TM en:
+*   - html (ombre et lien sont géré)
+*   - texte brut -> sans la mise en forme
+*   - image (tout format supporté, image d'arrière plan ou pas)
+*
+* @author Mr. Das - Gildas de Cadoudal - gdecad@gmail.com
+* @package framework
+*/
+class TmNick {
+	/**
+	* Ces codes sont valables dans l'ensemble des jeux TrackMania :
+	* 
+	* $t Majuscule
+	* $i Italique
+	* $s Ombré
+	* $w Espacements larges
+	* $n Espacements courts
+	* $m Espacements normaux
+	* $g Couleur par défaut
+	* $z Tout réinitialiser
+	* $$ Ecrire un "$"
+	* $o Gras avec espacements semi-larges
+	* $h Lien interne vers un Manialink
+	* $p Lien interne avec info joueur
+	* $l Lien externe vers un site web
+	*/
+	public  static $m_fontPath = 'fonts/';
+	public  static $linkProtocol = 'tmtp';
+	private static $m_pattern = '/\\$\\$|\\$[0-9a-fA-F][0-9a-zA-Z]{2}|\\$[twmgonishplzTWMGONISHLZ]/';
+	private static $m_patternLink = '/(?:\\[(?P<url>[^\\[\\]]*)\\]){0,1}(?P<label>.+){0,1}/';
+	private static $m_lstTags = array('h','p','l','o','g','t','w','m','n','i','s','z','color');
+	private static $m_css = array(
+		'h' => 'tmnick_internallink',
+		'p' => 'tmnick_internallink_withlogin',
+		'l' => 'tmnick_externallink',
+		'o' => 'tmnick_bold',
+		'g' => 'tmnick_defaultcolor',
+		't' => 'tmnick_upper',
+		'w' => 'tmnick_wide',
+		'm' => 'tmnick_normal',
+		'n' => 'tmnick_short',
+		'i' => 'tmnick_italic',
+		's' => 'tmnick_shadowed',
+		'z' => 'tmnick_raz'
+	);
+	private static $m_fonts = array(
+		'h' => '',
+		'l' => '',
+		'o' => 'DM',
+		'g' => '',
+		't' => '',
+		'w' => '',
+		'm' => '',
+		'n' => 'CN',
+		'i' => 'IT',
+		's' => '',
+		'z' => 'MD'
+	);
+	private static $m_defaultHexaOnError = '0';
+	private static $m_colorNameToHtml = array(
+		'aliceblue' => '#f0f8ff', 'antiquewhite' => '#faebd7', 'aqua' => '#00ffff', 'aquamarine' => '#7fffd4', 'azure' => '#f0ffff', 'beige' => '#f5f5dc', 'bisque' => '#ffe4c4', 'black' => '#000000', 'blanchedalmond' => '#ffebcd', 'blue' => '#0000ff',
+		'blueviolet' => '#8a2be2', 'brown' => '#a52a2a', 'burlywood' => '#deb887', 'cadetblue' => '#5f9ea0', 'chartreuse' => '#7fff00', 'chocolate' => '#d2691e', 'coral' => '#ff7f50', 'cornflowerblue' => '#6495ed', 'cornsilk' => '#fff8dc', 'crimson' => '#dc143c',
+		'cyan' => '#00ffff', 'darkblue' => '#00008b', 'darkcyan' => '#008b8b', 'darkgoldenrod' => '#b8860b', 'darkgray' => '#a9a9a9', 'darkgrey' => '#a9a9a9', 'darkgreen' => '#006400', 'darkkhaki' => '#bdb76b', 'darkmagenta' => '#8b008b', 'darkolivegreen' => '#556b2f',
+		'darkorange' => '#ff8c00', 'darkorchid' => '#9932cc', 'darkred' => '#8b0000', 'darksalmon' => '#e9967a', 'darkseagreen' => '#8fbc8f', 'darkslateblue' => '#483d8b', 'darkslategray' => '#2f4f4f', 'darkslategrey' => '#2f4f4f', 'darkturquoise' => '#00ced1', 'darkviolet' => '#9400d3',
+		'deeppink' => '#ff1493', 'deepskyblue' => '#00bfff', 'dimgray' => '#696969', 'dimgrey' => '#696969', 'dodgerblue' => '#1e90ff', 'firebrick' => '#b22222', 'floralwhite' => '#fffaf0', 'forestgreen' => '#228b22', 'fuchsia' => '#ff00ff', 'gainsboro' => '#dcdcdc',
+		'ghostwhite' => '#f8f8ff', 'gold' => '#ffd700', 'goldenrod' => '#daa520', 'gray' => '#808080', 'grey' => '#808080', 'green' => '#008000', 'greenyellow' => '#adff2f', 'honeydew' => '#f0fff0', 'hotpink' => '#ff69b4', 'indianred' => '#cd5c5c',
+		'indigo' => '#4b0082', 'ivory' => '#fffff0', 'khaki' => '#f0e68c', 'lavender' => '#e6e6fa', 'lavenderblush' => '#fff0f5', 'lawngreen' => '#7cfc00', 'lemonchiffon' => '#fffacd', 'lightblue' => '#add8e6', 'lightcoral' => '#f08080', 'lightcyan' => '#e0ffff',
+		'lightgoldenrodyellow' => '#fafad2', 'lightgray' => '#d3d3d3', 'lightgrey' => '#d3d3d3', 'lightgreen' => '#90ee90', 'lightpink' => '#ffb6c1', 'lightsalmon' => '#ffa07a', 'lightseagreen' => '#20b2aa', 'lightskyblue' => '#87cefa', 'lightslategray' => '#778899', 'lightslategrey' => '#778899',
+		'lightsteelblue' => '#b0c4de', 'lightyellow' => '#ffffe0', 'lime' => '#00ff00', 'limegreen' => '#32cd32', 'linen' => '#faf0e6', 'magenta' => '#ff00ff', 'maroon' => '#800000', 'mediumaquamarine' => '#66cdaa', 'mediumblue' => '#0000cd', 'mediumorchid' => '#ba55d3',
+		'mediumpurple' => '#9370d8', 'mediumseagreen' => '#3cb371', 'mediumslateblue' => '#7b68ee', 'mediumspringgreen' => '#00fa9a', 'mediumturquoise' => '#48d1cc', 'mediumvioletred' => '#c71585', 'midnightblue' => '#191970', 'mintcream' => '#f5fffa', 'mistyrose' => '#ffe4e1', 'moccasin' => '#ffe4b5',
+		'navajowhite' => '#ffdead', 'navy' => '#000080', 'oldlace' => '#fdf5e6', 'olive' => '#808000', 'olivedrab' => '#6b8e23', 'orange' => '#ffa500', 'orangered' => '#ff4500', 'orchid' => '#da70d6', 'palegoldenrod' => '#eee8aa', 'palegreen' => '#98fb98',
+		'paleturquoise' => '#afeeee', 'palevioletred' => '#d87093', 'papayawhip' => '#ffefd5', 'peachpuff' => '#ffdab9', 'peru' => '#cd853f', 'pink' => '#ffc0cb', 'plum' => '#dda0dd', 'powderblue' => '#b0e0e6', 'purple' => '#800080', 'red' => '#ff0000',
+		'rosybrown' => '#bc8f8f', 'royalblue' => '#4169e1', 'saddlebrown' => '#8b4513', 'salmon' => '#fa8072', 'sandybrown' => '#f4a460', 'seagreen' => '#2e8b57', 'seashell' => '#fff5ee', 'sienna' => '#a0522d', 'silver' => '#c0c0c0', 'skyblue' => '#87ceeb',
+		'slateblue' => '#6a5acd', 'slategray' => '#708090', 'slategrey' => '#708090', 'snow' => '#fffafa', 'springgreen' => '#00ff7f', 'steelblue' => '#4682b4', 'tan' => '#d2b48c', 'teal' => '#008080', 'thistle' => '#d8bfd8', 'tomato' => '#ff6347',
+		'turquoise' => '#40e0d0', 'violet' => '#ee82ee', 'wheat' => '#f5deb3', 'white' => '#ffffff', 'whitesmoke' => '#f5f5f5', 'yellow' => '#ffff00', 'yellowgreen' => '#9acd32'
+	);
+	
+	
+	/**
+	* Convertie une chaine TM en HTML
+	*
+	* @param string $nick                   -> La chaine TM pas de limite de longueur, et peut être multiligne
+	* @param int    $fontSize               -> Taille de la police
+	* @param bool   $forcedDefault          -> Force la couleur par défaut à être utilise à la place de la mise en forme
+	* @param string $defaultColor           -> La couleur par défaut (la couleur peut être au format HTML, nommé, array RGB, ou TM)
+	* @param string $defaultBackgroundColor -> La couleur de fond (transparent est possible) (la couleur peut être au format HTML, nommé, array RGB, ou TM)
+	* @return string chaine HTML sans le CSS
+	*/
+	public static function toHtml($nick, $fontSize = 11, $forcedShadow = false, $forcedDefault = false, $defaultColor = 'white', $defaultBackgroundColor = 'transparent'){
+		if($forcedShadow){ $nick = '$s'.str_replace(array('$s', '$S'), '', $nick); }
+		$linkProtocol = strtolower(self::$linkProtocol);
+		
+		$defaultHTMLColor = $defaultColor;
+		if( empty($defaultColor) ){
+			$defaultHTMLColor = 'white';
+		}
+		else if($defaultColor[0] == '$'){
+			$defaultHTMLColor = self::colorToHtml($defaultColor);
+		}
+		
+		$defaultHTMLBackgroundColor = $defaultBackgroundColor;
+		if( empty($defaultBackgroundColor) ){
+			$defaultHTMLBackgroundColor = 'black';
+		}
+		else if($defaultBackgroundColor[0] == '$'){
+			$defaultHTMLBackgroundColor = self::colorToHtml($defaultBackgroundColor);
+		}
+		
+		$strHtml = '<span class="tmnick_global" style="background-color:'.$defaultHTMLBackgroundColor.'">';
+		$lastLink = false;
+		$lastLinkTag = false;
+		$stack = self::_parse($nick, $defaultColor);
+		foreach($stack as $k => $ss){
+			$lstClass = $lstStyle = array();
+			$prefix = $suffix = '';
+			$preContent = $postContent = '';
+			foreach($ss['tagsOpen'] as $tag => $open){
+				if( (is_string($open) and !empty($open)) or (is_bool($open) and $open) ){
+					if( ($tag == 'h' or $tag == 'p' or $tag == 'l') and $lastLink !== $open ){
+						$scheme = parse_url($open, PHP_URL_SCHEME);
+						if( is_null($scheme) ){
+							if($tag == 'l'){
+								$open = 'http://'.$open;
+							}
+							else if($tag == 'h'){
+								$open = $linkProtocol.':///:'.$open;
+							}
+							else if($tag == 'p'){
+								$open = $linkProtocol.':///:'.$open.'?playerlogin=&lang=&nickname=&path=';
+							}
+						}
+						
+						$prefix .= '<a href="'.$open.'" target="_blank" class="'.self::$m_css[$tag].'">';
+						$lastLinkTag = $tag;
+						$lastLink = $open;
+					}
+					else if($tag == 'color'){
+						if($forcedDefault){
+							$lstStyle[] = 'color:'.$defaultHTMLColor;
+						}
+						else{
+							$lstStyle[] = 'color:'.$open;
+						}
+					}
+					else{
+						$lstClass[] = self::$m_css[$tag];
+					}
+				}
+				else{
+					if($tag == $lastLinkTag and $lastLink !== $open){
+						$prefix .= '</a>';
+						$lastLink = false;
+					}
+				}
+			}
+			
+			$strHtml .= $prefix;
+			if( !empty($ss['content']) ){
+				$strHtml .= '<span class="{$class$}" style="font-size: '.$fontSize.'pt;{$style$}">';
+				$strHtml .= $preContent.'{$content$}'.$postContent;
+				$strHtml .= '</span>';
+			}
+			$strHtml .= $suffix;
+			
+			$strHtml = str_replace('{$content$}', $ss['content'], $strHtml);
+			$strHtml = str_replace('{$class$}', implode(' ', $lstClass), $strHtml);
+			$strHtml = str_replace('{$style$}', implode(';', $lstStyle), $strHtml);
+		}
+		
+		$tags = array('h', 'p', 'l');
+		foreach($tags as $k => $tag){
+			if( isset($ss) and $ss['tagsOpen'][$tag] ){
+				$strHtml .= '</a>';
+			}
+		}
+		
+		$strHtml .= '</span>';
+		
+		return $strHtml;
+	}
+	
+	
+	/**
+	* Affiche une chaine TM en image
+	*
+	* @param string $nick                 -> La chaine TM pas de limite de longueur, et peut être multiligne
+	* @param string $type                 -> Le type de l'image (gif, jpg, jpeg, png, ico, bmp, wbmp, xpm)
+	* @param int    $fontSize             -> Taille de la police
+	* @param bool   $forceDefault         -> Force la couleur par défaut à être utilise à la place de la mise en forme
+	* @param string $defaultColor         -> La couleur par défaut (la couleur peut être au format HTML, nommé, array RGB, ou TM)
+	* @param string $defaultImgBackground -> Le chemin vers l'image de fond si vous en voulez une
+	* @param array  $arrRelativePosition  -> Tableau assoc avec les index 'x' et 'y', donnant la position du texte par rapport au bord gauche et/ou haut de l'image de fond, ces valeur peuvent être négative, dans ce cas la valeur represente la position depuis le bord droite et/ou bas
+	* @return bool
+	*/
+	public static function toImg($nick, $type = 'png', $fontSize = 12, $forceDefault = false, $defaultColor = 'white', $defaultImgBackground = null, $arrRelativePosition = array() ){
+		if(self::_isSupportedImageType($type) === false){
+			$imErr = self::_getErrorRessource('Le type "'.$type.'" n\'est pas supporté.');
+			return self::_getImageFromRessource($imErr, 'png');
+		}
+		
+		$res = true;
+		$nickText = self::toText($nick);
+		
+		$lines = str_replace('\r\n', '\n', $nick);
+		$lines = str_replace('\r', '\n', $lines);
+		$lines = explode('\n', $lines);
+		
+		// this gets the length of the longest string, in characters to determine
+		// the width of the output image
+		$xMax = -1;
+		$len = 0;
+		$count_lines =  count($lines);
+		for($x = 0; $x < $count_lines; $x++){
+			if(strlen($lines[$x]) > $len){
+				$len = strlen(self::toText($lines[$x]));
+				$xMax = $x;
+			}
+		}
+		
+		$defaultRGBColor = self::colorToRGB($defaultColor);
+		
+		$width = $height = 0;
+		
+		// initialization
+		$fontFile = self::$m_fontPath.'FRADMIT.TTF';
+		$box = self::_imagettfbboxextended($fontSize, 0, $fontFile, self::toText($lines[$xMax]));
+		
+		// next we turn the height and width into pixel values
+		$width = $box['width'] * 2;
+		$height = $box['height'] * 2;
+		$baseline = $box['y'];
+		
+		// create image with dimensions to fit text, plus two extra rows and
+		// two extra columns for border
+		$hasBgImd = false;
+		$im = null;
+		if( !is_null($defaultImgBackground) and file_exists($defaultImgBackground) ){
+			$infos = getimagesize($defaultImgBackground);
+			$width = $infos[0];
+			$height = $infos[0];
+			
+			$imgString = file_get_contents($defaultImgBackground);
+			$im = imagecreatefromstring($imgString);
+			$hasBgImd = true;
+		}else{
+			$im = imagecreate($width, $height);
+		}
+		
+		if($im){
+			// image creation success
+			$backColor = imagecolorallocatealpha($im, 254, 254, 254, 127);
+			$shadowColor = imagecolorallocatealpha($im, 105, 105, 105, 0);
+			if(!$hasBgImd){
+				imagefill($im, 0, 0, $backColor);
+			}
+			
+			// this loop outputs the error message to the image
+			// imagestring(image, font, x, y, msg, color);
+			$x = $y = 0;
+			
+			if(is_array($arrRelativePosition) and count($arrRelativePosition) > 0){
+				if( isset($arrRelativePosition['y']) ){
+					if($arrRelativePosition['y'] < 0){
+						$y = $width;
+					}
+					$y += $arrRelativePosition['y'];
+				}
+				if( isset($arrRelativePosition['x']) ){
+					if($arrRelativePosition['x'] < 0){
+						$x = $height;
+					}
+					$x += $arrRelativePosition['x'];
+				}
+			}
+			
+			$newX = 0;
+			$newY = 0;
+			for($i = 0; $i < count($lines); $i++){
+				$stack = self::_parse($lines[$i]);
+				$xl = $x;
+				
+				foreach($stack as $k => $ss){
+					if($forceDefault){
+						$color = $defaultRGBColor;
+					}else{
+						$color = self::colorToRGB($ss['tagsOpen']['color']);
+					}
+					$textColor = imagecolorallocatealpha($im, $color[0], $color[1], $color[2], 0);
+					$fontText = self::$m_fontPath.'FRA';
+					if($ss['tagsOpen']['o'] === true){
+						$fontText .= self::$m_fonts['o'];
+					}else{
+						$fontText .= self::$m_fonts['z'];
+					}
+					foreach($ss['tagsOpen'] as $t => $o){
+						if($o === true and $t != 'o' and $t != 'z'){
+							$fontText .= self::$m_fonts[$t];
+						}
+					}
+					$fontText .= '.TTF';
+					
+					$tbox = self::_imagettfbboxextended($fontSize, 0, $fontText, $ss['content']);
+					
+					if($ss['tagsOpen']['s'] === true){
+						imagettftext($im, $fontSize, 0, $xl + $tbox['x'] + 1, $y + $baseline + ($i * ($tbox['height'] + 5)) + 1, $shadowColor, $fontText, $ss['content']);
+					}
+					imagettftext($im, $fontSize, 0, $xl + $tbox['x'], $y + $baseline + ($i * ($tbox['height'] + 5)), $textColor, $fontText, $ss['content']);
+					
+					$xl += $tbox['width'];
+					
+					if($newX < $xl){
+						$newX = $xl;
+					}
+					if( $newY < ($y + $baseline + ($i * ($tbox['height'] + 5))) + (abs($baseline - $tbox['y'])) ){
+						$newY = ($y + $baseline + ($i * ($tbox['height'] + 5))) + (abs($baseline - $tbox['y']));
+					}
+					if($ss['tagsOpen']['s'] === true){
+						$newX++;
+						$newY++;
+					}
+				}
+			}
+			
+			// now, render your image using your favorite image* function
+			// (imagejpeg, for instance)
+			if(!$hasBgImd){
+				$im2 = imagecreate($newX, $newY);
+				imagecopyresized($im2, $im, 0, 0, 0, 0, $newX, $newY, $newX, $newY);
+				
+				$res = self::_getImageFromRessource($im2, $type);
+				imagedestroy($im2);
+			}else{
+				$res = self::_getImageFromRessource($im, $type);
+			}
+			imagedestroy($im);
+		}else{
+			// image creation failed, so just dump the array along with extra error
+			$error[] = 'Is GD Installed ?';
+			die(var_dump($error));
+		}
+		
+		return $res;
+	}
+	
+	
+	/**
+	* Convertie une chaine TM en text brut
+	*
+	* @param string $nick -> La chaine TM pas de limite de longueur, et peut être multiligne
+	* @return string
+	*/
+	public static function toText($nick){
+		
+		if( !is_string($nick) or empty($nick) ){
+			return '';
+		}
+		
+		$nb = preg_match_all(self::$m_pattern, $nick, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
+		$matches = $matches[0];
+		
+		$strText = '';
+		
+		$lastPos = 0;
+		foreach($matches as $num => $matche){
+			list($code, $pos) = $matche;
+			
+			if($code != '$$'){
+				$strText .= substr($nick, $lastPos, $pos - $lastPos);
+				$lastPos = $pos + strlen($matche[0]);
+			}
+		}
+		
+		$strText .= substr($nick, $lastPos, strlen($nick) - $lastPos);
+		$strText = preg_replace('/(\\[[^\\[\\]]*\\])/', '', $strText);
+		
+		return $strText;
+	}
+	
+	
+	/**
+	* Convertie une couleur au format HTML, TM, array RGB, ou nommé en format HTML
+	*
+	* @param string $color
+	* @return string
+	*/
+	public static function colorToHtml($color){
+		$colorHtml = '#';
+		
+		if( is_string($color) and !empty($color) and strlen($color) == 4 and ($color[0] == '$' or $color[0] == '#') ){
+			$color = preg_replace('/[g-z]/', self::$m_defaultHexaOnError, strtolower($color));
+			$colorHtml .= $color[1];
+			$colorHtml .= $color[1];
+			$colorHtml .= $color[2];
+			$colorHtml .= $color[2];
+			$colorHtml .= $color[3];
+			$colorHtml .= $color[3];
+		}
+		else if(is_array($color) and count($color) == 3){
+			$colorHtml .= sprintf('#%02X%02X%02X', $color[1], $color[2], $color[3]);
+		}
+		else if(is_string($color) and !empty($color) and strlen($color) == 7 and $color[0] == '#'){
+			$color = preg_replace('/[g-z]/', self::$m_defaultHexaOnError, strtolower($color));
+			$colorHtml = $color;
+		}
+		else{
+			$color = strtolower($color);
+			$colorHtml = self::$m_colorNameToHtml[$color];
+		}
+		
+		return $colorHtml;
+	}
+	
+	
+	/**
+	* Convertie une couleur au format HTML, TM, array RGB, ou nommé en format RGB
+	*
+	* @param string $color
+	* @return string
+	*/
+	public static function colorToRGB($color){
+		$colorRGB = array(0, 0, 0);
+		
+		if( is_string($color) and !empty($color) and strlen($color) == 4 and ($color[0] == '$' or $color[0] == '#') ){
+			$color = preg_replace('/[g-z]/', self::$m_defaultHexaOnError, strtolower($color));
+			$hex = $color[1];
+			$hex .= $color[1];
+			$colorRGB[0] = hexdec($hex);
+			$hex = $color[2];
+			$hex .= $color[2];
+			$colorRGB[1] = hexdec($hex);
+			$hex = $color[3];
+			$hex .= $color[3];
+			$colorRGB[2] = hexdec($hex);
+		}
+		else if(is_array($color) and count($color) == 3){
+			$colorRGB = $color;
+		}
+		else if(is_string($color) and !empty($color) and strlen($color) == 7 and $color[0] == '#'){
+			$color = preg_replace('/[g-z]/', self::$m_defaultHexaOnError, strtolower($color));
+			$hex = $color[1];
+			$hex .= $color[2];
+			$colorRGB[0] = hexdec($hex);
+			$hex = $color[3];
+			$hex .= $color[4];
+			$colorRGB[1] = hexdec($hex);
+			$hex = $color[5];
+			$hex .= $color[6];
+			$colorRGB[2] = hexdec($hex);
+		}
+		else{
+			$color = strtolower($color);
+			$colorRGB = self::colorToRGB(self::$m_colorNameToHtml[$color]);
+		}
+		
+		return $colorRGB;
+	}
+	
+	
+	/**
+	* Retourne le code css nécessaire à la mise en forme du code html
+	*
+	* @return string
+	*/
+	public static function getCss(){
+		$css = '<style type="text/css">
+			.tmnick_global {
+				font-style: normal;
+				font-weight: none;
+				letter-spacing: 0;
+			}
+			.tmnick_normal { letter-spacing: 0; }
+			.tmnick_short { letter-spacing: -1px; }
+			.tmnick_wide { letter-spacing: 2px; }
+			.tmnick_raz { font-style: normal; font-weight: none; letter-spacing: 0; }
+			.tmnick_italic { font-style: italic; }
+			.tmnick_bold { font-weight: bold; letter-spacing: 1px; }
+			.tmnick_upper { text-transform: uppercase; }
+			span.tmnick_shadow { text-shadow: 0 1px 1px #333; }
+			.tmnick_shadowed { position: relative; }
+			.tmnick_shadowed span { position: relative; }
+			span.tmnick_shadow { position: absolute; }
+			.tmnick_defaultcolor { }
+			a.tmnick_internallink, a.tmnick_internallink:visited {
+				color: inherit;
+				text-decoration: none;
+				border-bottom: thin solid Black;
+			}
+			a.tmnick_internallink:hover {
+				color: inherit;
+				text-decoration: none;
+				border-bottom: thin solid Blue;
+			}
+			a.tmnick_internallink_withlogin, a.tmnick_internallink_withlogin:visited  {
+				color: inherit;
+				text-decoration: none;
+				border-bottom: thin solid #F0E68C;
+			}
+			a.tmnick_internallink_withlogin:hover {
+				color: inherit;
+				text-decoration: none;
+				border-bottom: thin solid Gold;
+			}
+			a.tmnick_externallink, a.tmnick_externallink:visited {
+				color: inherit;
+				text-decoration: none;
+				border-bottom: thin solid Black;
+			}
+			a.tmnick_externallink:hover {
+				color: inherit;
+				text-decoration: none;
+				border-bottom: thin solid Orange;
+			}
+		</style>';
+		
+		return $css;
+	}
+	
+	
+	/**
+	* Enlève tous les codes de trackmania
+	*
+	* @param string $str   -> Texte à traiter
+	* @param array $select -> Un ou plusieurs codes à enlever. Par exemple, si on veut enlever seulement le code "$s"
+	* @return string texte sans codes $s, $o, etc ...
+	*/
+	public static function stripNadeoCode($str, $select = array() ){
+		if( !empty($select) ){
+			$stripNadeoCode = $select;
+		}
+		else{
+			$stripNadeoCode = array('$w', '$W', '$n', '$N', '$o', '$O', '$i', '$I', '$t', '$T', '$s', '$S', '$g', '$G', '$z', '$Z', '$<');
+		}
+		
+		return str_ireplace($stripNadeoCode, '', $str);
+	}
+	
+	
+	/**
+	* Parse une chaine TM dans une structure de donnée interne utilisé par les méthode toHtml, toImg, et toText
+	*
+	* @param string $nick la chaine TM pas de limite de longueur, et peut être multiligne
+	* @param string $defaultColor la couleur par défaut (la couleur peut être au format HTML, nommé, array RGB, ou TM)
+	* @return array
+	*/
+	private static function _parse($nick, $defaultColor = 'white'){
+		
+		if( !is_string($nick) or empty($nick) ){
+			return array();
+		}
+		
+		$defaultHTMLColor = $defaultColor;
+		if( empty($defaultColor) ){
+			$defaultHTMLColor = 'white';
+		}
+		else if($defaultColor[0] == '$'){
+			$defaultHTMLColor = self::colorToHtml($defaultColor);
+		}
+		
+		$nb = preg_match_all(self::$m_pattern, $nick, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
+		$matches = $matches[0];
+		
+		$strContent = '';
+		$lastPos = 0;
+		
+		$tagsOpen = array(
+			'h' => false,
+			'p' => false,
+			'l' => false,
+			'o' => false,
+			'g' => false,
+			't' => false,
+			'w' => false,
+			'm' => false,
+			'n' => false,
+			'i' => false,
+			's' => false,
+			'color' => $defaultColor
+		);
+		
+		$stack = array();
+		foreach($matches as $num => $matche){
+			list($code, $pos) = $matche;
+			
+			$tag = strtolower(substr($code, 1));
+			$param = null;
+			if(strlen($tag) == 3){
+				// color
+				$param = $tag;
+				$tag = 'color';
+			}
+			
+			if( !in_array($tag, self::$m_lstTags) ){
+				continue;
+			}
+			
+			$strContent = substr($nick, $lastPos, $pos - $lastPos);
+			if( !empty($strContent) ){
+				array_push($stack, array('content' => $strContent, 'tagsOpen' => $tagsOpen));
+			}
+			
+			switch($tag){
+				// raz (close)
+				case 'z':
+					$tagsOpen = array_merge($tagsOpen,
+						array(
+							'o' => false,
+							'g' => false,
+							't' => false,
+							'w' => false,
+							'm' => false,
+							'n' => false,
+							'i' => false,
+							's' => false,
+							'color' => $defaultColor
+						)
+					);
+					break;
+				
+				// defaultcolor (close)
+				case 'g':
+					$tagsOpen['color'] = $defaultColor;
+					break;
+				
+				// internal link (open)
+				case 'h':
+				// internal link with login (open)
+				case 'p':
+				// external link (open)
+				case 'l':
+					if(!$tagsOpen[$tag]){
+						// open
+						$tagsOpen[$tag] = true;
+					}
+					else{
+						// close
+						$strLink = '';
+						$i = count($stack) - 1;
+						while($i >= 0 and $stack[$i]['tagsOpen'][$tag]){
+							$strLink = $stack[$i]['content'] . $strLink;
+							$i--;
+						}
+						
+						$url = null;
+						$nb = preg_match(self::$m_patternLink, $strLink, $regs, PREG_OFFSET_CAPTURE);
+						
+						if( !empty($regs['label'][0]) ){
+							if( empty($regs['url'][0]) ){
+								$url = $regs['label'][0];
+							}else{
+								$url = $regs['url'][0];
+							}
+						}
+						
+						$nb = count($stack) - 1;
+						$lastMax = strlen($strLink);
+						for($j = $nb; $j >= ($i+1); $j--){
+							if( !is_null($url) ){
+								$subLabel = $stack[$j]['content'];
+								$max = max($lastMax - strlen($subLabel), $regs['label'][1]);
+								$subLabel = substr($strLink, $max, $lastMax - $max);
+								$lastMax = $max;
+								$stack[$j]['content'] = $subLabel;
+								
+								$stack[$j]['tagsOpen'][$tag] = $url;
+							}else{
+								// poubelle
+								unset($stack[$j]);
+							}
+						}
+						
+						$tagsOpen[$tag] = false;
+					}
+					break;
+					
+				// shadow (open)
+				case 's':
+				// upper
+				case 't':
+				// bold
+				case 'o':
+				// italic
+				case 'i':
+					if(!$tagsOpen[$tag]){
+						// open
+						$tagsOpen[$tag] = true;
+					}else{
+						// close
+						$tagsOpen[$tag] = false;
+					}
+					break;
+				
+				// wide (open)
+				case 'w':
+				// normal (open)
+				case 'm':
+				// short (open)
+				case 'n':
+					if(!$tagsOpen[$tag]){
+						// open
+						$tagsOpen['w'] = false;
+						$tagsOpen['m'] = false;
+						$tagsOpen['n'] = false;
+						$tagsOpen[$tag] = true;
+					}else{
+						// close
+						$tagsOpen[$tag] = false;
+					}
+					break;
+				
+				case 'color':
+					// color (open)
+					$tagsOpen[$tag] = self::colorToHtml($code);
+					break;
+				
+				default:
+					$stack[(count($stack) - 1)]['content'] .= $code;
+					break;
+			}
+			
+			foreach($stack as $s => $st){
+				if( empty($st['content']) ){
+					unset($stack[$s]);
+				}
+			}
+			
+			$lastPos = $pos + strlen($matche[0]);
+		}
+		
+		$strContent = substr($nick, $lastPos);
+		if( !empty($strContent) ){
+			array_push($stack, array('content' => $strContent, 'tagsOpen' => $tagsOpen));
+		}
+		
+		$tags = array('h', 'p', 'l');
+		foreach($tags as $k => $tag){
+			if($tagsOpen[$tag]){
+				// close
+				$strLink = '';
+				$i = count($stack) - 1;
+				while($i >= 0 and $stack[$i]['tagsOpen'][$tag]){
+					$strLink = $stack[$i]['content'] . $strLink;
+					$i--;
+				}
+				
+				$url = null;
+				$nb = preg_match(self::$m_patternLink, $strLink, $regs, PREG_OFFSET_CAPTURE);
+				
+				if(!empty($regs['label'][0]) ){
+					if(empty($regs['url'][0]) ){
+						$url = $regs['label'][0];
+					}else{
+						$url = $regs['url'][0];
+					}
+				}
+				
+				$nb = count($stack) - 1;
+				$lastMax = strlen($strLink);
+				for($j = $nb; $j >= ($i+1); $j--){
+					if( !is_null($url) ){
+						$subLabel = $stack[$j]['content'];
+						$max = max($lastMax - strlen($subLabel), $regs['label'][1]);
+						$subLabel = substr($strLink, $max, $lastMax - $max);
+						$lastMax = $max;
+						$stack[$j]['content'] = $subLabel;
+						
+						$stack[$j]['tagsOpen'][$tag] = $url;
+					}else{
+						// poubelle
+						unset($stack[$j]);
+					}
+				}
+				
+				$tagsOpen[$tag] = false;
+			}
+		}
+		
+		return $stack;
+	}
+	
+	
+	/**
+	* This function extends imagettfbbox and includes within the returned array
+	* the actual text width and height as well as the x and y coordinates the
+	* text should be drawn from to render correctly.  This currently only works
+	* for an angle of zero and corrects the issue of hanging letters e.g. jpqg
+	*
+	* @param float $size
+	* @param float $angle
+	* @param string $fontfile
+	* @param string $text
+	* @return array
+	*/
+	private static function _imagettfbboxextended($size, $angle, $fontfile, $text){
+		$bbox = imagettfbbox($size, $angle, $fontfile, $text);
+	
+		//calculate x baseline
+		if($bbox[0] >= -1){
+			$bbox['x'] = abs($bbox[0] + 1) * -1;
+		}else{
+			//$bbox['x'] = 0;
+			$bbox['x'] = abs($bbox[0] + 2);
+		}
+	
+		//calculate actual text width
+		$bbox['width'] = abs($bbox[2] - $bbox[0]);
+		if($bbox[0] < -1){
+			$bbox['width'] = abs($bbox[2]) + abs($bbox[0]) - 1;
+		}
+		
+		//caculate y baseline
+		$bbox['y'] = abs($bbox[5] + 1);
+		
+		//calculate actaul text height
+		$bbox['height'] = abs($bbox[7]) - abs($bbox[1]);
+		if($bbox[3] > 0){
+			$bbox['height'] = abs($bbox[7] - $bbox[1]) - 1;
+		}
+		
+		return $bbox;
+	}
+	
+	
+	/**
+	* Construit une ressource d'image d'erreur affcihant toute les erreur de $errors
+	*
+	* @param mixed $errors string of error or array of string of error
+	* @return ressource
+	*/
+	private static function _getErrorRessource($errors){
+		// $error is an array of error messages, each taking up one line
+		if( is_string($errors) ){
+			$errors = str_replace('\r\n', '\n', $errors);
+			$errors = str_replace('\r', '\n', $errors);
+			$errors = explode('\n', $errors);
+		}
+		
+		$error = array();
+		foreach($errors as $k => $err){
+			$err = str_replace('\r\n', '\n', $err);
+			$err = str_replace('\r', '\n', $err);
+			$error = array_merge($error, explode('\n', $err));
+		}
+		
+		// initialization
+		$fontSize = 12;
+		
+		// this gets the length of the longest string, in characters to determine
+		// the width of the output image
+		$xMax = -1;
+		$len = 0;
+		for($x = 0; $x < count($error); $x++){
+			if(strlen($error[$x]) > $len){
+				$len = strlen($error[$x]);
+				$xMax = $x;
+			}
+		}
+		
+		$fontFile = self::$m_fontPath.'FRAMD.TTF';
+		$box = imagettfbbox($fontSize, 0, $fontFile, $error[$xMax]);
+		
+		// next we turn the height and width into pixel values
+		$width = abs($box[2] - $box[0]);
+		$textHeight = abs($box[1] - $box[7]);
+		$height = ($textHeight + 2) * count($error);
+		
+		$im = imagecreate($width, $height);
+		
+		if($im){
+			// image creation success
+			$textColor = imagecolorallocatealpha($im, 255, 0, 0, 0);
+			$backColor = imagecolorallocatealpha($im, 255, 255, 255, 127);
+			imagefill($im, 0, 0, $backColor);
+			// this loop outputs the error message to the image
+			for($y = 0; $y < count($error); $y++){
+				// imagestring(image, font, x, y, msg, color);
+				imagettftext($im, $fontSize, 0, 0, ($textHeight + 5) * $y + $textHeight, $textColor, $fontFile, $error[$y]);
+			}
+			// now, render your image using your favorite image* function
+			// (imagejpeg, for instance)
+			return $im;
+		}else{
+			// image creation failed, so just dump the array along with extra error
+			$error[] = "Is GD Installed?";
+			die(var_dump($error));
+		}
+	}
+	
+	
+	/**
+	* Détermine si le type passé est supporté
+	*
+	* @param string $type type supporté (gif, jpg, jpeg, png, ico, bmp, wbmp, xpm)
+	* @return bool
+	*/
+	private static function _isSupportedImageType($type){
+		$type = strtoupper($type);
+		switch($type){
+			case 'GIF':
+				return IMG_GIF;
+				break;
+			case 'JPG':
+				return IMG_JPG;
+				break;
+			case 'JPEG':
+				return IMG_JPEG;
+				break;
+			case 'PNG':
+				return IMG_PNG;
+				break;
+			case 'ICO':
+			case 'BMP':
+			case 'WBMP':
+				return IMG_WBMP;
+				break;
+			case 'XPM':
+				return IMG_XPM;
+				break;
+			default:
+				return false;
+				break;
+		}
+	}
+	
+	
+	/**
+	* Affiche l'image correspondant à la ressource dans le format souhaité
+	*
+	* @param ressource $im ressource de l'image
+	* @param string $type type de l'image de sortie
+	* @return bool
+	*/
+	private static function _getImageFromRessource($im, $type){
+		if( ($imgtype = self::_isSupportedImageType($type)) !== false ){
+			header('Content-type:'.image_type_to_mime_type($imgtype).';');
+			switch($imgtype){
+				case IMG_GIF:
+					return imagegif($im);
+					break;
+				case IMG_JPG:
+				case IMG_JPEG:
+					return imagejpeg($im);
+					break;
+				case IMG_PNG:
+					return imagepng($im);
+					break;
+				case IMG_WBMP:
+					return imagewbmp($im);
+					break;
+				case IMG_XPM:
+					return imagexbm($im);
+					break;
+			}
+		}
+		header('Content-type:'.image_type_to_mime_type(IMG_PNG).';');
+		return imagepng(self::_getErrorRessource('Le format "'.$type.'" n\'est pas supporté.'));
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/class/upload.class.php b/resources/class/upload.class.php
new file mode 100644
index 0000000..3404bbc
--- /dev/null
+++ b/resources/class/upload.class.php
@@ -0,0 +1,580 @@
+<?php
+/**
+* CLASS UPLOAD
+*
+* Traite l'envoi de fichier en local ou FTP
+*
+* @example:
+*         $path = '/';
+*         $replaceOldFile = false;
+*         $allowedExtensions = array('jpg', 'png', 'gif');
+*         $sizeLimit = 4 * 1024 * 1024;
+*     LOCAL:
+*         echo FileUploader::saveUploadedFile($path, $replaceOldFile, $allowedExtensions, $sizeLimit);
+*     FTP:
+*         echo FileUploader::saveUploadedFileToFTP($ftp_stream, $path, $replaceOldFile, $allowedExtensions, $sizeLimit);
+*/
+
+
+/**
+* Permet de traiter le fichier envoyé par XHR (XMLHttpRequest)
+*/
+class UploadedFileXhr {
+	
+	/**
+	* Enregistre le fichier en local
+	*
+	* @param string $path -> Le chemin complet du fichier avec le filename
+	* @return bool true si réussi
+	*/
+	public function save($path){
+		$out = null;
+		
+		// Ouverture du flux "input" de PHP et création d'un fichier temp
+		$input = fopen("php://input", "r");
+		$temp = tmpfile();
+		$realSize = stream_copy_to_stream($input, $temp);
+		fclose($input);
+		if( $realSize != $this->getSize() ){
+			$out = false;
+		}
+		
+		// Création du fichier final
+		$target = fopen($path, "w");
+		fseek($temp, 0, SEEK_SET);
+		if( stream_copy_to_stream($temp, $target) > 0 ){
+			$out = true;
+		}
+		fclose($target);
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Enregistre le fichier sur un serveur FTP
+	*
+	* @param resource $ftp_stream -> La ressource de connexion FTP
+	* @param string   $path       -> Le chemin complet du dossier de destination
+	* @param string   $filename   -> Le nom du fichier
+	* @return true si réussi, sinon false
+	*/
+	public function saveFTP($ftp_stream, $path, $filename){
+		$out = null;
+		
+		// Ouverture du flux "input" de PHP et création d'un fichier temp
+		$input = fopen("php://input", "r");
+		$temp = tmpfile();
+		$realSize = stream_copy_to_stream($input, $temp);
+		fclose($input);
+		if( $realSize != $this->getSize() ){
+			$out = false;
+		}
+		
+		// Enregistre le fichier sur le FTP
+		fseek($temp, 0, SEEK_SET);
+		$out = ftp_fput($ftp_stream, $path.$filename, $temp, FTP_BINARY);
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Écrit la map dans le dossier "Maps" via le serveur
+	*
+	* @param resource $client   -> La ressource du client GbxRemote
+	* @param string   $filename -> Le chemin vers le fichier à partir du dossier "Maps"
+	*/
+	public function writeMap($client, $filename){
+		$out = true;
+		
+		// Ouverture du flux "input" de PHP et création d'un fichier temp
+		$input = fopen("php://input", "r");
+		$temp = tmpfile();
+		$realSize = stream_copy_to_stream($input, $temp);
+		fclose($input);
+		if( $realSize != $this->getSize() ){
+			$out = false;
+		}
+		if($out != false){
+			fseek($temp, 0, SEEK_SET);
+			$file = stream_get_contents($temp);
+			$str64 = new IXR_Base64($file);
+			
+			if( !$client->query('WriteFile', $filename, $str64) ){
+				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Ajoute ou insert une map à la liste du serveur
+	*
+	* @param resource $client   -> La ressource du client GbxRemote
+	* @param string   $filename -> Le chemin vers le fichier
+	* @param array    $queries  -> Requêtes à executer et le type d'ajout à la liste: array('insert' => 'InsertMap', 'add' => 'AddMap', 'type' => 'add')
+	* @return true si réussi, sinon erreur texte
+	*/
+	public function saveMap($client, $filename, $queries){
+		$out = true;
+		
+		if($queries['type'] == 'insert'){
+			if( !$client->query($queries['insert'], $filename) ){
+				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+			}
+		}
+		else{
+			if( !$client->query($queries['add'], $filename) ){
+				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le nom du fichier
+	*/
+	public function getName(){
+		return $_GET['qqfile'];
+	}
+	
+	
+	/**
+	* Récupère la taille du fichier
+	*/
+	public function getSize(){
+		if( isset($_SERVER['CONTENT_LENGTH']) ){
+			return (int)$_SERVER['CONTENT_LENGTH'];            
+		}
+		else{
+			throw new Exception('Getting content length is not supported.');
+		}
+	}
+}
+
+
+/**
+* Permet de traiter le fichier envoyé par Formulaire HTML (array $_FILES)
+*/
+class UploadedFileForm {
+	
+	/**
+	* Enregistre le fichier en local
+	*
+	* @param string $path -> Le chemin complet du fichier avec le filename
+	* @return bool true si réussi, sinon false
+	*/
+	public function save($path){
+		if( !move_uploaded_file($_FILES['qqfile']['tmp_name'], $path) ){
+			return false;
+		}
+		return true;
+	}
+	
+	
+	/**
+	* Enregistre le fichier sur un serveur FTP
+	*
+	* @param resource $ftp_stream -> La ressource de connexion FTP
+	* @param string   $path       -> Le chemin complet du dossier de destination
+	* @param string   $filename   -> Le nom du fichier
+	* @return true si réussi, sinon false
+	*/
+	public function saveFTP($ftp_stream, $path, $filename){
+		return ftp_put($ftp_stream, $path.$filename, $_FILES['qqfile']['tmp_name'], FTP_BINARY);
+	}
+	
+	
+	/**
+	* Écrit la map dans le dossier "Maps" via le serveur
+	*
+	* @param resource $client   -> La ressource du client GbxRemote
+	* @param string   $filename -> Le chemin vers le fichier
+	*/
+	public function writeMap($client, $filename){
+		$out = true;
+		$str = file_get_contents($_FILES['qqfile']['tmp_name']);
+		$str64 = new IXR_Base64($str);
+		
+		if( !$client->query('WriteFile', $filename, $str64) ){
+			$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage().'opuet';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Ajoute ou insert une map à la liste du serveur
+	*
+	* @param resource $client   -> La ressource du client GbxRemote
+	* @param string   $filename -> Le chemin vers le fichier
+	* @param array    $queries           -> Requêtes à executer et le type d'ajout à la liste: array('insert' => 'InsertMap', 'add' => 'AddMap', 'type' => 'add')
+	* @return true si réussi, sinon erreur texte
+	*/
+	public function saveMap($client, $filename, $queries){
+		$out = true;
+		
+		if($queries['type'] == 'insert'){
+			if( !$client->query($queries['insert'], $filename) ){
+				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage().'insert';
+			}
+		}
+		else{
+			if( !$client->query($queries['add'], $filename) ){
+				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage().'add';
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le nom du fichier
+	*/
+	public function getName(){
+		return $_FILES['qqfile']['name'];
+	}
+	
+	
+	/**
+	* Récupère la taille du fichier
+	*/
+	public function getSize(){
+		return $_FILES['qqfile']['size'];
+	}
+}
+
+
+/**
+* Permet de gérer l'enregistrement du fichier uploadé par XHR ou Formulaire
+*/
+class FileUploader {
+	private $allowedExtensions = array();
+	private $sizeLimit = 10485760;
+	private $file;
+	
+	function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){   
+		// Ecrase les paramètres dans les variables de config
+		$allowedExtensions = array_map("strtolower", $allowedExtensions);
+		$this->allowedExtensions = $allowedExtensions;
+		$this->sizeLimit = $sizeLimit;
+		
+		// Test si le serveur peut accepter la config
+		$this->_checkServerSettings();
+		
+		// Test si il y a bien un fichier, si oui, on selectionne le type d'enregistrement (XHR ou Formulaire)
+		if( isset($_GET['qqfile']) ){
+			$this->file = new uploadedFileXhr();
+		}
+		else if( isset($_FILES['qqfile']) ){
+			$this->file = new uploadedFileForm();
+		}
+		else{
+			$this->file = false; 
+		}
+	}
+	
+	
+	/**
+	* Vérifie si le serveur peut accepter la taille max configurée
+	*/
+	private function _checkServerSettings(){
+		$postSize = $this->_toBytes( ini_get('post_max_size') );
+		$uploadSize = $this->_toBytes( ini_get('upload_max_filesize') );
+		
+		if( $postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit ){
+			$size = max(1, $this->sizeLimit / 1024 / 1024) . 'Mo';
+			die("{'error':'increase post_max_size and upload_max_filesize to $size'}");    
+		}
+	}
+	
+	
+	/**
+	* Convertie les Go, Mo ou Ko du php.ini en octets
+	*/
+	private function _toBytes($str){
+		$val = trim($str);
+		$last = strtolower($str[strlen($str)-1]);
+		switch($last){
+			case 'g': $val *= 1024;
+			case 'm': $val *= 1024;
+			case 'k': $val *= 1024;
+		}
+		return $val;
+	}
+	
+	
+	/**
+	* Enregistre le fichier envoyé dans un dossier
+	*
+	* @param string   $uploadDirectory  -> Le chemin du dossier de destination
+	* @param bool     $replaceOldFile   -> Remplacement des anciens fichiers qui ont le même nom ? Non par défaut
+	* @param function $filenameFunction -> La fonction de traitement du filename
+	* @return array('success' => true) ou array('error' => 'error message')
+	*/
+	public function handleUpload($uploadDirectory, $replaceOldFile = false, $filenameFunction = null){
+		// Si on peut écrire dans le dossier de destination
+		if( !is_writable($uploadDirectory) ){
+			return array('error' => Utils::t('Server error. The upload destination folder isn\'t writable.'));
+		}
+		
+		// Si il y a bien un fichier envoyé
+		if( !$this->file ){
+			return array('error' => Utils::t('No file was uploaded'));
+		}
+		
+		// Récuperation de la taille du fichier et test si il n'est pas vide ou supérieur à la taille configurée
+		$size = $this->file->getSize();
+		if($size === 0){
+			return array('error' => Utils::t('The file is empty.'));
+			return array('error' => Utils::t('The file is empty.'));
+		}
+		if($size > $this->sizeLimit){
+			return array('error' => Utils::t('The file size is too large.'));
+		}
+		
+		// Récuperation du nom et de l'extension du fichier pour tester si l'extension est valide et si le nom du fichier n'existe pas déjà
+		$pathinfo = pathinfo( $this->file->getName() );
+		if($filenameFunction != null){
+			$filename = $filenameFunction($pathinfo['filename']);
+		}
+		else{
+			$filename = $pathinfo['filename'];
+		}
+		$ext = $pathinfo['extension'];
+		if( $this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions) ){
+			$these = implode(', ', $this->allowedExtensions);
+			return array('error' => Utils::t('The file has invalid extension (allowed extensions:').' '.$these.').');
+		}
+		if( !$replaceOldFile ){
+			// Pour chaque fichier, on test si il existe, si oui, on rajoute un nombre aléatoire de 10 à 99
+			while( file_exists($uploadDirectory . $filename . '.' . $ext) ){
+				$filename .= rand(10, 99);
+			}
+		}
+		
+		// Enregistrement du fichier
+		if( $this->file->save($uploadDirectory . $filename . '.' . $ext) ){
+			return array('success' => true);
+		}
+		else{
+			return array('error' => Utils::t('The file was not uploaded. Upload has been cancelled or a server error occurred.'));
+		}
+	}
+	
+	
+	/**
+	* Enregistre le fichier envoyé dans un dossier sur un serveur FTP
+	*
+	* @param resource $ftp_stream       -> La ressource de connexion FTP
+	* @param string   $uploadDirectory  -> Le chemin du dossier de destination
+	* @param bool     $replaceOldFile   -> Remplacement des anciens fichiers qui ont le même nom ? Non par défaut
+	* @param function $filenameFunction -> La fonction de traitement du filename
+	* @return array('success' => true) ou array('error' => 'error message')
+	*/
+	public function handleUploadFTP($ftp_stream, $uploadDirectory, $replaceOldFile = false, $filenameFunction = null){
+		// Si on peut écrire dans le dossier de destination
+		if( ! @ftp_chdir($ftp_stream, $uploadDirectory) ){
+			return array('error' => Utils::t('Server error. The upload destination folder isn\'t writable.'));
+		}
+		
+		// Si il y a bien un fichier envoyé
+		if( !$this->file ){
+			return array('error' => Utils::t('No file was uploaded'));
+		}
+		
+		// Récuperation de la taille du fichier et test si il n'est pas vide ou supérieur à la taille configurée
+		$size = $this->file->getSize();
+		if($size === 0){
+			return array('error' => Utils::t('The file is empty.'));
+		}
+		if($size > $this->sizeLimit){
+			return array('error' => Utils::t('The file size is too large.'));
+		}
+		
+		// Récuperation du nom et de l'extension du fichier pour tester si l'extension est valide et si le nom du fichier n'existe pas déjà
+		$pathinfo = pathinfo( $this->file->getName() );
+		if($filenameFunction != null){
+			$filename = $filenameFunction($pathinfo['filename']);
+		}
+		else{
+			$filename = $pathinfo['filename'];
+		}
+		$ext = $pathinfo['extension'];
+		if( $this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions) ){
+			$these = implode(', ', $this->allowedExtensions);
+			return array('error' => Utils::t('The file has invalid extension (allowed extensions:').' '.$these.').');
+		}
+		
+		// Si il ne faut pas remplacer les anciens fichiers
+		if( !$replaceOldFile ){
+			// Fonction pour vérifier si le fichier existe sur le FTP
+			function ftp_file_exists($ftp_stream, $uploadDirectory, $filename){
+				$files = ftp_nlist($ftp_stream, $uploadDirectory);
+				if( count($files) > 0){
+					foreach($files as $file){
+						if($uploadDirectory.$filename == $file){
+							return true;
+						}
+					}
+				}
+				return false;
+			}
+			// Pour chaque fichier, on test si il existe, si oui, on rajoute un nombre aléatoire de 10 à 99
+			while( ftp_file_exists($ftp_stream, $uploadDirectory, $filename.'.'.$ext) ){
+				$filename .= rand(10, 99);
+			}
+		}
+		
+		// Enregistrement du fichier
+		if( $this->file->saveFTP($ftp_stream, $uploadDirectory, $filename.'.'.$ext) ){
+			return array('success' => true);
+		}
+		else{
+			return array('error' => Utils::t('The file was not uploaded. Upload has been cancelled or a server error occurred.'));
+		}
+	}
+	
+	
+	/**
+	* Enregistre le fichier envoyé dans un dossier sur un serveur Maniaplanet
+	*
+	* @param resource $client           -> La ressource du client XMLRPC
+	* @param string   $uploadDirectory  -> Le chemin du dossier de destination
+	* @param bool     $replaceOldFile   -> Remplacement des anciens fichiers qui ont le même nom ? Non par défaut
+	* @param function $filenameFunction -> La fonction de traitement du filename
+	* @return array('success' => true) ou array('error' => 'error message')
+	*/
+	public function handleUploadManiaPlanetServer($client, $uploadDirectory, $queries, $filenameFunction = null){
+		// Si le client est initialisé
+		if (!$client->socket || $client->protocol == 0) {
+			return array('error' => Utils::t('Client not initialized'));
+		}
+		
+		// Si il y a bien un fichier envoyé
+		if( !$this->file ){
+			return array('error' => Utils::t('No file was uploaded'));
+		}
+		
+		// Récuperation de la taille du fichier et test si il n'est pas vide ou supérieur à la taille configurée
+		$size = $this->file->getSize();
+		if($size === 0){
+			return array('error' => Utils::t('The file is empty.'));
+		}
+		if($size > $this->sizeLimit){
+			return array('error' => Utils::t('The file size is too large.'));
+		}
+		
+		// Récuperation du nom et de l'extension du fichier pour tester si l'extension est valide et si le nom du fichier n'existe pas déjà
+		$pathinfo = pathinfo( $this->file->getName() );
+		if($filenameFunction != null){
+			$filename = $filenameFunction($pathinfo['filename']);
+		}
+		else{
+			$filename = $pathinfo['filename'];
+		}
+		$ext = $pathinfo['extension'];
+		if( $this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions) ){
+			return array('error' => Utils::t('The file has invalid extension (allowed extensions:').' '.implode(', ', $this->allowedExtensions).').');
+		}
+		
+		// Enregistrement du fichier
+		$error = false;
+		$pathToFile = $uploadDirectory.$filename.'.'.$ext;
+		if( file_exists($uploadDirectory) ){
+			if( ($result = $this->file->save($pathToFile)) !== true ){
+				$error = true;
+			}
+		}
+		else{
+			if( ($result = $this->file->writeMap($client, $pathToFile)) !== true ){
+				$error = true;
+			}
+		}
+		
+		if(!$error){
+			// Ajout/insert la map
+			if( isset($_GET['type']) && $_GET['type'] != 'local' ){
+				$out = $this->file->saveMap($client, $pathToFile, $queries);
+			}
+			// Envoi local seulement
+			else{
+				$out = true;
+			}
+		}
+		else{
+			// Erreur des fonctions save ou writeMap
+			if($result){
+				$out = $result;
+			}
+			else{
+				$out = 'write error';
+			}
+		}
+		
+		if($out === true){
+			return array('success' => true, 'out' => $out);
+		}
+		else{
+			return array('error' => Utils::t('The file was not uploaded. Upload has been cancelled or a server error occurred.').' ('.$out.')');
+		}
+	}
+	
+	
+	/**
+	* Enregistre le fichier envoyé en local
+	*
+	* @param string   $uploadDirectory   -> Le chemin du dossier de destination
+	* @param bool     $replaceOldFile    -> Remplacement des anciens fichiers qui ont le même nom ? Non par défaut
+	* @param array    $allowedExtensions -> Les extensions autorisées : array('jpg', 'png', 'gif');
+	* @param int      $sizeLimit         -> La taille limite d'envoi (égale ou inférieure à la configuration de PHP)
+	* @param function $filenameFunction  -> La fonction de traitement du filename
+	* @return array('success' => true) ou array('error' => 'error message')
+	*/
+	public static function saveUploadedFile($uploadDirectory, $replaceOldFile = false, $allowedExtensions = array(), $sizeLimit = 10485760, $filenameFunction = null){
+		$uploader = new FileUploader($allowedExtensions, $sizeLimit);
+		return $uploader->handleUpload($uploadDirectory, $replaceOldFile, $filenameFunction);
+	}
+	
+	
+	/**
+	* Enregistre le fichier envoyé sur un serveur FTP
+	*
+	* @param resource $ftp_stream        -> La ressource de connexion FTP
+	* @param string   $uploadDirectory   -> Le chemin du dossier de destination
+	* @param bool     $replaceOldFile    -> Remplacement des anciens fichiers qui ont le même nom ? Non par défaut
+	* @param array    $allowedExtensions -> Les extensions autorisées : array('jpg', 'png', 'gif');
+	* @param int      $sizeLimit         -> La taille limite d'envoi (égale ou inférieure à la configuration de PHP)
+	* @param function $filenameFunction  -> La fonction de traitement du filename
+	* @return array('success' => true) ou array('error' => 'error message')
+	*/
+	public static function saveUploadedFileToFTP($ftp_stream, $uploadDirectory, $replaceOldFile = false, $allowedExtensions = array(), $sizeLimit = 10485760, $filenameFunction = null){
+		$uploader = new FileUploader($allowedExtensions, $sizeLimit);
+		return $uploader->handleUploadFTP($ftp_stream, $uploadDirectory, $replaceOldFile, $filenameFunction);
+	}
+	
+	
+	/**
+	* Enregistre le fichier envoyé sur un serveur dédié Maniaplanet
+	*
+	* @param resource $client            -> La ressource du client XMLRPC
+	* @param string   $uploadDirectory   -> Le chemin du dossier de destination
+	* @param array    $queries           -> Requêtes à executer et le type d'ajout à la liste: array('insert' => 'InsertMap', 'add' => 'AddMap', 'type' => 'add')
+	* @param array    $allowedExtensions -> Les extensions autorisées : array('jpg', 'png', 'gif');
+	* @param int      $sizeLimit         -> La taille limite d'envoi (égale ou inférieure à la configuration de PHP)
+	* @param function $filenameFunction  -> La fonction de traitement du filename
+	* @return array('success' => true) ou array('error' => 'error message')
+	*/
+	public static function saveUploadedFileToManiaPlanetServer($client, $uploadDirectory, $queries, $allowedExtensions = array(), $sizeLimit = 10485760, $filenameFunction = null){
+		$uploader = new FileUploader($allowedExtensions, $sizeLimit);
+		return $uploader->handleUploadManiaPlanetServer($client, $uploadDirectory, $queries, $filenameFunction);
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/class/utils.class.php b/resources/class/utils.class.php
new file mode 100644
index 0000000..70420db
--- /dev/null
+++ b/resources/class/utils.class.php
@@ -0,0 +1,301 @@
+<?php
+/*
+* Classe utilitaire générale
+*/
+abstract class Utils {
+	
+	/**
+	* Redirection
+	*
+	* @param bool   $auto  -> Mode automatique, redirige vers la page en cours
+	* @param string $page  -> Page à rediriger
+	* @param int    $sleep -> Temps en seconde à attendre avec d'exécuter la redirection
+	*/
+	public static function redirection($auto = true, $page = null, $sleep = 0){
+		if( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != null){ $protocol = 'https'; }
+		else{ $protocol = 'http'; }
+		$host = $_SERVER['HTTP_HOST'];
+		$uri  = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
+		if($auto){
+			$page = basename($_SERVER['PHP_SELF']);
+			if($page == 'index.php'){
+				$page = null;
+			}
+		}
+		
+		// Redirection
+		if($sleep !== 0){
+			header("Refresh: $sleep; URL=$protocol://$host$uri/$page");
+		}
+		else{
+			header("Location: $protocol://$host$uri/$page");
+		}
+		exit;
+	}
+	
+	
+	/**
+	* Remplace une url texte en url cliquable
+	*
+	* @param string $str -> La chaine de caractères contenant une ou plusieurs url
+	* @param bool $bbcode -> Convertit en HTML par defaut, true pour le BBcode
+	* @return la chaine de caractères avec les url remplacées
+	*/
+	public static function replaceTextURL($str, $bbcode = false){
+		$regex = '$(?:https?|ftp)://(?:www\.|ssl\.)?[a-z0-9._%-]+(?:/[a-z0-9._/%-]*(?:\?[a-z0-9._/%-]+=[a-z0-9._/%+-]+(?:&(?:amp;)?[a-z0-9._/%-]+=[a-z0-9._/%+-]+)*)?)?(?:#[a-z0-9._-]*)?$i';
+		
+		if($bbcode){
+			$code = '[url]$0[/url]';
+		}
+		else{
+			$code = '<a href="$0">$0</a>';
+		}
+		
+		return preg_replace($regex, $code, $str);
+	}
+	
+	
+	/**
+	* Vérifie si l'adresse email est dans un format valide
+	*
+	* @param string $email -> L'adresse email à tester
+	* @return bool
+	*/
+	public static function isValidEmail($email){
+		$out = false;
+		$regex = '#^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,5}$#';
+		
+		if( preg_match($regex, $email) ){
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Vérifie si le numero de téléphone est dans un format valide
+	*
+	* @param string $tel -> Le numero de téléphone à tester
+	* @return bool
+	*/
+	public static function isValidTel($tel){
+		$out = false;
+		$regex = '#^0[0-9]([ .-]?[0-9]{2}){4}$#';
+		
+		if( preg_match($regex, $tel) ){
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne l'image du Captcha
+	*
+	* @require showcaptcha.php dans un dossier "./includes/captcha/"
+	*/
+	public static function showCaptcha(){
+		// Chaine de caractères pour créer le code
+		$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
+		$code = null;
+		for($i = 0; $i < 4; $i++) {
+			$code .= $chars[mt_rand(0, 35)];
+		}
+		// On stocke le code dans la session
+		$_SESSION['captcha'] = $code;
+		session_write_close();
+		return '<img src="./includes/captcha/showcaptcha.php" height="40" width="145" alt="Impossible d\'afficher le code !" />';
+	}
+	
+	
+	/**
+	* Lis les données d'un cookie
+	*
+	* @param string $cookie_name -> Le nom du cookie
+	* @param int    $data_pos    -> La position de la donnée à retourner, null pour toutes les données
+	* @return string si une position est choisie, sinon return array de toutes les données
+	*/
+	public static function readCookieData($cookie_name, $data_pos = null){
+		$separator = '|';
+		
+		if( isset($_COOKIE[$cookie_name]) ){
+			$out =  explode($separator, $_COOKIE[$cookie_name]);
+			
+			if( is_numeric($data_pos) ){
+				if( isset($out[$data_pos]) && $out[$data_pos] != null){
+					return $out[$data_pos];
+				}
+			}
+			else{
+				if($out[0] != null){
+					return $out;
+				}
+			}
+		}else{
+			return null;
+		}
+	}
+	
+	
+	/**
+	* Ajoute des données dans un cookie
+	*
+	* @param string $cookieName   -> Le nom du cookie
+	* @param array  $data         -> Les données du cookie
+	* @param int    $cookieExpire -> Le nombre de jours avant que le cookie expire
+	* @return true si l'écriture du cookie à réussi, sinon false
+	*/
+	public static function addCookieData($cookieName, $data, $cookieExpire = 15){
+		$separator = '|';
+		
+		$newCookieData = null;
+		for($i = 0; $i < count($data); $i++){
+			if($i == count($data)-1){
+				$newCookieData .= $data[$i];
+			}
+			else{
+				$newCookieData .= $data[$i].$separator;
+			}
+		}
+		
+		if( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != null){ $isHttps = true; }
+		else{ $isHttps = false; }
+		if( setcookie($cookieName, $newCookieData, time()+60*60*24*$cookieExpire, '/', $isHttps) ){
+			return true;
+		}
+		else{
+			return false;
+		}
+	}
+	
+	
+	/**
+	* Récupère la langue du navigateur
+	*
+	* @param string $forceLang -> Forcer l'utilisation du langue
+	* @return $_SESSION['lang']
+	*/
+	public static function getLang($forceLang = null){
+		if($forceLang){
+			$_SESSION['lang'] = $forceLang;
+		}
+		else{
+			if( !isset($_SESSION['lang']) ){
+				$_SESSION['lang'] = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
+			}
+		}
+		
+		return $_SESSION['lang'];
+	}
+	
+	
+	/**
+	* Retourne la valeur du terme
+	*
+	* @param array $args -> Arugments dans la clé. Ex: t('key word n°!numero', array('!numero' => $numero) );
+	*/
+	public static function t($key, $args = array() ){
+		global $translate;
+		$out = $key;
+		
+		if( isset($_SESSION['lang']) && $_SESSION['lang'] !== 'en' ){
+			if( isset($translate[$key]) ){
+				$out = $translate[$key];
+			}
+		}
+		
+		if( count($args) > 0 ){
+			$out = str_replace( array_keys($args), array_values($args), $out);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le navigateur internet du visiteur
+	*/
+	public static function getBrowser(){
+		$out = null;
+		$http_user_agent = $_SERVER['HTTP_USER_AGENT'];
+		
+		if( strstr($http_user_agent, 'Firefox') ){ $out = 'Firefox'; }
+		else if( strstr($http_user_agent, 'Chrome') ){ $out = 'Chrome'; }
+		else if( strstr($http_user_agent, 'Opera') ){ $out = 'Opera'; }
+		else if( strstr($http_user_agent, 'MSIE') ){ $out = 'IE'; }
+		else if( strstr($http_user_agent, 'Safari') ){ $out = 'Safari'; }
+		else if( strstr($http_user_agent, 'Konqueror') ){ $out = 'Konqueror'; }
+		else if( strstr($http_user_agent, 'Netscape') ){ $out = 'Netscape'; }
+		else{ $out = 'Others'; }
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le système d'exploitation du visiteur
+	*/
+	public static function getOperatingSystem(){
+		$out = null;
+		$http_user_agent = $_SERVER['HTTP_USER_AGENT'];
+		
+		if( strstr($http_user_agent, 'Win') ){ $out = 'Windows'; }
+		else if( (strstr($http_user_agent, 'Mac')) || (strstr('PPC', $http_user_agent)) ){ $out = 'Mac'; }
+		else if( strstr($http_user_agent, 'Linux') ){ $out = 'Linux'; }
+		else if( strstr($http_user_agent, 'FreeBSD') ){ $out = 'FreeBSD'; }
+		else if( strstr($http_user_agent, 'SunOS') ){ $out = 'SunOS'; }
+		else if( strstr($http_user_agent, 'IRIX') ){ $out = 'IRIX'; }
+		else if( strstr($http_user_agent, 'BeOS') ){ $out = 'BeOS'; }
+		else if( strstr($http_user_agent, 'OS/2') ){ $out = 'OS/2'; }
+		else if( strstr($http_user_agent, 'AIX') ){ $out = 'AIX'; }
+		else{ $out = 'Others'; }
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Détermine si le serveur est sous Windows, par défaut Unix
+	*
+	* @return bool
+	*/
+	public static function isWinServer(){
+		if( stripos(PHP_OS, 'WIN') === 0 ){
+			return true;
+		}
+		else{
+			return false;
+		}
+	}
+	
+	
+	/**
+	* Détermine si l'adresse ip du visiteur est dans le réseau local
+	*
+	* @param string $addr -> L'adresse IP à utiliser
+	* @return bool
+	*/
+	public static function isLocalhostIP($addr = null){
+		$out = false;
+		
+		$serverIPEx = explode('.', $_SERVER['SERVER_ADDR']);
+		$serverIP = $serverIPEx[0].'.'.$serverIPEx[1].'.'.$serverIPEx[2];
+		
+		if($addr){
+			$userIPEx = explode('.', $addr);
+		}
+		else{
+			$userIPEx = explode('.', $_SERVER['REMOTE_ADDR']);
+		}
+		$userIP = $userIPEx[0].'.'.$userIPEx[1].'.'.$userIPEx[2];
+		
+		if($userIP === $userIP){
+			$out = true;
+		}
+		
+		return $out;
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/class/zip.class.php b/resources/class/zip.class.php
new file mode 100644
index 0000000..28268dd
--- /dev/null
+++ b/resources/class/zip.class.php
@@ -0,0 +1,164 @@
+<?php
+/**
+* Class Zip
+*
+* Méthodes de traitement pour les archives ZIP
+*/
+class Zip extends ZipArchive {
+	
+	/**
+	* Créer une archive ZIP
+	*
+	* @param string $filename -> Nom de l'archive
+	* @param array  $struct   -> Tableau des données de l'archive :
+	*  $struct = array(
+	*    'dirname' => array(
+	*       'dirname2' => array(
+	*          'file3.txt'
+	*        ),
+	*        'file2.txt'
+	*     ),
+	*     'file1.txt'
+	*  );
+	* @return true si réussi, sinon false
+	*/
+	public function create($filename, $struct, &$errorMsg = null){
+		$out = false;
+		
+		if( !file_exists($filename) ){
+			$out = self::add($filename, $struct, $errorMsg);
+		}
+		else{
+			$errorMsg = self::_getErrorMsg(ZIPARCHIVE::ER_EXISTS);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Ajoute les données de la structure dans une archive ZIP
+	*
+	* @param string $filename -> Nom de l'archive
+	* @param array  $struct   -> Tableau des données de l'archive
+	* @return true si réussi, sinon false
+	*/
+	public function add($filename, $struct, &$errorMsg = null){
+		$out = false;
+		$zip = new ZipArchive();
+		
+		if( $result = $zip->open($filename, ZIPARCHIVE::CREATE) ){
+			self::_checkStructure($zip, $struct);
+			$out = true;
+			$zip->close();
+		}
+		else{
+			$errorMsg = self::_getErrorMsg($result);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Extrait une archive dans un dossier
+	*
+	* @param string $filename -> Chemin de l'archive
+	* @param string $path     -> Chemin d'extraction
+	*/
+	public function extract($filename, $path, &$errorMsg = null){
+		$out = false;
+		$zip = new ZipArchive();
+		
+		if( $result = $zip->open($filename) ){
+			if( !$out = $zip->extractTo($path) ){
+				$errorMsg = self::_getErrorMsg('ER_EXTRACT');
+			}
+			$zip->close();
+		}
+		else{
+			$errorMsg = self::_getErrorMsg($result);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Liste et créer la structure des données
+	*
+	* @param object $object -> L'instance de ZipArchive
+	* @param array  $struct -> Tableau des données de l'archive
+	* @param string $path   -> Le chemin à partir de la racine de la structure
+	*/
+	private function _checkStructure($object, $struct, $path = null){
+		if( count($struct) > 0 ){
+			foreach($struct as $folder => $file){
+				if( is_string($folder) ){
+					$object->addEmptyDir($path.$folder);
+					self::_checkStructure($object, $struct[$folder], $path.$folder.'/');
+				}
+				else{
+					$filename = null;
+					if( strstr($file, '/') ){
+						$pathinfo = pathinfo($file);
+						$filename = $pathinfo['basename'];
+					}
+					
+					if($filename){
+						$object->addFile($path.$file, $filename);
+					}else{
+						$object->addFile($path.$file);
+					}
+				}
+			}
+		}
+	}
+	
+	
+	/**
+	* Retourne le message d'erreur de ZipArchive correspondant au code erreur
+	*
+	* @param int $errorCode -> Le code d'erreur
+	* @return string
+	*/
+	private function _getErrorMsg($errorCode){
+		$out = null;
+		
+		switch($errorCode){
+			case ZIPARCHIVE::ER_EXISTS:
+				$out = 'Le fichier existe déjà.';
+				break;
+			case ZIPARCHIVE::ER_INCONS:
+				$out = 'L\'archive ZIP est inconsistante.';
+				break;
+			case ZIPARCHIVE::ER_INVAL:
+				$out = 'Argument invalide.';
+				break;
+			case ZIPARCHIVE::ER_MEMORY:
+				$out = 'Erreur de mémoire.';
+				break;
+			case ZIPARCHIVE::ER_NOENT:
+				$out = 'Le fichier n\'existe pas.';
+				break;
+			case ZIPARCHIVE::ER_NOZIP:
+				$out = 'N\'est pas une archive ZIP.';
+				break;
+			case ZIPARCHIVE::ER_OPEN:
+				$out = 'Impossible d\'ouvrir le fichier.';
+				break;
+			case ZIPARCHIVE::ER_READ:
+				$out = 'Erreur lors de la lecture.';
+				break;
+			case ZIPARCHIVE::ER_SEEK:
+				$out = 'Erreur de position.';
+				break;
+			case 'ER_EXTRACT':
+				$out = 'Erreur lors de l\'extraction.';
+				break;
+		}
+		
+		return $out;
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/core/adminlevel.php b/resources/core/adminlevel.php
new file mode 100644
index 0000000..218e480
--- /dev/null
+++ b/resources/core/adminlevel.php
@@ -0,0 +1,539 @@
+<?php
+
+/**
+* Classe pour la gestion des niveaux admins
+*/
+class AdminServAdminLevel {
+	
+	/**
+	* Constantes
+	*/
+	private static $DEFAULT_TYPE = array(
+		'SuperAdmin' => array('SuperAdmin', 'Admin', 'User'),
+		'Admin' => array('Admin', 'User'),
+		'User' => array('User'),
+	);
+	private static $DEFAULT_ACCESS = array(
+		'srvopts' => 'server_options',
+		'gameinfos' => 'game_infos',
+		'chat' => 'chat',
+		'maps-list' => 'maps_list',
+		'maps-local' => 'maps_local',
+		'maps-upload' => 'maps_upload',
+		'maps-order' => 'maps_order',
+		'maps-matchset' => 'maps_matchsettings',
+		'maps-creatematchset' => 'maps_create_matchsettings',
+		'link_access_server',
+		'plugins-list' => 'plugins_list',
+		'guestban' => 'guest_ban',
+	);
+	private static $DEFAULT_PERMISSION = array(
+		'speed_admin',
+		'switch_server',
+		'player_kick',
+		'player_ban',
+		'player_guest',
+		'player_ignore',
+		'player_forcetospectator',
+		'player_forcetoplayer',
+		'player_changeteam',
+		'force_scores',
+		'cancel_vote',
+		'srvopts_general_name',
+		'srvopts_general_comment',
+		'srvopts_general_playerpassword',
+		'srvopts_general_spectatorpassword',
+		'srvopts_general_nbplayers',
+		'srvopts_general_nbspectators',
+		'srvopts_advanced',
+		'srvopts_adminlevelpassword',
+		'srvopts_importexport',
+		'gameinfos_general_gamemode',
+		'gameinfos_general_options',
+		'gameinfos_general_warmup',
+		'gameinfos_teams_options',
+		'gameinfos_gamemode_options',
+		'chat_sendmessage',
+		'maps_list_moveaftercurrent',
+		'maps_list_removetolist',
+		'maps_local_add',
+		'maps_local_insert',
+		'maps_local_download',
+		'maps_local_rename',
+		'maps_local_move',
+		'maps_local_delete',
+		'maps_upload_add',
+		'maps_upload_insert',
+		'maps_upload_folder',
+		'maps_matchsettings_save',
+		'maps_matchsettings_load',
+		'maps_matchsettings_add',
+		'maps_matchsettings_insert',
+		'maps_matchsettings_edit',
+		'maps_matchsettings_delete',
+		'folder_new',
+		'folder_rename',
+		'folder_move',
+		'folder_delete',
+		'guestban_addplayer',
+		'guestban_removeplayer',
+		'guestban_playlist_new',
+		'guestban_playlist_save',
+		'guestban_playlist_load',
+		'guestban_playlist_delete',
+	);
+	private static $CONFIG_PATH = './config/';
+	private static $CONFIG_FILENAME = 'adminlevel.cfg.php';
+	private static $CONFIG_START_TEMPLATE = "<?php\nclass AdminLevelConfig {\n\tpublic static \$ADMINLEVELS = array(\n\t\t/********************* ADMINLEVELS CONFIGURATION *********************/\n\t\t\n";
+	private static $CONFIG_END_TEMPLATE =  "\t);\n}\n?>";
+	
+	
+	/**
+	* Vérifie s'il y a bien une config de niveaux admins
+	*
+	* @param string $levelName -> Tester si le niveau admin est présent
+	* @return bool
+	*/
+	public static function hasLevel($levelName = null) {
+		$out = false;
+		
+		if (class_exists('AdminLevelConfig')) {
+			$adminLevelList = AdminLevelConfig::$ADMINLEVELS;
+			
+			if (isset($adminLevelList) && !empty($adminLevelList)) {
+				if ($levelName) {
+					foreach ($adminLevelList as $adminLevelName => $adminLevelData) {
+						if ($adminLevelName === $levelName) {
+							$out = true;
+							break;
+						}
+					}
+				}
+				else {
+					$out = true;
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Vérifie s'il le niveau admin a bien l'accès à la page
+	*
+	* @param string $access    -> Nom de l'accès
+	* @param string $levelName -> Nom du niveau admin
+	* @return bool
+	*/
+	public static function hasAccess($access, $levelName = null) {
+		$out = false;
+		
+		// Si l'accès demandé est le nom d'une page
+		$defaultAccess = self::getDefaultAccess();
+		if (array_key_exists($access, $defaultAccess)) {
+			foreach ($defaultAccess as $pageName => $accessName) {
+				if ($access == $pageName) {
+					$access = $accessName;
+					break;
+				}
+			}
+		}
+		if ($levelName === null && defined('USER_ADMINLEVEL')) {
+			$levelName = USER_ADMINLEVEL;
+		}
+		$levelData = self::getData($levelName, 'access');
+		if (!empty($levelData) && in_array($access, $levelData)) {
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Vérifie s'il le niveau admin a bien la permission d'utiliser une fonctionnalité
+	*
+	* @param mixed  $permission -> Nom de la permission ou tableau de plusieurs permissions
+	* @param string $levelName  -> Nom du niveau admin
+	* @param string $levelType  -> Type de niveau minimum à autoriser
+	* @return bool
+	*/
+	public static function hasPermission($permission, $levelName = null, $levelType = null) {
+		$out = false;
+		if ($levelName === null && defined('USER_ADMINLEVEL')) {
+			$levelName = USER_ADMINLEVEL;
+		}
+		
+		if ($levelName) {
+			if ($levelType !== null) {
+				$levelData = self::getData($levelName, 'adminlevel');
+				$levelTypeAuthorized = self::getDefaultType($levelData['type']);
+				if (!in_array($levelType, $levelTypeAuthorized)) {
+					return false;
+				}
+			}
+			$levelData = self::getData($levelName, 'permission');
+			
+			if (!empty($levelData)) {
+				if (is_array($permission)) {
+					$result = array();
+					foreach ($permission as $perm) {
+						if (in_array($perm, $levelData)) {
+							$result[] = true;
+						}
+						else {
+							$result[] = false;
+						}
+					}
+					if (in_array(true, $result)) {
+						$out = true;
+					}
+				}
+				else {
+					if (in_array($permission, $levelData)) {
+						$out = true;
+					}
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère les niveaux par défaut ou renvoie les niveaux autorisés suivant le type
+	*
+	* @param string $type -> Type de niveau
+	* @return array
+	*/
+	public static function getDefaultType($levelType = null){
+		$out = array();
+		
+		if ($levelType === null) {
+			$out = array_keys(self::$DEFAULT_TYPE);
+		}
+		else {
+			foreach (self::$DEFAULT_TYPE as $defaultTypeLevel => $defaultAuthorizedLevel) {
+				if ($levelType === $defaultTypeLevel) {
+					$out = $defaultAuthorizedLevel;
+					break;
+				}
+			}
+		}
+		
+		return $out;
+	}
+	public static function getDefaultAccess(){
+		return self::$DEFAULT_ACCESS;
+	}
+	public static function getDefaultPermission(){
+		return self::$DEFAULT_PERMISSION;
+	}
+	
+	
+	/**
+	* Récupère les données de configuration pour un niveau admin
+	*
+	* @param string $levelName -> Nom du niveau admin
+	* @param string $fieldName -> Nom du champ de données à retourner
+	* @return array
+	*/
+	public static function getData($levelName = null, $fieldName = 'all') {
+		$out = array();
+		if ($levelName === null && defined('USER_ADMINLEVEL')) {
+			$levelName = USER_ADMINLEVEL;
+		}
+		
+		if (self::hasLevel($levelName)) {
+			$levelData = AdminLevelConfig::$ADMINLEVELS[$levelName];
+			
+			if ($fieldName != 'all') {
+				if (isset($levelData[$fieldName])) {
+					$out = $levelData[$fieldName];
+				}
+			}
+			else {
+				$out = $levelData;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la position du niveau admin dans le fichier de config
+	*
+	* @param string $levelName -> Nom du niveau admin
+	* @return string
+	*/
+	public static function getId($levelName = null) {
+		$id = 0;
+		$levelList = self::getStaticList();
+		if ($levelName === null && defined('USER_ADMINLEVEL')) {
+			$levelName = USER_ADMINLEVEL;
+		}
+		
+		// On cherche la position du niveau à partir de son nom
+		if (!empty($levelList)) {
+			foreach ($levelList as $levelListName) {
+				if ($levelListName == $levelName) {
+					break;
+				}
+				else {
+					$id++;
+				}
+			}
+		}
+		
+		// Si l'id = le nb total de levels -> pas trouvé
+		return ($id == count($levelList)) ? -1 : $id;
+	}
+	
+	
+	/**
+	* Récupère le type à partir du nom
+	*
+	* @param string $levelName -> Nom du niveau admin
+	* @return string
+	*/
+	public static function getType($levelName = null) {
+		$out = null;
+		if ($levelName === null && defined('USER_ADMINLEVEL')) {
+			$levelName = USER_ADMINLEVEL;
+		}
+		
+		$levelData = self::getData($levelName, 'adminlevel');
+		if (isset($levelData['type']) && $levelData['type'] != null) {
+			$out = $levelData['type'];
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le nom à partir du type
+	*
+	* @param int $levelId -> Numéro de la position dans la config
+	* @return string
+	*/
+	public static function getName($levelId) {
+		$out = null;
+		$levelList = self::getStaticList();
+		
+		if (!empty($levelList)) {
+			$i = 0;
+			foreach ($levelList as $levelListName) {
+				if ($i == $levelId) {
+					$out = $levelListName;
+					break;
+				}
+				$i++;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Détermine si le niveau utilisateur est au minimum de type $levelType
+	*
+	* @param string $levelType -> Type de niveau admin minimum
+	* @return bool
+	*/
+	public static function isType($levelType, $levelName = null) {
+		$out = false;
+		if ($levelName === null && defined('USER_ADMINLEVEL')) {
+			$levelName = USER_ADMINLEVEL;
+		}
+		
+		$levelData = self::getData($levelName, 'adminlevel');
+		$levelTypeAuthorized = self::getDefaultType($levelData['type']);
+		if (in_array($levelType, $levelTypeAuthorized)) {
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la liste des niveaux admins configurés pour le serveur courant
+	*
+	* @param string $server -> Nom du serveur
+	* @return array
+	*/
+	public static function getServerList($serverName = null) {
+		$out = array();
+		if ($serverName === null && defined('SERVER_NAME')) {
+			$serverName = SERVER_NAME;
+		}
+		
+		if (AdminServServerConfig::hasServer($serverName)) {
+			$levels = self::getStaticList();
+			if (!empty($levels)) {
+				foreach ($levels as $levelName) {
+					$levelType = self::getType($levelName);
+					foreach (ServerConfig::$SERVERS[$serverName]['adminlevel'] as $serverLevelType => $serverLevelTypeAccess) {
+						if ($levelType === $serverLevelType) {
+							if ($serverLevelType != null && $serverLevelTypeAccess != 'none') {
+								if (self::userAllowed($levelName, $serverName)) {
+									$out['levels'][] = $levelName;
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		
+		$out['last'] = Utils::readCookieData('adminserv', 1);
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la liste des niveaux admins configurés
+	*/
+	public static function getStaticList(){
+		$out = array();
+		
+		if (self::hasLevel()) {
+			foreach (AdminLevelConfig::$ADMINLEVELS as $levelName => $levelData) {
+				$out[] = $levelName;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Vérifie si l'ip de l'utilisateur est autorisé dans le niveau admin
+	*
+	* @param string $level  -> Nom du niveau admin
+	* @param string $server -> Nom du serveur
+	* @return bool
+	*/
+	public static function userAllowed($levelName, $serverName = null) {
+		$out = false;
+		if ($serverName === null && defined('SERVER_NAME')) {
+			$serverName = SERVER_NAME;
+		}
+		
+		if (AdminServServerConfig::hasServer($serverName)){
+			$levelType = self::getType($levelName);
+			if ($levelType) {
+				$serverLevelTypeAccess = ServerConfig::$SERVERS[$serverName]['adminlevel'][$levelType];
+				
+				if (is_array($serverLevelTypeAccess)) {
+					if (in_array($_SERVER['REMOTE_ADDR'], $serverLevelTypeAccess)) {
+						$out = true;
+					}
+				}
+				else {
+					if ($serverLevelTypeAccess === 'all') {
+						$out = true;
+					}
+					elseif ($serverLevelTypeAccess === 'none') {
+						$out = false;
+					}
+					else {
+						$out = Utils::isLocalhostIP();
+					}
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Créer le template d'un niveau admin
+	*
+	* @param array $levelData -> assoc array(adminlevel => array(type), access, permission)
+	*/
+	public static function getTemplate($levelData){
+		$out = "\t\t'".$levelData['name']."' => array(\n"
+			."\t\t\t'adminlevel' => array(\n";
+				foreach ($levelData['adminlevel'] as $adminlevelName => $adminlevelData) {
+					$out .= "\t\t\t\t'$adminlevelName' => '$adminlevelData',\n";
+				}
+			$out .= "\t\t\t),\n"
+			."\t\t\t'access' => array(\n";
+				if (!empty($levelData['access'])) {
+					foreach ($levelData['access'] as $accessName) {
+						$out .= "\t\t\t\t'$accessName',\n";
+					}
+				}
+			$out .= "\t\t\t),\n"
+			."\t\t\t'permission' => array(\n";
+				if (!empty($levelData['permission'])) {
+					foreach ($levelData['permission'] as $permissionName) {
+						$out .= "\t\t\t\t'$permissionName',\n";
+					}
+				}
+			$out .= "\t\t\t),\n"
+		."\t\t),\n";
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Sauvegarde le fichier de configuration des niveaux admins
+	*
+	* @param array $levelData -> assoc array(adminlevel => array(type), access, permission)
+	* @param int   $editLevel -> Id du niveau à éditer
+	* @param array $levelList -> Liste des niveaux de la config
+	* @return bool or string error
+	*/
+	public static function saveConfig($levelData = array(), $editLevel = -1, $levelList = array()) {
+		// Liste des niveaux
+		$levels = (isset($levelList) && !empty($levelList)) ? $levelList : AdminLevelConfig::$ADMINLEVELS;
+		
+		// Template
+		$fileTemplate = self::$CONFIG_START_TEMPLATE;
+		$i = 0;
+		foreach ($levels as $levelName => $levelValues) {
+			// Édition
+			if ($i == $editLevel && isset($levelData) && !empty($levelData)) {
+				$fileTemplate .= self::getTemplate($levelData);
+			}
+			else {
+				// Récupération des données des niveaux existant
+				$getLevelsData = array(
+					'name' => $levelName,
+					'adminlevel' => $levelValues['adminlevel'],
+					'access' => $levelValues['access'],
+					'permission' => $levelValues['permission'],
+				);
+				
+				// Ajout des données au template
+				$fileTemplate .= self::getTemplate($getLevelsData);
+			}
+			$i++;
+		}
+		
+		// Ajout d'un nouveau
+		if ($editLevel === -1 && isset($levelData) && !empty($levelData)) {
+			if (self::getId($levelData['name']) === -1) {
+				$fileTemplate .= self::getTemplate($levelData);
+			}
+			else {
+				return Utils::t('The admin level already exist! Change the name.');
+			}
+		}
+		$fileTemplate .= self::$CONFIG_END_TEMPLATE;
+		
+		// Enregistrement
+		return File::save(self::$CONFIG_PATH.self::$CONFIG_FILENAME, $fileTemplate, false);
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/core/adminserv.php b/resources/core/adminserv.php
new file mode 100644
index 0000000..dc089e2
--- /dev/null
+++ b/resources/core/adminserv.php
@@ -0,0 +1,2029 @@
+<?php
+define('ADMINSERV_TIMER', false);
+define('ADMINSERV_VERSION', '2.1.1');
+
+/**
+* Classe pour le fonctionnement d'AdminServ
+*/
+class AdminServ {
+	
+	/**
+	* Inclue les classes PHP
+	*/
+	public static function getClass(){
+		$pathClass = AdminServConfig::$PATH_RESOURCES.'class/';
+		require_once $pathClass.'GbxRemote.inc.php';
+		require_once $pathClass.'gbxdatafetcher.inc.php';
+		require_once $pathClass.'utils.class.php';
+		require_once $pathClass.'tmnick.class.php';
+		require_once $pathClass.'timedate.class.php';
+		require_once $pathClass.'file.class.php';
+		require_once $pathClass.'folder.class.php';
+		require_once $pathClass.'str.class.php';
+		require_once $pathClass.'upload.class.php';
+		require_once $pathClass.'zip.class.php';
+		
+		$pathCore = AdminServConfig::$PATH_RESOURCES.'core/';
+		require_once $pathCore.'adminlevel.php';
+		require_once $pathCore.'cache.php';
+		require_once $pathCore.'event.php';
+		require_once $pathCore.'logs.php';
+		require_once $pathCore.'plugin.php';
+		require_once $pathCore.'server.php';
+		require_once $pathCore.'sort.php';
+		require_once $pathCore.'ui.php';
+	}
+	
+	
+	/**
+	* Méthodes de debug
+	*/
+	public static function dsm($val){
+		echo '<pre>';
+		print_r($val);
+		echo '</pre>';
+	}
+	public static function debug($globalValue = null){
+		$const = get_defined_constants(true);
+		
+		return self::dsm(
+			array(
+				'GLOBALS' => ($globalValue) ? $GLOBALS[$globalValue] : $GLOBALS,
+				'ADMINSERV' => $const['user']
+			)
+		);
+	}
+	
+	/**
+	* Erreurs et infos
+	*/
+	public static function error($text = null){
+		global $client;
+		// Tente de récupérer le message d'erreur du dédié
+		if($text === null){
+			$text = '['.$client->getErrorCode().'] '.Utils::t( $client->getErrorMessage() );
+		}
+		else {
+			$text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
+		}
+		
+		AdminServLogs::add('error', $text);
+		unset($_SESSION['info']);
+		$_SESSION['error'] = $text;
+	}
+	public static function info($text){
+		$_SESSION['info'] = $text;
+	}
+	
+	
+	/**
+	* Temps de chargement de page
+	*/
+	public static function startTimer(){
+		global $timeStart;
+		$timeStart = microtime(true);
+	}
+	public static function endTimer(){
+		global $timeStart;
+		$timeEnd = microtime(true);
+		$time = $timeEnd - $timeStart;
+		return number_format($time, 3);
+	}
+	
+	
+	/**
+	* Vérifie la version de PHP
+	*/
+	public static function checkPHPVersion($version){
+		if( !version_compare(PHP_VERSION, $version, '>=') ){
+			echo '<b>This PHP version is not compatible with AdminServ.</b><br />Your PHP version: '. PHP_VERSION .'<br />PHP version required: '.$version;
+			exit;
+		}
+	}
+	
+	
+	/**
+	* Vérifie les droits pour l'écriture/lecture des fichiers
+	*
+	* @param array $list -> Liste des fichiers à tester : array('path' => 777)
+	* @return array
+	*/
+	public static function checkRights($list){
+		if( count($list) > 0 ){
+			foreach($list as $path => $minChmod){
+				$result = Folder::checkRights($path, $minChmod);
+				foreach($result as $grpName => $grpValues){
+					foreach($grpValues['result'] as $bool){
+						if(!$bool){
+							self::error( Utils::t('This path was not required rights:').' '.$path.' ("'.$grpName.'" '.Utils::t('needs').' "'.$minChmod.'")');
+							break;
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	
+	/**
+	* Intialise le client du serveur courant
+	*
+	* @param bool $fullInit -> Intialisation complète ? oui par défaut.
+	* Si non, ça ne recupère aucune info de base, seulement la connexion
+	* au serveur dédié et son authentication.
+	* @return bool
+	*/
+	public static function initialize($fullInit = true){
+		global $client;
+		$out = false;
+		
+		if( isset($_SESSION['adminserv']['sid']) ){
+			// CONSTANTS
+			define('USER_ADMINLEVEL', $_SESSION['adminserv']['adminlevel']);
+			define('SERVER_ID', $_SESSION['adminserv']['sid']);
+			define('SERVER_NAME', $_SESSION['adminserv']['name']);
+			define('SERVER_ADDR', ServerConfig::$SERVERS[SERVER_NAME]['address']);
+			define('SERVER_XMLRPC_PORT', ServerConfig::$SERVERS[SERVER_NAME]['port']);
+			define('SERVER_MATCHSET', ServerConfig::$SERVERS[SERVER_NAME]['matchsettings']);
+			define('SERVER_MAPS_BASEPATH', (isset(ServerConfig::$SERVERS[SERVER_NAME]['mapsbasepath'])) ? ServerConfig::$SERVERS[SERVER_NAME]['mapsbasepath'] : '');
+			define('SERVER_ADMINLEVEL', serialize( ServerConfig::$SERVERS[SERVER_NAME]['adminlevel']) );
+			
+			// CONNEXION
+			$client = new IXR_ClientMulticall_Gbx;
+			if( !$client->InitWithIp(SERVER_ADDR, SERVER_XMLRPC_PORT, AdminServConfig::SERVER_CONNECTION_TIMEOUT) ){
+				Utils::redirection(false, '?error='.urlencode( Utils::t('The server is not accessible.') ) );
+			}
+			else{
+				if( !AdminServAdminLevel::userAllowed(USER_ADMINLEVEL) ){
+					Utils::redirection(false, '?error='.urlencode( Utils::t('You are not allowed at this admin level') ) );
+				}
+				else{
+					if( !$client->query('Authenticate', AdminServAdminLevel::getType(), $_SESSION['adminserv']['password']) ){
+						Utils::redirection(false, '?error='.urlencode( Utils::t('The password doesn\'t match to the server.') ) );
+					}
+					else{
+						if($fullInit){
+							$client->addCall('SetApiVersion', array(date('Y-m-d')) );
+							$client->addCall('GetVersion');
+							$client->addCall('GetSystemInfo');
+							$client->addCall('IsRelayServer');
+							
+							if( !$client->multiquery() ){
+								self::error();
+							}
+							else{
+								$queriesData = $client->getMultiqueryResponse();
+								
+								// Version
+								$getVersion = $queriesData['GetVersion'];
+								define('SERVER_VERSION_NAME', $getVersion['Name']);
+								define('SERVER_VERSION', $getVersion['Version']);
+								define('SERVER_BUILD', $getVersion['Build']);
+								if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+									define('API_VERSION', $getVersion['ApiVersion']);
+								}
+								
+								// SystemInfo
+								$getSystemInfo = $queriesData['GetSystemInfo'];
+								define('SERVER_LOGIN', $getSystemInfo['ServerLogin']);
+								define('SERVER_PUBLISHED_IP', $getSystemInfo['PublishedIp']);
+								define('SERVER_PORT', $getSystemInfo['Port']);
+								define('SERVER_P2P_PORT', $getSystemInfo['P2PPort']);
+								if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+									define('SERVER_TITLE', $getSystemInfo['TitleId']);
+									define('IS_SERVER', $getSystemInfo['IsServer']);
+									define('IS_DEDICATED', $getSystemInfo['IsDedicated']);
+								}
+								
+								// Relay
+								define('IS_RELAY', $queriesData['IsRelayServer']);
+								
+								// Protocole : tmtp ou maniaplanet
+								if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+									TmNick::$linkProtocol = 'maniaplanet';
+								}
+								define('LINK_PROTOCOL', TmNick::$linkProtocol);
+								
+								// Mode d'affichage : detail ou simple
+								if( isset($_SESSION['adminserv']['mode']['general']) ){
+									define('USER_MODE_GENERAL', $_SESSION['adminserv']['mode']['general']);
+								}
+								else{
+									define('USER_MODE_GENERAL', 'simple');
+								}
+								if( isset($_SESSION['adminserv']['mode']['maps']) ){
+									define('USER_MODE_MAPS', $_SESSION['adminserv']['mode']['maps']);
+								}
+								else{
+									define('USER_MODE_MAPS', 'simple');
+								}
+								
+								// TmForever
+								if(SERVER_VERSION_NAME == 'TmForever'){
+									array_shift(ExtensionConfig::$GAMEMODES);
+									$stuntsGameMode = array_pop(ExtensionConfig::$GAMEMODES);
+									$CupGameMode = array_pop(ExtensionConfig::$GAMEMODES);
+									ExtensionConfig::$GAMEMODES[4] = $stuntsGameMode;
+									ExtensionConfig::$GAMEMODES[5] = $CupGameMode;
+								}
+								
+								$out = true;
+							}
+						}
+						else{
+							$out = true;
+						}
+					}
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne un lien protocol TM ou ManiaPlanet
+	*
+	* @param string $link -> Lien : #join=server_login ou /:manialink_name
+	* @return string
+	*/
+	public static function getProtocolLink($link) {
+		$out = null;
+		$protocolName = 'maniaplanet';
+		if (defined('LINK_PROTOCOL')) {
+			$protocolName = LINK_PROTOCOL;
+		}
+		$protocolSeparator = '://';
+		
+		if (defined('SERVER_VERSION_NAME') && SERVER_VERSION_NAME == 'ManiaPlanet' && defined('SERVER_TITLE')) {
+			$out = $protocolName.$protocolSeparator.$link.'@'.SERVER_TITLE;
+		}
+		else {
+			$out = $protocolName.$protocolSeparator.$link;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le nom du game mode
+	*
+	* @param int  $gameMode  -> La réponse de GetGameMode()
+	* @param bool $getManual -> Forcer la récupération manuelle du nom à partir du numéro dans la config
+	* @return string
+	*/
+	public static function getGameModeName($gameMode, $getManual = false){
+		$out = Utils::t('No game mode available');
+		
+		if( class_exists('ExtensionConfig') && isset(ExtensionConfig::$GAMEMODES) && count(ExtensionConfig::$GAMEMODES) > 0 ){
+			if($getManual && SERVER_VERSION_NAME == 'TmForever'){
+				$gameMode--;
+				if( isset(ExtensionConfig::$GAMEMODES[$gameMode]) ){
+					$out = ExtensionConfig::$GAMEMODES[$gameMode];
+				}
+			}
+			else{
+				$out = ExtensionConfig::$GAMEMODES[$gameMode];
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Détermine si le nom du mode de jeu fourni en paramètre correspond au mode de jeu actuel
+	*
+	* @param string $gameModeName    -> Nom du mode de jeu à tester
+	* @param int    $currentGameMode -> ID du mode de jeu courant. Si null, le mode de jeu courant est récupéré par le serveur
+	* @return bool
+	*/
+	public static function isGameMode($gameModeName, $currentGameMode = null){
+		global $client;
+		$out = false;
+		if($currentGameMode === null){
+			$client->query('GetGameMode');
+			$currentGameMode = $client->getResponse();
+		}
+		
+		if($gameModeName == self::getGameModeName($currentGameMode) ){
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Vérifie si la configuration du serveur est compatible avec le mode équipe
+	*
+	* @params int    $gameMode   -> ID du mode de jeu
+	* @params string $scriptName -> Nom du script si le mode de jeu est 0
+	* @return bool
+	*/
+	public static function checkDisplayTeamMode($gameMode, $scriptName = null){
+		$out = false;
+		
+		if($gameMode == 0 && SERVER_VERSION_NAME == 'ManiaPlanet' && class_exists('ExtensionConfig') && isset(ExtensionConfig::$TEAMSCRIPTS) && count(ExtensionConfig::$TEAMSCRIPTS) > 0 ){
+			foreach(ExtensionConfig::$TEAMSCRIPTS as $teamScript){
+				if( stristr($scriptName, $teamScript) ){
+					$out = true;
+					break;
+				}
+			}
+		}
+		else{
+			if( self::isGameMode('Team', $gameMode) ){
+				$out = true;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Formate le nom d'un script
+	*
+	* @param string $scriptName -> Le nom du script retourné par le serveur
+	* @return string
+	*/
+	public static function formatScriptName($scriptName){
+		$out = str_ireplace('.script.txt', '', $scriptName);
+		$scriptNameEx = explode('\\', $out);
+		$out = $scriptNameEx[count($scriptNameEx)-1];
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère les informations du serveur actuel (map, serveur, stats, joueurs)
+	*
+	* @param string $sortBy -> Le tri à faire sur la liste
+	* @return array
+	*/
+	public static function getCurrentServerInfo($sortBy = null){
+		global $client;
+		$out = array();
+		
+		// JEU
+		if(SERVER_VERSION_NAME == 'TmForever'){
+			$queryName = array(
+				'getMapInfo' => 'GetCurrentChallengeInfo'
+			);
+		}
+		else{
+			$queryName = array(
+				'getMapInfo' => 'GetCurrentMapInfo'
+			);
+		}
+		
+		// REQUÊTES
+		$client->addCall($queryName['getMapInfo']);
+		if( AdminServAdminLevel::isType('Admin') ){
+			$client->addCall('GetMapsDirectory');
+		}
+		$client->addCall('GetGameMode');
+		$client->addCall('GetServerName');
+		$client->addCall('GetStatus');
+		$client->addCall('GetCurrentCallVote');
+		if( AdminServAdminLevel::isType('SuperAdmin') ){
+			$client->addCall('GetNetworkStats');
+		}
+		$client->addCall('GetPlayerList', array(AdminServConfig::LIMIT_PLAYERS_LIST, 0, 1) );
+		
+		if( !$client->multiquery() ){
+			$out['error'] = Utils::t('Client not initialized');
+		}
+		else{
+			// DONNÉES DES REQUÊTES
+			$queriesData = $client->getMultiqueryResponse();
+			
+			// GameMode
+			$out['srv']['gameModeId'] = $queriesData['GetGameMode'];
+			$out['srv']['gameModeName'] = self::getGameModeName($out['srv']['gameModeId']);
+			$out['srv']['gameModeScriptName'] = null;
+			if( self::isGameMode('Script', $out['srv']['gameModeId']) ){
+				$client->query('GetModeScriptInfo');
+				$getModeScriptInfo = $client->getResponse();
+				if( isset($getModeScriptInfo['Name']) ){
+					$out['srv']['gameModeScriptName'] = self::formatScriptName($getModeScriptInfo['Name']);
+				}
+			}
+			$displayTeamMode = self::checkDisplayTeamMode($out['srv']['gameModeId'], $out['srv']['gameModeScriptName']);
+			
+			// CurrentMapInfo
+			$currentMapInfo = $queriesData[$queryName['getMapInfo']];
+			$out['map']['name'] = TmNick::toHtml($currentMapInfo['Name'], 10, true, false, '#999');
+			$out['map']['uid'] = $currentMapInfo['UId'];
+			$out['map']['author'] = $currentMapInfo['Author'];
+			$out['map']['enviro'] = $currentMapInfo['Environnement'];
+			
+			// MapThumbnail
+			$out['map']['thumb'] = null;
+			if( isset($queriesData['GetMapsDirectory']) && $currentMapInfo['FileName'] != null){
+				$mapFileName = $queriesData['GetMapsDirectory'].$currentMapInfo['FileName'];
+				if( file_exists($mapFileName) ){
+					if(SERVER_VERSION_NAME == 'TmForever'){
+						$Gbx = new GBXChallengeFetcher($queriesData['GetMapsDirectory'].$currentMapInfo['FileName'], false, true);
+					}
+					else{
+						$Gbx = new GBXChallMapFetcher(false, true);
+						$Gbx->processFile($queriesData['GetMapsDirectory'].$currentMapInfo['FileName']);
+					}
+					
+					$out['map']['thumb'] = base64_encode($Gbx->thumbnail);
+				}
+			}
+			
+			// CurrentCallVote
+			$out['map']['callvote']['login'] = $queriesData['GetCurrentCallVote']['CallerLogin'];
+			$out['map']['callvote']['cmdname'] = $queriesData['GetCurrentCallVote']['CmdName'];
+			$out['map']['callvote']['cmdparam'] = $queriesData['GetCurrentCallVote']['CmdParam'];
+			
+			// TeamScores (mode team)
+			if( self::isGameMode('Team', $out['srv']['gameModeId']) ){
+				$client->query('GetCurrentRanking', 2, 0);
+				$currentRanking = $client->getResponse();
+				$out['map']['scores']['blue'] = $currentRanking[0]['Score'];
+				$out['map']['scores']['red'] = $currentRanking[1]['Score'];
+			}
+			
+			// ServerName
+			$out['srv']['name'] = TmNick::toHtml($queriesData['GetServerName'], 10, true, false, '#999');
+			
+			// Status
+			$out['srv']['status'] = $queriesData['GetStatus']['Name'];
+			
+			// NetworkStats
+			if( isset($queriesData['GetNetworkStats']) && count($queriesData['GetNetworkStats']) > 0 ){
+				$networkStats = $queriesData['GetNetworkStats'];
+				$out['net']['uptime'] = TimeDate::secToStringTime($networkStats['Uptime'], false);
+				$out['net']['nbrconnection'] = $networkStats['NbrConnection'];
+				$out['net']['meanconnectiontime'] = TimeDate::secToStringTime($networkStats['MeanConnectionTime'], false);
+				$out['net']['meannbrplayer'] = $networkStats['MeanNbrPlayer'];
+				$out['net']['recvnetrate'] = $networkStats['RecvNetRate'];
+				$out['net']['sendnetrate'] = $networkStats['SendNetRate'];
+				$out['net']['totalreceivingsize'] = $networkStats['TotalReceivingSize'];
+				$out['net']['totalsendingsize'] = $networkStats['TotalSendingSize'];
+			}
+			else{
+				$out['net'] = null;
+			}
+			
+			// PlayerList
+			$playerList = $queriesData['GetPlayerList'];
+			$countPlayerList = count($playerList);
+			
+			if( $countPlayerList > 0 ){
+				$client->query('GetCurrentRanking', AdminServConfig::LIMIT_PLAYERS_LIST, 0);
+				$rankingList = $client->GetResponse();
+				$rankingKeyList = array(
+					'Rank',
+					'BestTime',
+					'BestCheckpoints',
+					'Score',
+					'NbrLapsFinished',
+					'LadderScore'
+				);
+				$i = 0;
+				foreach($playerList as $player){
+					// Nickname et Playerlogin
+					$out['ply'][$i]['NickName'] = TmNick::toHtml(htmlspecialchars($player['NickName'], ENT_QUOTES, 'UTF-8'), 10, true);
+					$out['ply'][$i]['Login'] = $player['Login'];
+					
+					// PlayerStatus
+					if($player['SpectatorStatus'] != 0){ $playerStatus = Utils::t('Spectator'); }else{ $playerStatus = Utils::t('Player'); }
+					$out['ply'][$i]['PlayerStatus'] = $playerStatus;
+					
+					// Others
+					$out['ply'][$i]['PlayerId'] = $player['PlayerId'];
+					$out['ply'][$i]['TeamId'] = $player['TeamId'];
+					if($player['TeamId'] == 0){ $teamName = Utils::t('Blue'); }else if($player['TeamId'] == 1){ $teamName = Utils::t('Red'); }else{ $teamName = Utils::t('Spectator'); }
+					$out['ply'][$i]['TeamName'] = $teamName;
+					$out['ply'][$i]['SpectatorStatus'] = $player['SpectatorStatus'];
+					
+					// Rankings
+					foreach($rankingKeyList as $rankName){
+						if( isset($rankingList[$i][$rankName]) ){
+							$out['ply'][$i][$rankName] = $rankingList[$i][$rankName];
+						}
+					}
+					if($player['LadderRanking'] == -1){
+						$player['LadderRanking'] = Utils::t('Not rated');
+					}
+					$out['ply'][$i]['LadderRanking'] = $player['LadderRanking'];
+					$i++;
+				}
+			}
+			else{
+				$out['ply'] = Utils::t('No player');
+			}
+			
+			
+			// Nombre de joueurs
+			if($countPlayerList > 1){
+				$out['nbp'] = $countPlayerList.' '.Utils::t('players');
+			}
+			else{
+				$out['nbp'] = $countPlayerList.' '.Utils::t('player');
+			}
+			
+			
+			// TRI
+			if( is_array($out['ply']) && count($out['ply']) > 0 ){
+				// Si on est en mode équipe, on tri par équipe
+				if($displayTeamMode){
+					uasort($out['ply'], 'AdminServSort::sortByRank');
+					uasort($out['ply'], 'AdminServSort::sortByTeam');
+				}
+				else{
+					switch($sortBy){
+						case 'nickname':
+							uasort($out['ply'], 'AdminServSort::sortByNickName');
+							break;
+						case 'ladder':
+							uasort($out['ply'], 'AdminServSort::sortByLadderRanking');
+							break;
+						case 'login':
+							uasort($out['ply'], 'AdminServSort::sortByLogin');
+							break;
+						case 'status':
+							uasort($out['ply'], 'AdminServSort::sortByStatus');
+							break;
+						default:
+							uasort($out['ply'], 'AdminServSort::sortByRank');
+							uasort($out['ply'], 'AdminServSort::sortByStatus');
+					}
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* @deprecated
+	* Récupère le login du serveur principal à partir d'un serveur Relai
+	*
+	* @return string
+	*/
+	public static function getMainServerLoginFromRelay(){
+		global $client;
+		$out = null;
+		
+		if( AdminServAdminLevel::isType('Admin') ){
+			if( !$client->query('GameDataDirectory') ){
+				self::error();
+			}
+			else{
+				// Récupération du login
+				$out = null;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le nombre de joueurs présent sur le serveur
+	*
+	* @param bool $spectator -> Inclus les spectateurs dans le calcul
+	* @return int
+	*/
+	public static function getNbPlayers($spectator = true){
+		global $client;
+		$out = 0;
+		
+		if( !$client->query('GetPlayerList', AdminServConfig::LIMIT_PLAYERS_LIST, 0, 1) ){
+			self::error();
+		}
+		else{
+			$playerList = $client->getResponse();
+			$countPlayerList = count($playerList);
+			
+			if($spectator){
+				$out = $countPlayerList;
+			}
+			else{
+				if($countPlayerList > 0){
+					foreach($playerList as $player){
+						if($player['SpectatorStatus'] == 0){
+							$out++;
+						}
+					}
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Administration rapide
+	*
+	* @param  string $cmd -> Le nom de la commande (PrevMap, RestartMap, NextMap ou ForceEndRound)
+	* @return true si réussi, sinon un message d'erreur
+	*/
+	public static function speedAdmin($cmd){
+		global $client;
+		$out = true;
+		
+		// Méthode en fonction du jeu
+		if($cmd != 'ForceEndRound'){
+			if(SERVER_VERSION_NAME == 'TmForever'){
+				$queries = array(
+					'restartMap' => 'RestartChallenge',
+					'nextMap' => 'NextChallenge',
+					'getCurrentMapIndex' => 'GetCurrentChallengeIndex',
+					'setNextMapIndex' => 'SetNextChallengeIndex'
+				);
+			}else{
+				$queries = array(
+					'restartMap' => 'RestartMap',
+					'nextMap' => 'NextMap',
+					'getCurrentMapIndex' => 'GetCurrentMapIndex',
+					'setNextMapIndex' => 'SetNextMapIndex'
+				);
+			}
+		}
+		
+		// Si c'est le mode Cup
+		$isCupMode = false;
+		if( self::isGameMode('Cup') ){
+			$isCupMode = true;
+		}
+		
+		// Suivant la commande demandée
+		switch($cmd){
+			case 'PrevMap':
+				if( !$client->query($queries['getCurrentMapIndex']) ){
+					$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+				}
+				else{
+					$currentMapIndex = $client->getResponse();
+					if($currentMapIndex === 0){
+						$nbMaps = self::getNbMaps( self::getMapList() );
+						$prevMapIndex =  $nbMaps['nbm']['count'] - 1;
+					}
+					else{
+						$prevMapIndex = $currentMapIndex - 1;
+					}
+					
+					if( !$client->query($queries['setNextMapIndex'], $prevMapIndex) ){
+						$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+					}
+					else{
+						self::speedAdmin('NextMap');
+					}
+				}
+				break;
+			case 'RestartMap':
+				if( !$client->query($queries['restartMap'], $isCupMode) ){
+					$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+				}
+				break;
+			case 'NextMap':
+				if( !$client->query($queries['nextMap'], $isCupMode) ){
+					$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+				}
+				break;
+			case 'ForceEndRound':
+				if($isCupMode){
+					if( !$client->query($queries['nextMap']) ){
+						$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+					}
+				}
+				else{
+					if( !$client->query('ForceEndRound') ){
+						$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+					}
+				}
+				break;
+			default:
+				$out = Utils::t('Unknown command');
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère les options du serveur
+	*
+	* @global resource $client -> Le client doit être initialisé
+	* @return array
+	*/
+	public static function getServerOptions(){
+		global $client;
+		$out = array();
+		
+		if(SERVER_VERSION_NAME == 'TmForever'){
+			$client->addCall('GetServerOptions', array(1) );
+		}
+		else{
+			$client->addCall('GetServerOptions');
+		}
+		$client->addCall('GetBuddyNotification', array('') );
+		if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+			$client->addCall('AreHornsDisabled');
+		}
+		
+		if( !$client->multiquery() ){
+			self::error();
+		}
+		else{
+			$queriesData = $client->getMultiqueryResponse();
+			$out = $queriesData['GetServerOptions'];
+			$out['Name'] = stripslashes($out['Name']);
+			if($out['Name'] == null){
+				$out['Name'] = SERVER_NAME;
+			}
+			$out['NameHtml'] = TmNick::toHtml($out['Name'], 10, false, false, '#666');
+			$out['Comment'] = stripslashes($out['Comment']);
+			$out['CommentHtml'] = TmNick::toHtml('$i'.nl2br($out['Comment']), 10, false, false, '#666');
+			if($out['CurrentLadderMode'] !== 0){
+				$out['CurrentLadderModeName'] = Utils::t('Forced'); 
+			}
+			else{
+				$out['CurrentLadderModeName'] = Utils::t('Inactive');
+			}
+			if($out['CurrentVehicleNetQuality'] !== 0){
+				$out['CurrentVehicleNetQualityName'] = Utils::t('High');
+			}
+			else{
+				$out['CurrentVehicleNetQualityName'] = Utils::t('Fast');
+			}
+			$out['BuddyNotification'] = $queriesData['GetBuddyNotification'];
+			if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+				$out['DisableHorns'] = $queriesData['AreHornsDisabled'];
+			}
+			else{
+				$out['DisableHorns'] = null;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne la structure pour l'enregistrement des options du serveur
+	*
+	* @return array
+	*/
+	public static function getServerOptionsStruct(){
+		if(SERVER_VERSION_NAME == 'TmForever'){
+			$keys = array(
+				'allowMapDownload' => 'AllowChallengeDownload'
+			);
+		}
+		else{
+			$keys = array(
+				'allowMapDownload' => 'AllowMapDownload'
+			);
+		}
+		
+		$out = array(
+			'Name' => stripslashes($_POST['Name']),
+			'Comment' => stripslashes($_POST['Comment']),
+			'Password' => trim($_POST['Password']),
+			'PasswordForSpectator' => trim($_POST['PasswordForSpectator']),
+			'NextMaxPlayers' => intval($_POST['NextMaxPlayers']),
+			'NextMaxSpectators' => intval($_POST['NextMaxSpectators']),
+			'IsP2PUpload' => array_key_exists('IsP2PUpload', $_POST),
+			'IsP2PDownload' => array_key_exists('IsP2PDownload', $_POST),
+			'NextLadderMode' => intval($_POST['NextLadderMode']),
+			'NextVehicleNetQuality' => intval($_POST['NextVehicleNetQuality']),
+			'NextCallVoteTimeOut' => TimeDate::secToMillisec( intval($_POST['NextCallVoteTimeOut']) ),
+			'CallVoteRatio' => (double)$_POST['CallVoteRatio'],
+			$keys['allowMapDownload'] => array_key_exists('AllowMapDownload', $_POST),
+			'AutoSaveReplays' => array_key_exists('AutoSaveReplays', $_POST),
+			'HideServer' => (int)array_key_exists('HideServer', $_POST),
+			'BuddyNotification' => array_key_exists('BuddyNotification', $_POST),
+			
+		);
+		if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+			$out['ClientInputsMaxLatency'] = ($_POST['ClientInputsMaxLatency'] == 'more') ? $_POST['ClientInputsMaxLatencyValue'] : $_POST['ClientInputsMaxLatency'];
+			$out['DisableHorns'] = array_key_exists('DisableHorns', $_POST);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Enregistre les options du serveur
+	*
+	* @param array $struct -> Structure contenant les champs demandés par la méthode SetServerOptions()
+	*/
+	public static function setServerOptions($struct){
+		global $client;
+		$out = false;
+		
+		if( !$client->query('SetServerOptions', $struct) ){
+			self::error();
+		}
+		else{
+			$client->addCall('SetHideServer', array($struct['HideServer']) );
+			$client->addCall('SetBuddyNotification', array('', $struct['BuddyNotification']) );
+			if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+				$client->addCall('SetClientInputsMaxLatency', array($struct['ClientInputsMaxLatency']) );
+				$client->addCall('DisableHorns', array($struct['DisableHorns']) );
+			}
+			
+			if( !$client->multiquery() ){
+				self::error();
+			}
+			else{
+				$out = true;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Exporte les options du serveur dans un fichier
+	*
+	* @param  string $file -> Chemin du fichier à écrire
+	* @param  array  $data -> Structure des options du serveur à écrire
+	* @return bool
+	*/
+	public static function exportServerOptions($file, $data){
+		$out = false;
+		
+		$xml = new DOMDocument('1.0', 'utf-8');
+		$xml->formatOutput = true;
+		$srvopts = $xml->createElement('ServerOptions');
+		$srvopts = $xml->appendChild($srvopts);
+		foreach($data as $dataField => $dataValue){
+			$srvoptsElement = $xml->createElement($dataField, $dataValue);
+			$srvoptsElementAttribute = $xml->createAttribute('type');
+			$srvoptsElementAttribute->value = Str::getValueType($dataValue);
+			$srvoptsElement->appendChild($srvoptsElementAttribute);
+			$srvoptsElement = $srvopts->appendChild($srvoptsElement);
+		}
+		
+		if( $result = $xml->save($file) > 0 ){
+			$out = true;
+			self::info( Utils::t('Server options are exported in').' '.$file);
+		}
+		else{
+			self::error( Utils::t('Unable to export server options') );
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Importe les options du serveur depuis un fichier
+	*
+	* @param  string $file -> Chemin du fichier à lire
+	* @return array
+	*/
+	public static function importServerOptions($file){
+		global $client;
+		$out = array();
+		
+		if( file_exists($file) ){
+			$dom = new DOMDocument();
+			$dom->load($file);
+			$srvopts = $dom->childNodes->item(0);
+			
+			for($i = 0; $i < $srvopts->childNodes->length; $i++){
+				$srvoptsElement = $srvopts->childNodes->item($i);
+				if($srvoptsElement->nodeName != '#text'){
+					$out[$srvoptsElement->nodeName] = Str::setValueType($srvoptsElement->nodeValue, $srvoptsElement->getAttribute('type') );
+				}
+			}
+		}
+		else{
+			self::error( Utils::t('No such file or file is not readable').' : '.$file);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère les informations de jeux
+	*
+	* @global resource $client -> Le client doit être initialisé
+	* @return array
+	*/
+	public static function getGameInfos(){
+		global $client;
+		$out = array();
+		
+		// Jeu
+		if(SERVER_VERSION_NAME == 'TmForever'){
+			$queries = array(
+				'CupRoundsPerMap' => 'GetCupRoundsPerChallenge',
+			);
+		}
+		else{
+			$queries = array(
+				'CupRoundsPerMap' => 'GetCupRoundsPerMap',
+			);
+		}
+		
+		// Requêtes
+		$client->addCall('GetGameInfos');
+		$client->addCall('GetAllWarmUpDuration');
+		$client->addCall('GetDisableRespawn');
+		$client->addCall('GetForceShowAllOpponents');
+		if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+			$client->addCall('GetScriptName');
+		}
+		$client->addCall('GetCupPointsLimit');
+		$client->addCall($queries['CupRoundsPerMap']);
+		$client->addCall('GetCupNbWinners');
+		$client->addCall('GetCupWarmUpDuration');
+		$client->addCall('GetRoundCustomPoints');
+		
+		if( !$client->multiquery() ){
+			self::error();
+		}
+		else{
+			$queriesData = $client->getMultiqueryResponse();
+			
+			// Game infos
+			$currGamInf = $queriesData['GetGameInfos']['CurrentGameInfos'];
+			$nextGamInf = $queriesData['GetGameInfos']['NextGameInfos'];
+			
+			// Nb de WarmUp
+			$currGamInf['AllWarmUpDuration'] = $queriesData['GetAllWarmUpDuration']['CurrentValue'];
+			$nextGamInf['AllWarmUpDuration'] = $queriesData['GetAllWarmUpDuration']['NextValue'];
+			
+			// Respawn
+			$currGamInf['DisableRespawn'] = $queriesData['GetDisableRespawn']['CurrentValue'];
+			$nextGamInf['DisableRespawn'] = $queriesData['GetDisableRespawn']['NextValue'];
+			
+			// ForceShowAllOpponents
+			$currGamInf['ForceShowAllOpponents'] = $queriesData['GetForceShowAllOpponents']['CurrentValue'];
+			$nextGamInf['ForceShowAllOpponents'] = $queriesData['GetForceShowAllOpponents']['NextValue'];
+			
+			// ScriptName
+			$currGamInf['ScriptName'] = null;
+			$nextGamInf['ScriptName'] = null;
+			if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+				$currGamInf['ScriptName'] = $queriesData['GetScriptName']['CurrentValue'];
+				$nextGamInf['ScriptName'] = $queriesData['GetScriptName']['NextValue'];
+			}
+			
+			// Mode Cup
+			$currGamInf['CupPointsLimit'] = $queriesData['GetCupPointsLimit']['CurrentValue'];
+			$nextGamInf['CupPointsLimit'] = $queriesData['GetCupPointsLimit']['NextValue'];
+			$currGamInf['CupRoundsPerMap'] = $queriesData[$queries['CupRoundsPerMap']]['CurrentValue'];
+			$nextGamInf['CupRoundsPerMap'] = $queriesData[$queries['CupRoundsPerMap']]['NextValue'];
+			$currGamInf['CupNbWinners'] = $queriesData['GetCupNbWinners']['CurrentValue'];
+			$nextGamInf['CupNbWinners'] = $queriesData['GetCupNbWinners']['NextValue'];
+			$currGamInf['CupWarmUpDuration'] = $queriesData['GetCupWarmUpDuration']['CurrentValue'];
+			$nextGamInf['CupWarmUpDuration'] = $queriesData['GetCupWarmUpDuration']['NextValue'];
+			
+			// RoundCustomPoints
+			$RoundCustomPoints = implode(',', $queriesData['GetRoundCustomPoints']);
+			$currGamInf['RoundCustomPoints'] = $RoundCustomPoints;
+			$nextGamInf['RoundCustomPoints'] = $RoundCustomPoints;
+			
+			// Retour
+			$out['curr'] = $currGamInf;
+			$out['next'] = $nextGamInf;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne la structure pour l'enregistrement des informations de jeu
+	*
+	* @return array
+	*/
+	public static function getGameInfosStructFromPOST(){
+		if($_POST['NextFinishTimeoutValue'] < 2){
+			if($_POST['NextFinishTimeout'] == 0){ $FinishTimeout = 0; }
+			else if($_POST['NextFinishTimeout'] == 1){ $FinishTimeout = 1; }
+		}
+		else{ $FinishTimeout = TimeDate::secToMillisec( intval($_POST['NextFinishTimeoutValue']) ); }
+		if( array_key_exists('NextDisableRespawn', $_POST) === true ){ $DisableRespawn = false; }
+		else{ $DisableRespawn = true; }
+		if($_POST['NextForceShowAllOpponentsValue'] < 2){
+			if($_POST['NextForceShowAllOpponents'] == 0){ $NextForceShowAllOpponents = 0; }
+			else if($_POST['NextForceShowAllOpponents'] == 1){ $NextForceShowAllOpponents = 1; }
+		}
+		else{ $NextForceShowAllOpponents = intval($_POST['NextForceShowAllOpponentsValue']); }
+		
+		$out = array(
+			'GameMode' => intval($_POST['NextGameMode']),
+			'ChatTime' => TimeDate::secToMillisec( intval($_POST['NextChatTime'] - 8) ),
+			'RoundsPointsLimit' => intval($_POST['NextRoundsPointsLimit']),
+			'RoundCustomPoints' => intval($_POST['NextRoundCustomPoints']),
+			'RoundsUseNewRules' => array_key_exists('NextRoundsUseNewRules', $_POST),
+			'RoundsForcedLaps' => intval($_POST['NextRoundsForcedLaps']),
+			'RoundsPointsLimitNewRules' => intval($_POST['NextRoundsPointsLimit']),
+			'TimeAttackLimit' => TimeDate::secToMillisec( intval($_POST['NextTimeAttackLimit']) ),
+			'TimeAttackSynchStartPeriod' => TimeDate::secToMillisec( intval($_POST['NextTimeAttackSynchStartPeriod']) ),
+			'TeamPointsLimit' => intval($_POST['NextTeamPointsLimit']),
+			'TeamMaxPoints' => intval($_POST['NextTeamMaxPoints']),
+			'TeamUseNewRules' => array_key_exists('NextTeamUseNewRules', $_POST),
+			'TeamPointsLimitNewRules' => intval($_POST['NextTeamPointsLimit']),
+			'LapsNbLaps' => intval($_POST['NextLapsNbLaps']),
+			'LapsTimeLimit' => TimeDate::secToMillisec( intval($_POST['NextLapsTimeLimit']) ),
+			'FinishTimeout' => $FinishTimeout,
+			'AllWarmUpDuration' => intval($_POST['NextAllWarmUpDuration']),
+			'DisableRespawn' => $DisableRespawn,
+			'ForceShowAllOpponents' => $NextForceShowAllOpponents,
+			'CupPointsLimit' => intval($_POST['NextCupPointsLimit']),
+			'CupRoundsPerMap' => intval($_POST['NextCupRoundsPerMap']),
+			'CupNbWinners' => intval($_POST['NextCupNbWinners']),
+			'CupWarmUpDuration' => intval($_POST['NextCupWarmUpDuration'])
+		);
+		if(SERVER_VERSION_NAME != 'TmForever'){
+			$out += array('ScriptName' => $_POST['NextScriptName']);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Enregistre les infos sur les équipes
+	* @param array $team1 -> (assoc) array(name, color (0 to 1), country)
+	* @param array $team2
+	* @return bool
+	*/
+	public static function setTeamInfo($team1, $team2){
+		global $client;
+		$out = false;
+		
+		if( !$client->query('SetTeamInfo', 'Unused', 0., 'World', $team1['name'], (double)$team1['color'], $team1['country'], $team2['name'], (double)$team2['color'], $team2['country']) ){
+			AdminServ::error();
+		}
+		else{
+			$_SESSION['adminserv']['teaminfo'] = array(
+				'team1' => $team1,
+				'team2' => $team2
+			);
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Add chat line on server
+	*
+	* @param string $message       -> Text message
+	* @param string $nickname      -> Nickname
+	* @param string $color         -> Text color
+	* @param string $destination   -> Message destination: server or player login
+	* @param string $showAdminText -> Display "Admin" before the message
+	* @return bool or text error
+	*/
+	public static function addChatServerLine($message, $nickname = null, $color = '$ff0', $destination = 'server', $showAdminText = false){
+		global $client;
+		$out = false;
+		$admin = null;
+		Utils::addCookieData('adminserv_user', array(AdminServUI::theme(), AdminServUI::lang(), $nickname, $color), AdminServConfig::COOKIE_EXPIRE);
+		
+		if($showAdminText){
+			$admin = '$fffAdmin:';
+		}
+		
+		if($nickname){
+			$nickname = '$g$ff0'.TmNick::stripNadeoCode($nickname, array('$s') );
+		}
+		
+		$nickname = '$s$ff0['.$admin.$nickname.'$z$s$ff0]$z';
+		$message = $nickname.' '.$color.$message;
+		$_SESSION['adminserv']['chat_dst'] = $destination;
+		
+		if($destination === 'server'){
+			if( !$client->query('ChatSendServerMessage', $message) ){
+				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+			}
+			else{
+				$out = true;
+			}
+		}
+		else{
+			if( !$client->query('ChatSendServerMessageToLogin', $message, $destination) ){
+				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+			}
+			else{
+				$out = true;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère les lignes du chat serveur
+	*
+	* @param bool $hideServerLines -> Masquer les lignes provenant d'un gestionnaire de serveur
+	* @return string
+	*/
+	public static function getChatServerLines($hideServerLines = false){
+		global $client;
+		$out = null;
+		
+		if( !$client->query('GetChatLines') ){
+			$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+		}
+		else{
+			$langCode = AdminServUI::lang();
+			$chatLines = $client->getResponse();
+			
+			foreach($chatLines as $line){
+				if( self::isServerLine($line) ){
+					if($hideServerLines){
+						unset($line);
+					}
+					else{
+						$tradLines = array(
+							'$99FThis round is a draw.',
+							'$99FThe $<$00FBlue team$> wins this round.',
+							'$99FThe $<$F00Red team$> wins this round.'
+						);
+						if( in_array($line, $tradLines) ){
+							foreach($tradLines as $tradLine){
+								if($line == $tradLine){
+									if($langCode == 'en'){
+										$line = '$999'.TmNick::toText( TmNick::stripNadeoCode($tradLine, array('$<', '$>')) );
+									}
+									else{
+										$line = '$999'.TmNick::toText( Utils::t($tradLine) );
+									}
+									break;
+								}
+							}
+						}
+						else{
+							if( strstr($line, '$fffAdmin:') ){
+								$pattern = '$ff0]$z';
+								$lineEx = explode($pattern, $line);
+								$nickname = $lineEx[0].$pattern;
+								$message = TmNick::toText( trim($lineEx[1]) );
+								$line = $nickname.' $666'.$message;
+							}
+							else{
+								$line = '$999'.TmNick::toText($line);
+							}
+						}
+					}
+				}
+				else{
+					$lineEx = explode('$>', $line);
+					$nickname = TmNick::stripNadeoCode($lineEx[0], array('$s', '[$<') );
+					$message = TmNick::toText( substr($lineEx[1], 2) );
+					
+					$line = '$s$ff0['.$nickname.'$g$ff0]$z $666'.$message;
+				}
+				
+				if( isset($line) ){
+					$out .= TmNick::toHtml($line, 10);
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne true si la ligne est générée par le serveur
+	*
+	* @param string $line -> La ligne de la réponse GetChatLines
+	* @return bool
+	*/
+	public static function isServerLine($line){
+		$out = false;
+		$char = substr(utf8_decode($line), 0, 1);
+		
+		if($char == '<' || $char == '/' || substr($line, 0, 4) == '$99F' || substr($line, 0, 12) == 'Invalid time' || $char == '?'){
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le chemin du dossier "Maps"
+	*
+	* @global resource $client -> Le client doit être initialisé
+	* @return string
+	*/
+	public static function getMapsDirectoryPath(){
+		global $client;
+		$out = null;
+		
+		if(SERVER_VERSION_NAME == 'TmForever'){
+			$queryName = 'GetTracksDirectory';
+		}
+		else{
+			$queryName = 'GetMapsDirectory';
+		}
+		
+		if( !$client->query($queryName) ){
+			$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
+		}
+		else{
+			$out = Str::toSlash( $client->getResponse() );
+			if( substr($out, -1, 1) != '/'){ $out .= '/'; }
+			if(SERVER_MAPS_BASEPATH){
+				$out .= Str::toSlash(SERVER_MAPS_BASEPATH);
+				if( substr($out, -1, 1) != '/'){ $out .= '/'; }
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne un tableau avec le nombre de maps et l'intitulé
+	*
+	* @param array $array -> La tableau contenant la liste des maps
+	* @return array
+	*/
+	public static function getNbMaps($array){
+		$out = array();
+		
+		if( isset($array['lst']) && is_array($array['lst']) ){
+			$countMapsList = count($array['lst']);
+		}
+		else{
+			$countMapsList = 0;
+		}
+		
+		$out['nbm']['count'] = $countMapsList;
+		if($countMapsList > 1){
+			$out['nbm']['title'] = Utils::t('maps');
+		}
+		else{
+			$out['nbm']['title'] = Utils::t('map');
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la liste des maps sur le serveur
+	*
+	* @global resource $client -> Le client doit être initialisé
+	* @param  string   $sortBy -> Le tri à faire sur la liste
+	* @return array
+	*/
+	public static function getMapList($sortBy = null){
+		global $client;
+		$out = array();
+		
+		// Méthodes
+		if(SERVER_VERSION_NAME == 'TmForever'){
+			$queryName = array(
+				'mapList' => 'GetChallengeList',
+				'mapIndex' => 'GetCurrentChallengeIndex'
+			);
+		}
+		else{
+			$queryName = array(
+				'mapList' => 'GetMapList',
+				'mapIndex' => 'GetCurrentMapIndex'
+			);
+		}
+		
+		// MAPSLIST
+		if( !$client->query($queryName['mapList'], AdminServConfig::LIMIT_MAPS_LIST, 0) ){
+			$out['error'] = Utils::t('Client not initialized');
+		}
+		else{
+			$mapList = $client->getResponse();
+			$countMapList = count($mapList);
+			$client->query($queryName['mapIndex']);
+			$out['cid'] = $client->getResponse();
+			
+			if( $countMapList > 0 ){
+				$i = 0;
+				foreach($mapList as $map){
+					// Name
+					$name = htmlspecialchars($map['Name'], ENT_QUOTES, 'UTF-8');
+					$out['lst'][$i]['Name'] = TmNick::toHtml($name, 10, true);
+					
+					// Environnement
+					$env = $map['Environnement'];
+					if($env == 'Speed'){ $env = 'Desert'; }else if($env == 'Alpine'){ $env = 'Snow'; }
+					$out['lst'][$i]['Environment'] = $env;
+					
+					// Autres
+					$out['lst'][$i]['UId'] = $map['UId'];
+					$out['lst'][$i]['FileName'] = $map['FileName'];
+					$out['lst'][$i]['Author'] = $map['Author'];
+					$out['lst'][$i]['GoldTime'] = TimeDate::format($map['GoldTime']);
+					$out['lst'][$i]['CopperPrice'] = $map['CopperPrice'];
+					if(SERVER_VERSION_NAME == 'ManiaPlanet'){
+						$out['lst'][$i]['Type']['Name'] = self::formatScriptName($map['MapType']);
+						$out['lst'][$i]['Type']['FullName'] = $map['MapType'];
+						$out['lst'][$i]['Style']['Name'] = self::formatScriptName($map['MapStyle']);
+						$out['lst'][$i]['Style']['FullName'] = $map['MapStyle'];
+					}
+					$i++;
+				}
+			}
+			
+			// Nombre de maps
+			$out += self::getNbMaps($out);
+			if($out['nbm']['count'] == 0){
+				$out['lst'] = Utils::t('No map');
+			}
+			
+			
+			// TRI
+			if($sortBy != null){
+				if( is_array($out['lst']) && count($out['lst']) > 0 ){
+					switch($sortBy){
+						case 'name':
+							uasort($out['lst'], 'AdminServSort::sortByName');
+							break;
+						case 'env':
+							uasort($out['lst'], 'AdminServSort::sortByEnviro');
+							break;
+						case 'author':
+							uasort($out['lst'], 'AdminServSort::sortByAuthor');
+							break;
+						case 'goldtime':
+							uasort($out['lst'], 'AdminServSort::sortByGoldTime');
+							break;
+						case 'cost':
+							uasort($out['lst'], 'AdminServSort::sortByPrice');
+							break;
+					}
+				}
+				$out['lst'] = array_values($out['lst']);
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la liste des maps sur le serveur et retourne un champ en particulier
+	*
+	* @global resource $client -> Le client doit être initialisé
+	* @return array
+	*/
+	public static function getMapListField($field){
+		global $client;
+		$out = array();
+		
+		// Méthodes
+		if(SERVER_VERSION_NAME == 'TmForever'){
+			$queryName = array(
+				'mapList' => 'GetChallengeList',
+			);
+		}
+		else{
+			$queryName = array(
+				'mapList' => 'GetMapList',
+			);
+		}
+		
+		// Mapslist
+		if( !$client->query($queryName['mapList'], AdminServConfig::LIMIT_MAPS_LIST, 0) ){
+			$out['error'] = Utils::t('Client not initialized');
+		}
+		else{
+			$mapList = $client->getResponse();
+			$countMapList = count($mapList);
+			if( $countMapList > 0 ){
+				$i = 0;
+				foreach($mapList as $map){
+					switch($field){
+						case 'Name':
+							$name = htmlspecialchars($map['Name'], ENT_QUOTES, 'UTF-8');
+							$out[] = TmNick::toHtml($name, 10, true);
+							break;
+						case 'Environment':
+							$env = $map['Environnement'];
+							if($env == 'Speed'){ $env = 'Desert'; }else if($env == 'Alpine'){ $env = 'Snow'; }
+							$out[] = $env;
+							break;
+						case 'UId':
+							$out[] = $map['UId'];
+							break;
+						case 'FileName':
+							$out[] = $map['FileName'];
+							break;
+						case 'Author':
+							$out[] = $map['Author'];
+							break;
+						case 'GoldTime':
+							$out[] = TimeDate::format($map['GoldTime']);
+							break;
+						case 'CopperPrice':
+							$out[] = $map['CopperPrice'];
+							break;
+						case 'MapType':
+							$out[] = $map['MapType'];
+							break;
+						case 'MapStyle':
+							$out[] = $map['MapStyle'];
+							break;
+					}
+					$i++;
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la liste des maps en local à partir d'un chemin
+	*
+	* @param string $path   -> Le chemin du dossier à lister
+	* @param string $sortBy -> Le tri à faire sur la liste
+	* @return array
+	*/
+	public static function getLocalMapList($directory, $currentPath, $sortBy = null){
+		global $client;
+		$out = array();
+		
+		if( is_array($directory) ){
+			if( !empty($directory['files']) ){
+				// Récupération du cache existant
+				$mapsDirectoryPath = self::getMapsDirectoryPath();
+				$cache = new AdminServCache();
+				$cacheKey = 'mapslist-'.Str::replaceChars($mapsDirectoryPath.$currentPath);
+				$cacheMaps = $cache->get($cacheKey);
+				
+				// Fichiers
+				$files = array();
+				foreach($directory['files'] as $fileName => $fileValues){
+					$dbExt = File::getDoubleExtension($fileName);
+					if( in_array($dbExt, AdminServConfig::$MAP_EXTENSION) ){
+						$files[$fileName] = $fileValues;
+					}
+				}
+				
+				// Suppression du cache en trop
+				$cacheOverFiles = array_diff_key($cacheMaps, $files);
+				if( !empty($cacheOverFiles) ){
+					foreach($cacheOverFiles as $fileName => $fileValues){
+						if( isset($cacheMaps[$fileName]) ){
+							unset($cacheMaps[$fileName]);
+						}
+					}
+					$cache->set($cacheKey, $cacheMaps);
+				}
+				
+				// Ajout des fichiers manquant dans le cache
+				$cacheMissingFiles = array_diff_key($files, $cacheMaps);
+				if( !empty($cacheMissingFiles) ){
+					// Path
+					$path = $mapsDirectoryPath.$currentPath;
+					
+					// Création du cache
+					foreach($cacheMissingFiles as $file => $values){
+						// Données
+						$processFile = utf8_decode($file);
+						if(SERVER_VERSION_NAME == 'TmForever'){
+							$Gbx = new GBXChallengeFetcher($path.$processFile);
+						}
+						else{
+							$Gbx = new GBXChallMapFetcher();
+							$Gbx->processFile($path.$processFile);
+						}
+						
+						// Name
+						$filename = $Gbx->name;
+						if($filename == 'read error'){
+							$filename = str_ireplace('.'.$dbExt, '', $file);
+						}
+						$name = htmlspecialchars($filename, ENT_QUOTES, 'UTF-8');
+						$out['lst'][$file]['Name'] = TmNick::toHtml($name, 10, true);
+						
+						// Environnement
+						$env = $Gbx->envir;
+						if($env == 'read error'){ $env = null; }
+						if($env == 'Speed'){ $env = 'Desert'; }else if($env == 'Alpine'){ $env = 'Snow'; }
+						$out['lst'][$file]['Environment'] = $env;
+						
+						// Autres
+						$out['lst'][$file]['FileName'] = $currentPath.$file;
+						$uid = $Gbx->uid;
+						if($uid == 'read error'){ $uid = null; }
+						$out['lst'][$file]['UId'] = $uid;
+						$author = $Gbx->author;
+						if($author == 'read error'){ $author = null; }
+						$out['lst'][$file]['Author'] = $author;
+						$out['lst'][$file]['Recent'] = $values['recent'];
+						
+						// MapType
+						$mapType = $Gbx->mapType;
+						if($mapType == null && $Gbx->typeName != null){
+							$mapType = $Gbx->typeName;
+						}
+						$out['lst'][$file]['Type']['Name'] = self::formatScriptName($mapType);
+						$out['lst'][$file]['Type']['FullName'] = $mapType;
+					}
+					
+					// Mise à jour du cache
+					if( !empty($cacheMaps) ){
+						$out['lst'] = array_merge($cacheMaps, $out['lst']);
+					}
+					$cache->set($cacheKey, $out['lst']);
+				}
+				else{
+					$out['lst'] = $cacheMaps;
+				}
+				
+				// Maps on server?
+				$currentMapsListUId = null;
+				if(AdminServConfig::LOCAL_GET_MAPS_ON_SERVER){
+					$currentMapsListUId = self::getMapListField('UId');
+				}
+				foreach($out['lst'] as &$file){
+					$file['OnServer'] = false;
+					if($currentMapsListUId){
+						if( in_array($file['UId'], $currentMapsListUId) ){
+							$file['OnServer'] = true;
+						}
+					}
+				}
+				
+				// Nombre de maps
+				$out += self::getNbMaps($out);
+				if($out['nbm']['count'] == 0){
+					$out['lst'] = Utils::t('No map');
+				}
+				else{
+					// TRIS
+					if($sortBy != null){
+						switch($sortBy){
+							case 'filename':
+								uasort($out['lst'], 'AdminServSort::sortByFileName');
+								break;
+							case 'name':
+								uasort($out['lst'], 'AdminServSort::sortByName');
+								break;
+							case 'env':
+								uasort($out['lst'], 'AdminServSort::sortByEnviro');
+								break;
+							case 'type':
+								uasort($out['lst'], 'AdminServSort::sortByType');
+								break;
+							case 'author':
+								uasort($out['lst'], 'AdminServSort::sortByAuthor');
+								break;
+						}
+					}
+				}
+			}
+			else{
+				$out += self::getNbMaps($out);
+				$out['lst'] = Utils::t('No map');
+			}
+		}
+		// Retour des erreurs de la méthode read
+		else{
+			$out = $directory;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la liste des matchsettings en local à partir d'un chemin
+	*
+	* @param string $path -> Le chemin du dossier à lister
+	* @return array
+	*/
+	public static function getLocalMatchSettingList($directory, $currentPath){
+		$out = array();
+		
+		if( is_array($directory) ){
+			if( !empty($directory['files']) ){
+				$mapsDirectoryPath = self::getMapsDirectoryPath();
+				
+				foreach($directory['files'] as $file => $values){
+					if( in_array(File::getExtension($file), AdminServConfig::$MATCHSET_EXTENSION) ){
+						$matchsetData = self::getMatchSettingsData($mapsDirectoryPath.$currentPath.$file, array('maps'));
+						$matchsetNbmCount = 0;
+						if( isset($matchsetData['maps']) ){
+							$matchsetNbmCount = count($matchsetData['maps']);
+						}
+						$matchsetNbmTitle = ($matchsetNbmCount > 1) ? Utils::t('maps') : Utils::t('map');
+						
+						$out['lst'][$file]['Name'] = substr($file, 0, -4);
+						$out['lst'][$file]['FileName'] = $currentPath.$file;
+						$out['lst'][$file]['Nbm'] = $matchsetNbmCount.' '.$matchsetNbmTitle;
+						$out['lst'][$file]['Mtime'] = $values['mtime'];
+						$out['lst'][$file]['Recent'] = $values['recent'];
+					}
+				}
+			}
+			
+			// Nombre de matchsettings
+			if( isset($out['lst']) && is_array($out['lst']) ){
+				$out['nbm']['count'] = count($out['lst']);
+				$out['nbm']['title'] = ($out['nbm']['count'] > 1) ? Utils::t('matchsettings') : Utils::t('matchsetting');
+			}
+			else{
+				$out['nbm']['count'] = 0;
+				$out['nbm']['title'] = Utils::t('matchsetting');
+			}
+			if($out['nbm']['count'] == 0){
+				$out['lst'] = Utils::t('No matchsetting');
+			}
+		}
+		else{
+			// Retour des erreurs de la méthode read
+			$out = $directory;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Enregistre la sélection du MatchSettings en session
+	*
+	* @param array $maps -> Le tableau de maps à ajouter à la sélection
+	*/
+	public static function saveMatchSettingSelection($maps = array() ){
+		// Liste des maps
+		$out = array();
+		if( isset($_SESSION['adminserv']['matchset_maps_selected']) ){
+			$mapsSelected = $_SESSION['adminserv']['matchset_maps_selected'];
+			if( isset($mapsSelected['lst']) && is_array($mapsSelected['lst']) && count($mapsSelected['lst']) > 0 ){
+				foreach($mapsSelected['lst'] as $id => $values){
+					$out['lst'][] = $values;
+				}
+			}
+		}
+		if( isset($maps['lst']) && is_array($maps['lst']) && count($maps['lst']) > 0 ){
+			foreach($maps['lst'] as $id => $values){
+				$out['lst'][] = $values;
+			}
+		}
+		if( isset($out['lst']) && count($out['lst']) > 0 ){
+			$out['lst'] = array_unique($out['lst'], SORT_REGULAR);
+		}
+		
+		// Nombre de maps
+		$out += self::getNbMaps($out);
+		if($out['nbm']['count'] == 0){
+			$out['lst'] = Utils::t('No map');
+		}
+		
+		// Mise à jour de la session
+		$_SESSION['adminserv']['matchset_maps_selected'] = $out;
+	}
+	
+	
+	/**
+	* Enregistre un MatchSettings
+	*
+	* @param string $filename -> L'url du dossier dans lequel le MatchSettings sera crée
+	* @param array  $struct   -> La structure du MatchSettings avec ses données
+	* $struct = Array
+	* (
+	*  [gameinfos] => Array
+	*   (
+	*    [game_mode] => 0
+	*    etc...
+	*   )
+	*  [hotseat] => Array()
+	*  [filter] => Array()
+	*  [startindex] => 1
+	*  [map] => Array
+	*   (
+	*    [8bDoQMwzUllV0D9eu7hSth3rQs6] => name.Map.Gbx
+	*    etc...
+	*   )
+	* )
+	* @return true si réussi, sinon une erreur
+	*/
+	public static function saveMatchSettings($filename, $struct){
+		$out = false;
+		
+		if(SERVER_VERSION_NAME == 'TmForever'){
+			$mapField = 'challenge';
+		}
+		else{
+			$mapField = 'map';
+		}
+		
+		$xml = new DOMDocument('1.0', 'utf-8');
+		$xml->formatOutput = true;
+		$playlist = $xml->createElement('playlist');
+		$playlist = $xml->appendChild($playlist);
+		
+		// GameInfos, Hotseat, Filter
+		$structFields = array(
+			'gameinfos',
+			'hotseat',
+			'filter'
+		);
+		foreach($structFields as $strucField){
+			if( isset($struct[$strucField]) && !empty($struct[$strucField]) ){
+				$node = $xml->createElement($strucField);
+				$node = $playlist->appendChild($node);
+				foreach($struct[$strucField] as $field => $value){
+					$childNode = $xml->createElement($field, $value);
+					$childNode = $node->appendChild($childNode);
+				}
+			}
+		}
+		
+		// Script settings
+		if( isset($struct['scriptsettings']) && !empty($struct['scriptsettings']) ){
+			$scriptsettings = $xml->createElement('mode_script_settings');
+			$scriptsettings = $playlist->appendChild($scriptsettings);
+			foreach($struct['scriptsettings'] as $settingParams){
+				$setting = $xml->createElement('setting');
+				$setting = $scriptsettings->appendChild($setting);
+				if( !empty($settingParams) ){
+					foreach($settingParams as $paramKey => $paramValue){
+						$param = $xml->createAttribute($paramKey);
+						$param->value = $paramValue;
+						$setting->appendChild($param);
+					}
+				}
+			}
+		}
+		
+		// Maps
+		$startindex = $xml->createElement('startindex', $struct['startindex']);
+		$startindex = $playlist->appendChild($startindex);
+		if( isset($struct[$mapField]) && !empty($struct[$mapField]) ){
+			foreach($struct[$mapField] as $dataIdent => $dataFile){
+				$map = $xml->createElement($mapField);
+				$map = $playlist->appendChild($map);
+				$file = $xml->createElement('file', $dataFile);
+				$file = $map->appendChild($file);
+				if(SERVER_VERSION_NAME == 'TmForever'){
+					$ident = $xml->createElement('ident', $dataIdent);
+					$ident = $map->appendChild($ident);
+				}
+			}
+		}
+		
+		if( !$xml->save($filename) ){
+			$out = Utils::t('Saving XML file error');
+		}
+		else{
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Extrait les données d'un MatchSettings et renvoi un tableau
+	*
+	* @param string $filename -> L'url du MatchSettings
+	* @param array  $list     -> Liste des champs à retourner
+	* @return array
+	*/
+	public static function getMatchSettingsData($filename, $list = array('gameinfos', 'hotseat', 'filter', 'scriptsettings', 'maps') ){
+		$out = array();
+		$xml = null;
+		
+		if( file_exists($filename) ){
+			$xml = new DOMDocument('1.0', 'utf-8');
+			$xml->load($filename);
+		}
+		
+		if($xml){
+			// Gameinfos
+			if( in_array('gameinfos', $list) ){
+				$fields = array(
+					'game_mode' => 'GameMode',
+					'chat_time' => 'ChatTime',
+					'finishtimeout' => 'FinishTimeout',
+					'allwarmupduration' => 'AllWarmUpDuration',
+					'disablerespawn' => 'DisableRespawn',
+					'forceshowallopponents' => 'ForceShowAllOpponents',
+					'rounds_pointslimit' => 'RoundsPointsLimit',
+					'rounds_custom_points' => 'RoundCustomPoints',
+					'rounds_usenewrules' => 'RoundsUseNewRules',
+					'rounds_forcedlaps' => 'RoundsForcedLaps',
+					'rounds_pointslimitnewrules' => 'RoundsPointsLimitNewRules',
+					'team_pointslimit' => 'TeamPointsLimit',
+					'team_maxpoints' => 'TeamMaxPoints',
+					'team_usenewrules' => 'TeamUseNewRules',
+					'team_pointslimitnewrules' => 'TeamPointsLimitNewRules',
+					'timeattack_limit' => 'TimeAttackLimit',
+					'timeattack_synchstartperiod' => 'TimeAttackSynchStartPeriod',
+					'laps_nblaps' => 'LapsNbLaps',
+					'laps_timelimit' => 'LapsTimeLimit',
+					'cup_pointslimit' => 'CupPointsLimit',
+					'cup_roundsperchallenge' => 'CupRoundsPerMap',
+					'cup_nbwinners' => 'CupNbWinners',
+					'cup_warmupduration' => 'CupWarmUpDuration',
+				);
+				if(SERVER_VERSION_NAME != 'TmForever'){
+					$fields['script_name'] = 'ScriptName';
+				}
+				
+				foreach($fields as $fieldXML => $fieldName){
+					$fieldList = $xml->getElementsByTagName($fieldXML);
+					if($fieldList->length > 0){
+						$out['gameinfos'][$fieldName] = $fieldList->item(0)->nodeValue;
+					}
+				}
+			}
+			
+			// Hotseat
+			if( in_array('hotseat', $list) ){
+				$fields = array(
+					'game_mode' => 'GameMode',
+					'time_limit' => 'TimeLimit',
+					'rounds_count' => 'RoundsCount',
+				);
+				
+				foreach($fields as $fieldXML => $fieldName){
+					$fieldList = $xml->getElementsByTagName($fieldXML);
+					if($fieldList->length > 0){
+						$out['hotseat'][$fieldName] = $fieldList->item(0)->nodeValue;
+					}
+				}
+			}
+			
+			// Filter
+			if( in_array('filter', $list) ){
+				$fields = array(
+					'is_lan' => 'IsLan',
+					'is_internet' => 'IsInternet',
+					'is_solo' => 'IsSolo',
+					'is_hotseat' => 'IsHotseat',
+					'sort_index' => 'SortIndex',
+					'random_map_order' => 'RandomMapOrder',
+					'force_default_gamemode' => 'ForceDefaultGameMode',
+				);
+				
+				foreach($fields as $fieldXML => $fieldName){
+					$fieldList = $xml->getElementsByTagName($fieldXML);
+					if($fieldList->length > 0){
+						$out['filter'][$fieldName] = $fieldList->item(0)->nodeValue;
+					}
+				}
+			}
+			
+			// Script Settings
+			if( in_array('scriptsettings', $list) ){
+				$scriptsettings = $xml->getElementsByTagName('setting');
+				if($scriptsettings->length > 0){
+					$i = 0;
+					foreach($scriptsettings as $setting){
+						if( $setting->hasAttributes() ){
+							foreach($setting->attributes as $attName => $attrNode) {
+								$out['scriptsettings'][$i][$attName] = $attrNode->value;
+							}
+						}
+						$i++;
+					}
+				}
+			}
+			
+			// Maps
+			if( in_array('maps', $list) ){
+				$fieldStartIndex = $xml->getElementsByTagName('startindex');
+				if($fieldStartIndex->length > 0){
+					$out['StartIndex'] = $fieldStartIndex->item(0)->nodeValue;
+				}
+				
+				$mapsField = (SERVER_VERSION_NAME == 'TmForever') ? 'challenge' : 'map';
+				$fieldMaps = $xml->getElementsByTagName($mapsField);
+				
+				foreach($fieldMaps as $map){
+					$ident = null;
+					$fieldIdent = $map->getElementsByTagName('ident');
+					if($fieldIdent->length > 0){
+						$ident = $fieldIdent->item(0)->nodeValue;
+					}
+					$file = null;
+					$fieldFile = $map->getElementsByTagName('file');
+					if($fieldFile->length > 0){
+						$file = $fieldFile->item(0)->nodeValue;
+					}
+					
+					if($ident){
+						$out['maps'][$ident] = $file;
+					}
+					else{
+						$out['maps'][] = $file;
+					}
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Met en forme les données des maps à partir d'un MatchSettings
+	*
+	* @global resource $client -> Le client doit être initialisé
+	* @param  array    $maps   -> Le tableau extrait du matchsettings : assoc array(ident => filename)
+	* @return array
+	*/
+	public static function getMapListFromMatchSetting($maps){
+		global $client;
+		$out = array();
+		$path = self::getMapsDirectoryPath();
+		$countMapList = count($maps);
+		
+		if($countMapList > 0){
+			$i = 0;
+			foreach($maps as $mapUId => $mapFileName){
+				if( in_array(File::getDoubleExtension($mapFileName), AdminServConfig::$MAP_EXTENSION) ){
+					// Données
+					if(SERVER_VERSION_NAME == 'TmForever'){
+						$Gbx = new GBXChallengeFetcher($path.Str::toSlash($mapFileName));
+					}
+					else{
+						$Gbx = new GBXChallMapFetcher();
+						$Gbx->processFile($path.Str::toSlash($mapFileName));
+					}
+					
+					// Name
+					$name = htmlspecialchars($Gbx->name, ENT_QUOTES, 'UTF-8');
+					$out['lst'][$i]['Name'] = TmNick::toHtml($name, 10, true);
+					
+					// Environnement
+					$env = $Gbx->envir;
+					if($env == 'Speed'){ $env = 'Desert'; }else if($env == 'Alpine'){ $env = 'Snow'; }
+					$out['lst'][$i]['Environment'] = $env;
+					
+					// Autres
+					$out['lst'][$i]['FileName'] = $mapFileName;
+					$out['lst'][$i]['UId'] = $Gbx->uid;
+					$out['lst'][$i]['Author'] = $Gbx->author;
+					$i++;
+				}
+			}
+		}
+		
+		// Nombre de maps
+		$out += self::getNbMaps($out);
+		if($out['nbm']['count'] == 0){
+			$out['lst'] = Utils::t('No map');
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Extrait les données d'une playlist (blacklist ou guestlist)
+	*
+	* @param string $filename -> L'url de la playlist
+	* @return array
+	*/
+	public static function getPlaylistData($filename){
+		$out = array();
+		
+		$xml = null;
+		if( file_exists($filename) ){
+			$xml = new DOMDocument('1.0', 'utf-8');
+			$xml->load($filename);
+		}
+		
+		if($xml){
+			$root = $xml->documentElement;
+			$out['type'] = $root->nodeName;
+			$players = $xml->getElementsByTagName($root->nodeName);
+			foreach($players as $player){
+				$login = $player->getElementsByTagName('login');
+				if($login->length > 0){
+					$out['logins'][] = $login->item(0)->nodeValue;
+				}
+			}
+		}
+		
+		return $out;
+	}
+}
+?>
diff --git a/resources/core/cache.php b/resources/core/cache.php
new file mode 100644
index 0000000..e11d1e4
--- /dev/null
+++ b/resources/core/cache.php
@@ -0,0 +1,125 @@
+<?php
+
+/**
+* Classe pour la gestion du cache
+*/
+class AdminServCache {
+	private $folder;
+	
+	/**
+	* Initialisation du cache
+	*/
+	function __construct(){
+		$this->folder = AdminServConfig::$PATH_RESOURCES.'cache/';
+		
+		if( !file_exists($this->folder) ){
+			Folder::create($this->folder);
+		}
+	}
+	
+	
+	/**
+	* Enregistre la valeur dans un fichier
+	*
+	* @param string $key   -> Clef du cache
+	* @param array  $value -> Valeur à enregistrer
+	* @return bool
+	*/
+	public function set($key, $value){
+		$out = false;
+		$file = $this->folder . $key . '.json';
+		$data = json_encode($value);
+		
+		if( file_exists($file) ){
+			if( File::save($file, $data, false) ){
+				$out = true;
+			}
+		}
+		else{
+			if( File::save($file) ){
+				self::set($key, $value);
+			}
+		}
+		
+		$error = self::getErrorMsg('set');
+		if($error){
+			$out = false;
+			AdminServ::error($error);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la valeur depuis un fichier
+	*
+	* @param string $key -> Clef du cache à récupérer
+	* @return array()
+	*/
+	public function get($key){
+		$out = array();
+		$file = $this->folder . $key . '.json';
+		
+		if( file_exists($file) ){
+			$data = file_get_contents($file);
+			$out = json_decode($data, true);
+		}
+		
+		$error = self::getErrorMsg('get');
+		if($error){
+			$out = array();
+			AdminServ::error($error);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Supprime un fichier de cache
+	*
+	* @param string $key -> Clef du cache à supprimer
+	* @return bool
+	*/
+	public function delete($key){
+		$out = false;
+		$file = $this->folder . $key . '.json';
+		
+		if( file_exists($file) ){
+			if( ($result = File::delete($file)) !== true ){
+				AdminServ::error($result);
+			}
+			else{
+				$out = true;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le message d'erreur lors de l'encodage/décodage du JSON
+	*/
+	public static function getErrorMsg($type){
+		switch( json_last_error() ){
+			case JSON_ERROR_DEPTH:
+				return 'CACHE ('.$type.') - Profondeur maximale atteinte';
+				break;
+			case JSON_ERROR_STATE_MISMATCH:
+				return 'CACHE ('.$type.') - Inadéquation des modes ou underflow';
+				break;
+			case JSON_ERROR_CTRL_CHAR:
+				return 'CACHE ('.$type.') - Erreur lors du contrôle des caractères';
+				break;
+			case JSON_ERROR_SYNTAX:
+				return 'CACHE ('.$type.') - Erreur de syntaxe ; JSON malformé';
+				break;
+			case JSON_ERROR_UTF8:
+				return 'CACHE ('.$type.') - Caractères UTF-8 malformés, probablement une erreur d\'encodage';
+				break;
+		}
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/core/event.php b/resources/core/event.php
new file mode 100644
index 0000000..c7e9d73
--- /dev/null
+++ b/resources/core/event.php
@@ -0,0 +1,86 @@
+<?php
+
+/**
+* Classe pour la gestion des événements
+*/
+class AdminServEvent {
+	
+	/**
+	* Retourne les arguments d'AdminServ
+	*/
+	public static function getArgs(){
+		global $args;
+		
+		if( isset($_GET['p']) ){
+			define('USER_PAGE', htmlspecialchars($_GET['p']) );
+		}
+		else{
+			if( isset($_SESSION['adminserv']['check_password']) || isset($_SESSION['adminserv']['get_password']) ){
+				define('USER_PAGE', 'servers-online-config');
+			}
+			else{
+				define('USER_PAGE', 'index');
+			}
+		}
+		
+		if( isset($_GET['c']) ){ $args['category'] = addslashes( htmlspecialchars($_GET['c']) ); }else{ $args['category'] = null; }
+		if( isset($_GET['view']) ){ $args['view'] = addslashes( htmlspecialchars($_GET['view']) ); }else{ $args['view'] = null; }
+		if( isset($_GET['i']) ){ $args['index'] = intval($_GET['i']); }else{ $args['index'] = -1; }
+		if( isset($_GET['id']) ){ $args['id'] = intval($_GET['id']); }else{ $args['id'] = -1; }
+		if( isset($_GET['d']) ){ $args['directory'] = addslashes( urldecode($_GET['d']) ); }else{ $args['directory'] = null; }
+		if( isset($_GET['th']) ){ $args['theme'] = addslashes($_GET['th']); }else{ $args['theme'] = null; }
+		if( isset($_GET['lg']) ){ $args['lang'] = addslashes($_GET['lg']); }else{ $args['lang'] = null; }
+	}
+	
+	
+	/**
+	* Permet de changer de serveur
+	*/
+	public static function switchServer(){
+		if( isset($_GET['switch']) && $_GET['switch'] != null ){
+			$_SESSION['adminserv']['sid'] = AdminServServerConfig::getServerId($_GET['switch']);
+			$_SESSION['adminserv']['name'] = $_GET['switch'];
+			unset($_SESSION['adminserv']['teaminfo']);
+			Utils::addCookieData('adminserv', array($_SESSION['adminserv']['sid'], Utils::readCookieData('adminserv', 1)), AdminServConfig::COOKIE_EXPIRE);
+			
+			if(USER_PAGE && USER_PAGE != 'index'){
+				Utils::redirection(false, '?p='.USER_PAGE);
+			}
+			else{
+				Utils::redirection();
+			}
+		}
+	}
+	
+	
+	/**
+	* Vérifie si on est connecté au serveur
+	*/
+	public static function isLoggedIn(){
+		$out = false;
+		
+		if( isset($_SESSION['adminserv']['sid']) && isset($_SESSION['adminserv']['password']) && isset($_SESSION['adminserv']['adminlevel']) && !isset($_GET['error']) ){
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Déconnexion
+	*/
+	public static function logout(){
+		if( isset($_GET['error']) || isset($_GET['logout']) ){
+			$adminservPath = $_SESSION['adminserv']['path'];
+			session_unset();
+			session_destroy();
+			session_start();
+			$_SESSION['adminserv']['path'] = $adminservPath;
+			if( isset($_GET['logout']) ){
+				Utils::redirection(false);
+			}
+		}
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/core/logs.php b/resources/core/logs.php
new file mode 100644
index 0000000..adea87c
--- /dev/null
+++ b/resources/core/logs.php
@@ -0,0 +1,95 @@
+<?php
+
+/**
+* Classe pour le traitement des logs AdminServ
+*/
+class AdminServLogs {
+	/**
+	* Globales
+	*/
+	public static $LOGS_PATH = './logs/';
+	
+	/**
+	* Initialise les logs (vérification des droits, création des fichiers)
+	* @return bool
+	*/
+	public static function initialize(){
+		$out = false;
+		$error = null;
+		
+		if( in_array(true, AdminServConfig::$LOGS) ){
+			if( file_exists(self::$LOGS_PATH) ){
+				if( is_writable(self::$LOGS_PATH) ){
+					$out = true;
+				}
+				else{
+					$error = Utils::t('The folder "logs" is not writable.');
+				}
+			}
+			else{
+				$error = Utils::t('The folder "logs" does not exist.');
+			}
+		}
+		
+		if($out){
+			if( count(AdminServConfig::$LOGS) > 0 ){
+				foreach(AdminServConfig::$LOGS as $file => $activate){
+					$path = self::$LOGS_PATH.$file.'.log';
+					if($activate && !file_exists($path) ){
+						if( File::save($path) !== true ){
+							$error = Utils::t('Unable to create log file:').' '.$file.'.';
+							$out = false;
+							break;
+						}
+					}
+				}
+			}
+		}
+		
+		if($error){
+			if($_SESSION['error'] != null){
+				$_SESSION['error'] .= '<br />'.$error;
+			}
+			else{
+				$_SESSION['error'] = $error;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Ajoute un log au fichier correspondant
+	*
+	* @param string $type -> Type de log : access, action, etc
+	* @param string $str  -> Ligne de log à écrire
+	* @return bool
+	*/
+	public static function add($type, $str){
+		$out = false;
+		$type = strtolower($type);
+		if( defined('USER_PAGE') ){ $userPage = USER_PAGE; }else{ $userPage = 'index'; }
+		if( defined('SERVER_NAME') ){ $serverName = '['.utf8_decode(SERVER_NAME).'] '; }else{ $serverName = null; }
+		$str = '['.date('d/m/Y H:i:s').'] ['.$_SERVER['REMOTE_ADDR'].'] : '.$serverName.'['.$userPage.'] '.utf8_decode($str)."\n";
+		$path = self::$LOGS_PATH.$type.'.log';
+		
+		if( file_exists($path) ){
+			if( File::save($path, utf8_encode($str) ) !== true ){
+				$error = Utils::t('Unable to add log in file:').' '.$type.'.';
+				if($_SESSION['error'] != null){
+					$_SESSION['error'] .= '<br />'.$error;
+				}
+				else{
+					$_SESSION['error'] = $error;
+				}
+			}
+			else{
+				$out = true;
+			}
+		}
+		
+		return $out;
+	}
+}
+?>
diff --git a/resources/core/plugin.php b/resources/core/plugin.php
new file mode 100644
index 0000000..c96215b
--- /dev/null
+++ b/resources/core/plugin.php
@@ -0,0 +1,253 @@
+<?php
+
+/**
+* Classe pour la gestion des plugins
+*/
+class AdminServPlugin {
+	
+	/**
+	* Tente de récupérer une config des plugins à partir d'un autre fichier
+	*/
+	public static function setPluginsList(){
+		$otherPluginsList = AdminServConfig::PLUGINS_LIST;
+		
+		if($otherPluginsList){
+			if( file_exists($otherPluginsList) ){
+				include_once $otherPluginsList;
+				
+				if( isset($PLUGINS) ){
+					if(AdminServConfig::PLUGINS_LIST_TYPE == 'add'){
+						ExtensionConfig::$PLUGINS = array_merge(ExtensionConfig::$PLUGINS, $PLUGINS);
+					}
+					else{
+						ExtensionConfig::$PLUGINS = $PLUGINS;
+					}
+				}
+				else{
+					AdminServ::error( Utils::t('Variable "$PLUGINS" not found.') );
+				}
+			}
+			else{
+				AdminServ::error( Utils::t('Cannot include another plugins config file.') );
+			}
+		}
+	}
+	
+	
+	/**
+	* Détermine s'il y a au moins un plugin disponible
+	*
+	* @param string $pluginName -> Test un plugin en particulier
+	* @return bool
+	*/
+	public static function hasPlugin($pluginName = null){
+		$out = false;
+		
+		if( class_exists('ExtensionConfig') ){
+			if( isset(ExtensionConfig::$PLUGINS) && count(ExtensionConfig::$PLUGINS) > 0 ){
+				foreach(ExtensionConfig::$PLUGINS as $plugin){
+					$pluginConfig = self::getConfig($plugin);
+					if( ($pluginConfig['game'] == SERVER_VERSION_NAME || $pluginConfig['game'] == 'all') && AdminServAdminLevel::isType($pluginConfig['adminlevel']) ){
+						if($pluginName){
+							if($pluginName == $plugin){
+								$out = true;
+							}
+						}
+						else{
+							$out = true;
+						}
+					}
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le plugin courant
+	*
+	* @return pluginName
+	*/
+	public static function getCurrent(){
+		$out = null;
+		
+		if( defined('USER_PAGE') ){
+			$pageEx = explode('-', USER_PAGE);
+			if( count($pageEx) > 0 && isset($pageEx[0]) && $pageEx[0] == 'plugins' ){
+				if( isset($pageEx[1]) && $pageEx[1] != 'list' ){
+					$out = $pageEx[1];
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la config du plugin grâce au fichier config.ini
+	*
+	* @param string $pluginName  -> Le nom du dossier plugin
+	* @param string $returnField -> Retourner un champ en particulier
+	* @return array ou string si le 2ème paramètre est spécifié
+	*/
+	public static function getConfig($pluginName = null, $returnField = null){
+		$out = null;
+		if($pluginName === null){
+			$pluginName = USER_PLUGIN;
+		}
+		$path = AdminServConfig::$PATH_PLUGINS .$pluginName.'/config.ini';
+		
+		if( file_exists($path) ){
+			$ini = parse_ini_file($path);
+			if($returnField && isset($ini[$returnField]) ){
+				$out = $ini[$returnField];
+			}
+			else{
+				$out = $ini;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne une liste html pour le menu des plugins
+	*
+	* @return html
+	*/
+	public static function getMenuList(){
+		$out = null;
+		$pluginsList = array();
+		if( count(ExtensionConfig::$PLUGINS) > 0 ){
+			foreach(ExtensionConfig::$PLUGINS as $plugin){
+				$pluginInfos = self::getConfig($plugin);
+				if( ($pluginInfos['game'] == 'all' || $pluginInfos['game'] == SERVER_VERSION_NAME) && AdminServAdminLevel::isType($pluginInfos['adminlevel']) ){
+					$pluginsList[$plugin] = $pluginInfos;
+				}
+			}
+		}
+		
+		if( count($pluginsList) > 0 ){
+			$out = '<nav class="vertical-nav">'
+				.'<ul>';
+					foreach($pluginsList as $plugin => $infos){
+						$out .= '<li><a '; if(self::getCurrent() == $plugin){ $out .= 'class="active" '; } $out .= 'href="?p=plugins-'.$plugin.'" title="'.Utils::t('Version').' : '.$infos['version'].'">'.$infos['name'].'</a></li>';
+					}
+				$out .= '</ul>'
+			.'</nav>';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Compte le nombre de plugins installés
+	*
+	* @return array
+	*/
+	public static function countPlugins(){
+		$out = array();
+		$pluginsList = array();
+		if( self::hasPlugin() ){
+			foreach(ExtensionConfig::$PLUGINS as $plugin){
+				$pluginInfos = self::getConfig($plugin);
+				if($pluginInfos['game'] == 'all' || $pluginInfos['game'] == SERVER_VERSION_NAME){
+					$pluginsList[] = $plugin;
+				}
+			}
+		}
+		
+		$out['count'] = count($pluginsList);
+		if($out['count'] > 1){
+			$out['title'] = Utils::t('plugins installed');
+		}
+		else{
+			$out['title'] = Utils::t('plugin installed');
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Inclue les fichiers pour le rendu d'un plugin
+	*
+	* @param string $pluginName -> Le nom du dossier plugin
+	* @return html
+	*/
+	public static function renderPlugin($pluginName = null) {
+		global $client, $translate, $args;
+		if($pluginName === null){
+			$pluginName = USER_PLUGIN;
+		}
+		
+		// Tente de récupérer les plugins d'une autre config
+		self::setPluginsList();
+		
+		// Création du rendu du plugin
+		$pluginPath = AdminServConfig::$PATH_PLUGINS .$pluginName.'/';
+		$scriptFile = $pluginPath.'script.php';
+		$viewFile = $pluginPath.'view.php';
+		if (file_exists($scriptFile) && file_exists($viewFile)) {
+			// Process
+			require_once $scriptFile;
+			
+			// Terminate client
+			if (isset($client) && $client->socket != null) {
+				$client->Terminate();
+			}
+			
+			// Header
+			AdminServUI::getHeader();
+			
+			// Content
+			echo '<section class="plugins hasMenu">'
+				.'<section class="cadre left menu">'
+					.self::getMenuList()
+				.'</section>'
+				
+				.'<section class="cadre right">'
+					.'<h1>'.self::getConfig($pluginName, 'name').'</h1>';
+					require_once $viewFile;
+				echo '</section>'
+			.'</section>';
+			
+			// Footer
+			AdminServUI::getFooter();
+			
+			AdminServLogs::add('access', 'Plugin: '.$pluginName);
+		}
+		else {
+			AdminServ::error( Utils::t('Plugin error: script.php or view.php file is missing.') );
+			AdminServUI::getHeader();
+			AdminServUI::getFooter();
+		}
+	}
+	
+	
+	/**
+	* Récupère le chemin du dossier plugin
+	*
+	* @param string $pluginName -> Le nom du dossier plugin
+	* @return string
+	*/
+	public static function getPluginPath($pluginName = null){
+		$out = null;
+		if($pluginName === null){
+			$pluginName = USER_PLUGIN;
+		}
+		$path = AdminServConfig::$PATH_PLUGINS;
+		
+		if($path && $pluginName){
+			$out = $path.$pluginName.'/';
+		}
+		
+		return $out;
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/core/server.php b/resources/core/server.php
new file mode 100644
index 0000000..0bc3119
--- /dev/null
+++ b/resources/core/server.php
@@ -0,0 +1,258 @@
+<?php
+
+/**
+* Classe pour la gestion de la configuration serveur
+*/
+class AdminServServerConfig {
+	
+	/**
+	* Constantes
+	*/
+	private static $CONFIG_PATH = './config/';
+	private static $CONFIG_FILENAME = 'servers.cfg.php';
+	private static $CONFIG_START_TEMPLATE = "<?php\nclass ServerConfig {\n\tpublic static \$SERVERS = array(\n\t\t/********************* SERVER CONFIGURATION *********************/\n\t\t\n";
+	private static $CONFIG_END_TEMPLATE =  "\t);\n}\n?>";
+	
+	
+	/**
+	* Détermine si il y a au moins un serveur disponible
+	*
+	* @param string $serverName -> Tester si le serveur est présent
+	* @return bool
+	*/
+	public static function hasServer($serverName = null){
+		$out = false;
+		
+		if (class_exists('ServerConfig')) {
+			$serverList = ServerConfig::$SERVERS;
+			
+			if (isset($serverList) && !empty($serverList) && !isset($serverList['new server name']) && !isset($serverList[''])) {
+				if ($serverName) {
+					foreach ($serverList as $serverListName => $serverListData) {
+						if ($serverListName === $serverName) {
+							$out = true;
+							break;
+						}
+					}
+				}
+				else {
+					$out = true;
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère les données d'un serveur
+	*
+	* @param string $serverName -> Le nom du serveur dans la config
+	* @return array
+	*/
+	public static function getServer($serverName){
+		$out = null;
+		
+		if( self::hasServer() ){
+			if( isset(ServerConfig::$SERVERS[$serverName]) ){
+				$out = ServerConfig::$SERVERS[$serverName];
+			}
+			else{
+				$out = Utils::t('This server does not exist');
+			}
+		}
+		else{
+			$out = Utils::t('No server available');
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne l'identifiant du serveur dans la config
+	*
+	* @param  string $serverName -> Le nom du serveur dans la config
+	* @return int
+	*/
+	public static function getServerId($serverName){
+		$id = 0;
+		$servers = ServerConfig::$SERVERS;
+		$countServers = count($servers);
+		
+		// On cherche la position du serveur à partir de son nom
+		if( $countServers > 0 ){
+			foreach($servers as $server_name => $server_values){
+				if($server_name == $serverName){
+					break;
+				}
+				else{
+					$id++;
+				}
+			}
+		}
+		
+		// Si l'id = le nb total de serveur -> pas trouvé
+		if($id == $countServers ){
+			return -1;
+		}
+		else{
+			return $id;
+		}
+	}
+	
+	
+	/**
+	* Retourne le nom du serveur dans la config
+	*
+	* @param  int $serverId -> L'id du serveur dans la config
+	* @return string
+	*/
+	public static function getServerName($serverId){
+		$out = null;
+		$servers = ServerConfig::$SERVERS;
+		
+		if( count($servers) > 0 ){
+			$i = 0;
+			foreach($servers as $serverName => $serverValues){
+				if($i == $serverId){
+					$out = $serverName;
+					break;
+				}
+				else{
+					$i++;
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Créer le template d'un serveur
+	*
+	* @param array $serverData -> assoc array(name, address, port, mapsbasepath, matchsettings, adminlevel => array(SuperAdmin, Admin, User));
+	*/
+	public static function getServerTemplate($serverData){
+		$out = "\t\t'".$serverData['name']."' => array(\n"
+			."\t\t\t'address'\t\t=> '".$serverData['address']."',\n"
+			."\t\t\t'port'\t\t\t=> ".$serverData['port'].",\n"
+            ."\t\t\t'ds_pw'\t\t\t=> '".$serverData['ds_pw']."',\n"
+			."\t\t\t'mapsbasepath'\t=> '".$serverData['mapsbasepath']."',\n"
+			."\t\t\t'matchsettings'\t=> '".$serverData['matchsettings']."',\n"
+			."\t\t\t'adminlevel'\t=> array(";
+			$adminlevelId = 0;
+			$adminlevelCount = count($serverData['adminlevel']);
+			foreach($serverData['adminlevel'] as $admLvlId => $admLvlValue){
+				$out .= "'$admLvlId' => ";
+				if( is_array($serverData['adminlevel'][$admLvlId]) ){
+					$out .= "'".implode("', '", str_replace(' ', '', $serverData['adminlevel'][$admLvlId]))."'";
+				}
+				else{
+					$out .= "'".$serverData['adminlevel'][$admLvlId]."'";
+				}
+				
+				if($adminlevelId < $adminlevelCount-1){
+					$out .= ', ';
+				}
+				$adminlevelId++;
+			}
+		$out .= ")\n\t\t),\n";
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Sauvegarde le mot de passe de la configuration serveur
+	*
+	* @param string $filename -> Le chemin vers le fichier de config
+	* @param string $password -> Le mot de passe à écrire
+	* @return true or text error
+	*/
+	public static function savePasswordConfig($filename, $password){
+		$out = false;
+		$seek = null;
+		
+		// Récupération du pointeur
+		$search = 'const PASSWORD = \'';
+		$seek = File::getSeekFromString($filename, $search, true);
+		
+		// Écriture dans le fichier
+		if($seek !== null){
+			if( ($result = File::saveAtSeek($filename, $password, $seek)) !== true ){
+				$out = $result;
+			}
+			else{
+				$out = true;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Sauvegarde le fichier de configuration des serveurs
+	*
+	* @param array $serverData -> assoc array(name, address, port, matchsettings, adminlevel => array(SuperAdmin, Admin, User));
+	* @param int   $editServer -> Id du serveur à éditer
+	* @param array $serverList -> Liste des serveurs de la config
+	* @return bool or string error
+	*/
+	public static function saveServerConfig($serverData = array(), $editServer = -1, $serverList = array() ){
+		// Liste des serveurs
+		if( isset($serverList) && count($serverList) > 0 ){
+			$servers = $serverList;
+		}else{
+			$servers = ServerConfig::$SERVERS;
+		}
+		
+		// Template
+		$fileTemplate = self::$CONFIG_START_TEMPLATE;
+		$i = 0;
+		foreach($servers as $serverName => $serverValues){
+			// Édition
+			if($i == $editServer && isset($serverData) && count($serverData) > 0 ){
+				$fileTemplate .= self::getServerTemplate($serverData);
+			}
+			else{
+				// Récupération des données des serveurs existant
+				$getServerValues = array(
+					'name' => $serverName,
+					'address' => $serverValues['address'],
+					'port' => $serverValues['port'],
+                    'ds_pw' => $serverValues['ds_pw'],
+					'mapsbasepath' => isset($serverValues['mapsbasepath']) ? $serverValues['mapsbasepath'] : '',
+					'matchsettings' => $serverValues['matchsettings'],
+					'adminlevel' => array()
+				);
+				foreach($serverValues['adminlevel'] as $admLvlId => $admLvlValue){
+					$getServerValues['adminlevel'][$admLvlId] = $admLvlValue;
+				}
+				
+				// Ajout des données au template
+				$fileTemplate .= self::getServerTemplate($getServerValues);
+			}
+			$i++;
+		}
+		
+		// Ajout d'un nouveau
+		if($editServer === -1 && isset($serverData) && count($serverData) > 0 ){
+			if( self::getServerId($serverData['name']) === -1 ){
+				$fileTemplate .= self::getServerTemplate($serverData);
+			}
+			else{
+				return Utils::t('The server already exist! Change the name.');
+			}
+		}
+		$fileTemplate .= self::$CONFIG_END_TEMPLATE;
+		
+		// Enregistrement
+		return File::save(self::$CONFIG_PATH.self::$CONFIG_FILENAME, $fileTemplate, false);
+	}
+}
+
+?>
diff --git a/resources/core/sort.php b/resources/core/sort.php
new file mode 100644
index 0000000..ecd7e6a
--- /dev/null
+++ b/resources/core/sort.php
@@ -0,0 +1,127 @@
+<?php
+
+/**
+* Classe pour le traitement des tris AdminServ
+*/
+class AdminServSort {
+	
+	
+	public static function sortByNickName($a, $b){
+		$a = TmNick::toText($a['NickName']);
+		$b = TmNick::toText($b['NickName']);
+		
+		if($a == $b){
+			return 0;
+		}
+		return ($a < $b) ? -1 : 1;
+	}
+	public static function sortByLadderRanking($a, $b){
+		if($a['LadderRanking'] == $b['LadderRanking']){
+			return 0;
+		}
+		return ($a['LadderRanking'] < $b['LadderRanking']) ? -1 : 1;
+	}
+	public static function sortByLogin($a, $b){
+		if($a['Login'] == $b['Login']){
+			return 0;
+		}
+		return ($a['Login'] < $b['Login']) ? -1 : 1;
+	}
+	public static function sortByStatus($a, $b){
+		if($a['SpectatorStatus'] == $b['SpectatorStatus']){
+			return 0;
+		}
+		return ($a['SpectatorStatus'] < $b['SpectatorStatus']) ? -1 : 1;
+	}
+	public static function sortByTeam($a, $b){
+		if($a['TeamId'] == 0){
+			$a['TeamId'] = 'blue';
+		}else if($a['TeamId'] == 1){
+			$a['TeamId'] = 'red';
+		}else{
+			$a['TeamId'] = 'spectator';
+		}
+		if($b['TeamId'] == 0){
+			$b['TeamId'] = 'blue';
+		}else if($b['TeamId'] == 1){
+			$b['TeamId'] = 'red';
+		}else{
+			$b['TeamId'] = 'spectator';
+		}
+		
+		if($a['TeamId'] == $b['TeamId']){
+			return 0;
+		}
+		return ($a['TeamId'] < $b['TeamId']) ? -1 : 1;
+	}
+	
+	/* Maps-list */
+	public static function sortByFileName($a, $b){
+		if($a['FileName'] == $b['FileName']){
+			return 0;
+		}
+		return ($a['FileName'] < $b['FileName']) ? -1 : 1;
+	}
+	public static function sortByName($a, $b){
+		$a = strip_tags($a['Name']);
+		$b = strip_tags($b['Name']);
+		
+		if($a == $b){
+			return 0;
+		}
+		return ($a < $b) ? -1 : 1;
+	}
+	public static function sortByEnviro($a, $b){
+		if($a['Environment'] == 'Speed'){
+			$a['Environment'] = 'Desert';
+		}
+		if($b['Environment'] == 'Speed'){
+			$b['Environment'] = 'Desert';
+		}
+		if($a['Environment'] == 'Alpine'){
+			$a['Environment'] = 'Snow';
+		}
+		if($b['Environment'] == 'Alpine'){
+			$b['Environment'] = 'Snow';
+		}
+		
+		if($a['Environment'] == $b['Environment']){
+			return 0;
+		}
+		return ($a['Environment'] < $b['Environment']) ? -1 : 1;
+	}
+	public static function sortByType($a, $b){
+		if($a['Type']['Name'] == $b['Type']['Name']){
+			return 0;
+		}
+		return ($a['Type']['Name'] < $b['Type']['Name']) ? -1 : 1;
+	}
+	public static function sortByAuthor($a, $b){
+		$a = strtolower($a['Author']);
+		$b = strtolower($b['Author']);
+		
+		if($a == $b){
+			return 0;
+		}
+		return ($a < $b) ? -1 : 1;
+	}
+	public static function sortByGoldTime($a, $b){
+		if($a['GoldTime'] == $b['GoldTime']){
+			return 0;
+		}
+		return ($a['GoldTime'] < $b['GoldTime']) ? -1 : 1;
+	}
+	public static function sortByPrice($a, $b){
+		if($a['CopperPrice'] == $b['CopperPrice']){
+			return 0;
+		}
+		return ($a['CopperPrice'] < $b['CopperPrice']) ? -1 : 1;
+	}
+	public static function sortByRank($a, $b){
+		if($a['Rank'] == $b['Rank']){
+			return 0;
+		}
+		return ($a['Rank'] < $b['Rank']) ? -1 : 1;
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/core/ui.php b/resources/core/ui.php
new file mode 100644
index 0000000..4b3fee5
--- /dev/null
+++ b/resources/core/ui.php
@@ -0,0 +1,672 @@
+<?php
+
+/**
+* Classe pour l'interface d'AdminServ
+*/
+class AdminServUI {
+	
+	/**
+	* Récupère le titre de l'application
+	*
+	* @param string $type -> Retourner "str" ou "html"
+	* @return string
+	*/
+	public static function getTitle($type = 'str'){
+		$out = null;
+		$title = AdminServConfig::TITLE;
+		if(!$title){
+			$title = 'Admin,Serv';
+		}
+		
+		if($type == 'html'){
+			if( strstr($title, ',') ){
+				$out = str_replace(',', '<span class="title-color">', $title).'</span>';
+			}
+			else{
+				$out = $title;
+			}
+		}
+		else{
+			$out = str_replace(',', '', $title);
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Vérifie s'il y a bien une config de theme
+	*/
+	public static function hasTheme(){
+		$out = false;
+		
+		if( class_exists('ExtensionConfig') && isset(ExtensionConfig::$THEMES) && count(ExtensionConfig::$THEMES) > 0 ){
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le thème courant ou
+	*
+	* @param string $setTheme -> Utiliser un autre thème
+	* @return $_SESSION['theme']
+	*/
+	public static function theme($setTheme = null){
+		$saveCookie = false;
+		
+		if($setTheme){
+			$_SESSION['theme'] = $setTheme;
+			$saveCookie = true;
+		}
+		else{
+			if( !isset($_SESSION['theme']) ){
+				if( isset($_COOKIE['adminserv_user']) ){
+					$_SESSION['theme'] = Utils::readCookieData('adminserv_user', 0);
+				}
+				else{
+					if(AdminServConfig::DEFAULT_THEME){
+						$_SESSION['theme'] = AdminServConfig::DEFAULT_THEME;
+					}
+					else{
+						$_SESSION['theme'] = 'red';
+					}
+					$saveCookie = true;
+				}
+			}
+		}
+		
+		if($saveCookie){
+			$cookieData = array(
+				$_SESSION['theme'],
+				self::lang(),
+				Utils::readCookieData('adminserv_user', 2),
+				Utils::readCookieData('adminserv_user', 3)
+			);
+			
+			Utils::addCookieData('adminserv_user', $cookieData, AdminServConfig::COOKIE_EXPIRE);
+		}
+		
+		if($setTheme){
+			if(USER_PAGE == 'index'){
+				Utils::redirection();
+			}
+			else{
+				Utils::redirection(false, '?p='.USER_PAGE);
+			}
+		}
+		
+		return strtolower($_SESSION['theme']);
+	}
+	
+	
+	/**
+	* Récupère la couleur définie dans le thème
+	*
+	* @param int $indexColor -> Index de la couleur à récupérer
+	* @return string code hexa
+	*/
+	public static function getThemeColor($indexColor = 0){
+		$out = null;
+		
+		if( self::hasTheme() && ($theme = self::theme()) ){
+			if( isset(ExtensionConfig::$THEMES[$theme]) && isset(ExtensionConfig::$THEMES[$theme][$indexColor]) ){
+				$out = ExtensionConfig::$THEMES[$theme][$indexColor];
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la liste des thèmes
+	*/
+	public static function getThemeList($currentTheme = array() ){
+		$out = null;
+		$list = array();
+		if( self::hasTheme() ){
+			$list = ExtensionConfig::$THEMES;
+		}
+		$countList = count($list);
+		
+		// Page courante
+		if(USER_PAGE && USER_PAGE != 'index'){
+			$param = '?p='.USER_PAGE .'&amp;th=';
+		}
+		else{
+			$param = '?th=';
+		}
+		
+		if( $countList > 0 ){
+			$out .= '<ul>';
+			// S'il y a un thème courant, on le place en 1er
+			if( count($currentTheme) > 0 ){
+				$currentThemeName = key($currentTheme);
+				$currentThemeColor = current($currentTheme);
+				unset($list[$currentThemeName]);
+				$out .= '<li><a tabindex="-1" class="theme-color" style="background-color: '.$currentThemeColor[0].';" href="'.$param.$currentThemeName.'" title="'.Utils::t( ucfirst($currentThemeName) ).'"></a></li>';
+			}
+			foreach($list as $name => $color){
+				$out .= '<li><a tabindex="-1" class="theme-color" style="background-color: '.$color[0].';" href="'.$param.$name.'" title="'.Utils::t( ucfirst($name) ).'"></a></li>';
+			}
+			$out .= '</ul>';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Vérifie s'il y a bien une config de langue
+	*/
+	public static function hasLang(){
+		$out = false;
+		
+		if( class_exists('ExtensionConfig') && isset(ExtensionConfig::$LANG) && count(ExtensionConfig::$LANG) > 0 ){
+			$out = true;
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la langue courante
+	*
+	* @param string $setLang -> Forcer l'utilisation de la langue
+	* @return $_SESSION['lang']
+	*/
+	public static function lang($setLang = null){
+		global $translate;
+		$saveCookie = false;
+		
+		if($setLang){
+			$_SESSION['lang'] = $setLang;
+			$saveCookie = true;
+		}
+		else{
+			if( !isset($_SESSION['lang']) ){
+				if( isset($_COOKIE['adminserv_user']) ){
+					$_SESSION['lang'] = Utils::readCookieData('adminserv_user', 1);
+				}
+				else{
+					if( AdminServConfig::DEFAULT_LANGUAGE == 'auto' ){
+						$_SESSION['lang'] = 'en';
+						$autoLangCode = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
+						if( self::hasLang() ){
+							if( in_array($autoLangCode, ExtensionConfig::$LANG) ){
+								$_SESSION['lang'] = $autoLangCode;
+							}
+						}
+					}
+					else{
+						if(AdminServConfig::DEFAULT_LANGUAGE){
+							$_SESSION['lang'] = AdminServConfig::DEFAULT_LANGUAGE;
+						}
+						else{
+							$_SESSION['lang'] = 'en';
+						}
+					}
+					$saveCookie = true;
+				}
+			}
+		}
+		
+		if($saveCookie){
+			$cookieData = array(
+				self::theme(),
+				$_SESSION['lang'],
+				Utils::readCookieData('adminserv_user', 2),
+				Utils::readCookieData('adminserv_user', 3)
+			);
+			
+			Utils::addCookieData('adminserv_user', $cookieData, AdminServConfig::COOKIE_EXPIRE);
+		}
+		
+		if($setLang){
+			if(USER_PAGE == 'index'){
+				Utils::redirection();
+			}
+			else{
+				Utils::redirection(false, '?p='.USER_PAGE);
+			}
+		}
+		
+		$langCode = strtolower($_SESSION['lang']);
+		$langFile = AdminServConfig::$PATH_RESOURCES .'lang/'.$langCode.'.php';
+		if( file_exists($langFile) ){
+			require_once $langFile;
+		}
+		
+		return $langCode;
+	}
+	
+	
+	/**
+	* Récupère la liste des langues
+	*/
+	public static function getLangList($currentLang = array() ){
+		$out = null;
+		$list = array();
+		if( self::hasLang() ){
+			$list = ExtensionConfig::$LANG;
+		}
+		$countList = count($list);
+		
+		// Page courante
+		if(USER_PAGE && USER_PAGE != 'index'){
+			$param = '?p='.USER_PAGE .'&amp;lg=';
+		}
+		else{
+			$param = '?lg=';
+		}
+		
+		// Liste de toutes les langues
+		if( $countList > 0 ){
+			$out .= '<ul>';
+			// S'il y a une langue courante, on la place en 1er
+			if( count($currentLang) > 0 ){
+				$currentLangCode = key($currentLang);
+				$currentLangName = current($currentLang);
+				unset($list[$currentLangCode]);
+				$out .= '<li><a tabindex="-1" class="lang-flag" style="background-image: url('. AdminServConfig::$PATH_RESOURCES .'images/lang/'.$currentLangCode.'.png);" href="'.$param.$currentLangCode.'" title="'.$currentLangName.'"></a></li>';
+			}
+			foreach($list as $code => $name){
+				$out .= '<li><a tabindex="-1" class="lang-flag" style="background-image: url('. AdminServConfig::$PATH_RESOURCES .'images/lang/'.$code.'.png);" href="'.$param.$code.'" title="'.$name.'"></a></li>';
+			}
+			$out .= '</ul>';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le header/footer du site
+	*/
+	public static function getHeader(){
+		global $args;
+		
+		if( !isset($GLOBALS['body_class']) ){
+			$GLOBALS['body_class'] = null;
+		}
+		if(USER_PAGE != 'servers-online-config' && !self::isPageType('config') ){
+			if( defined('SERVER_NAME') ){
+				$GLOBALS['page_title'] = SERVER_NAME;
+				$GLOBALS['body_class'] .= ' not-front';
+			}
+			else{
+				$GLOBALS['body_class'] .= ' front';
+			}
+		}
+		else{
+			$GLOBALS['body_class'] .= ' config';
+		}
+		if( defined('USER_PAGE') && USER_PAGE ){
+			$GLOBALS['body_class'] .= ' section-'.USER_PAGE;
+		}
+		if( defined('CURRENT_PLUGIN') && CURRENT_PLUGIN ){
+			$GLOBALS['body_class'] .= ' plugin-'.CURRENT_PLUGIN;
+		}
+		$GLOBALS['body_class'] = trim($GLOBALS['body_class']);
+		
+		require_once AdminServConfig::$PATH_RESOURCES . 'templates/header.tpl.php';
+	}
+	public static function getFooter(){
+		require_once AdminServConfig::$PATH_RESOURCES . 'templates/footer.tpl.php';
+	}
+	
+	
+	/**
+	* Récupère le CSS/JS du site
+	*/
+	public static function getCss(){
+		$path = AdminServConfig::$PATH_RESOURCES .'css/';
+		$out = '<link rel="stylesheet" href="'.$path.'fileuploader.css" />'."\n\t\t"
+		.'<link rel="stylesheet" href="'.$path.'global.css" />'."\n\t\t"
+		.'<!--[if IE]><link rel="stylesheet" href="'.$path.'ie.css" /><![endif]-->'."\n\t\t";
+		if( defined('USER_THEME') && USER_THEME ){
+			$out .= '<link rel="stylesheet" href="'.$path.'jqueryui/'. USER_THEME .'.css" />'."\n\t\t"
+			.'<link rel="stylesheet" href="'.$path.'theme.php?th='. USER_THEME .'" />'."\n\t\t";
+		}
+		$out .= '<link rel="stylesheet" media="screen and (max-width: 1000px) and (min-width: 335px)" href="'.$path.'mobile.css" />'."\n";
+		
+		return $out;
+	}
+	public static function getJS(){
+		$path = AdminServConfig::$PATH_RESOURCES .'js/';
+		$out = '<script src="'.$path.'jquery.js"></script>'."\n\t\t"
+		.'<script src="'.$path.'jquery-ui.js"></script>'."\n\t\t"
+		.'<script src="'.$path.'colorpicker.js"></script>'."\n\t\t"
+		.'<script src="'.$path.'fileuploader.js"></script>'."\n\t\t"
+		.'<script src="'.$path.'adminserv_funct.js"></script>'."\n\t\t"
+		.'<script src="'.$path.'adminserv_event.js"></script>'."\n";
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la liste des serveurs configurés
+	*
+	* @return string
+	*/
+	public static function getServerList(){
+		$out = null;
+		
+		if( class_exists('ServerConfig') && AdminServServerConfig::hasServer() ){
+			if( isset($_GET['server']) && $_GET['server'] != null ){
+				$currentServerId = intval($_GET['server']);
+			}
+			else{
+				$currentServerId = Utils::readCookieData('adminserv', 0);
+			}
+			
+			foreach(ServerConfig::$SERVERS as $server => $values){
+				$selected = (AdminServServerConfig::getServerId($server) == $currentServerId) ? ' selected="selected"' : null;
+				$out .= '<option value="'.$server.'"'.$selected.'>'.$server.'</option>';
+			}
+		}
+		else{
+			$out = '<option value="null">'.Utils::t('No server available').'</option>';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère la liste des modes de jeu
+	*
+	* @param int $currentGameMode -> Le mode de jeu à sélectionner
+	* @return string
+	*/
+	public static function getGameModeList($currentGameMode = null){
+		$out = null;
+		
+		if( class_exists('ExtensionConfig') && isset(ExtensionConfig::$GAMEMODES) && count(ExtensionConfig::$GAMEMODES) > 0 ){
+			foreach(ExtensionConfig::$GAMEMODES as $gameModeId => $gameModeName){
+				$selected = ($gameModeId == $currentGameMode) ? ' selected="selected"' : null;
+				$out .= '<option value="'.$gameModeId.'"'.$selected.'>'.$gameModeName.'</option>';
+			}
+		}
+		else{
+			$out = '<option value="null">'.Utils::t('No game mode available').'</option>';
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Récupère le formulaire pour un champ
+	*
+	* @param array  $gameinfos -> Informations de jeu courantes et suivantes
+	* @param string $name      -> Le nom du champ affiché dans un label
+	* @param string $id        -> L'id du champ du tableau GameInfos
+	* @return string HTML
+	*/
+	public static function getGameInfosField($gameinfos, $name, $id){
+		global $data;
+		$data['gameInfosField'] = array(
+			'gameInfos' => $gameinfos,
+			'name' => $name,
+			'id' => $id
+		);
+		
+		self::getTemplate('gameinfos-field');
+		unset($data['gameInfosField']);
+	}
+	
+	
+	/**
+	* Récupère la liste des joueurs
+	*
+	* @param string $currentPlayerLogin -> Le login joueur à sélectionner
+	* @return string
+	*/
+	public static function getPlayerList($currentPlayerLogin = null){
+		global $client;
+		$out = '<option value="null">'.Utils::t('No player available').'</option>';
+		
+		if( !$client->query('GetPlayerList', AdminServConfig::LIMIT_PLAYERS_LIST, 0, 1) ){
+			AdminServ::error();
+		}
+		else{
+			$playerList = $client->getResponse();
+			if( count($playerList) > 0 ){
+				$out = null;
+				foreach($playerList as $player){
+					if($currentPlayerLogin == $player['Login']){ $selected = ' selected="selected"'; }
+					else{ $selected = null; }
+					$out .= '<option value="'.$player['Login'].'"'.$selected.'>'.TmNick::toText($player['NickName']).'</option>';
+				}
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Retourne le menu pour les pages maps
+	*
+	* @return template html
+	*/
+	public static function getMapsMenuList(){
+		global $data, $args;
+		$list = ExtensionConfig::$MAPSMENU;
+		$excludeLocalPage = array('maps-local', 'maps-matchset', 'maps-creatematchset');
+		if( !IS_LOCAL ){
+			foreach($excludeLocalPage as $page){
+				unset($list[$page]);
+			}
+		}
+		
+		$data += array(
+			'menuList' => $list,
+		);
+		self::getTemplate('maps-menu');
+	}
+	
+	
+	/**
+	* Récupère la liste des dossiers du répertoire "Maps"
+	*
+	* @require class "Folder"
+	*
+	* @param string $path        -> Le chemin du dossier "Maps"
+	* @param string $currentPath -> Le chemin à partir de "Maps"
+	* @param bool   $showOptions -> Afficher les options (nouveau, renommer, déplacer, supprimer)
+	* @return template maps-directorylist
+	*/
+	public static function getMapsDirectoryList($directory, $currentPath = null, $showOptions = true){
+		global $data;
+		
+		if (class_exists('Folder')) {
+			$data += array(
+				'folders' => array(),
+				'currentPath' => $currentPath,
+				'parentPath' => null,
+				'showOptions' => $showOptions,
+			);
+			
+			// Liste des dossiers
+			if (is_array($directory)) {
+				// Dossier parent
+				if ($currentPath) {
+					$params = null;
+					$parentPathEx = explode('/', $currentPath);
+					array_pop($parentPathEx);
+					array_pop($parentPathEx);
+					if (!empty($parentPathEx)) {
+						$parentPath = null;
+						foreach ($parentPathEx as $part) {
+							$parentPath .= $part.'/';
+						}
+						$data['parentPath'] = $parentPath;
+					}
+				}
+				
+				// Dossiers
+				if (!empty($directory['folders'])) {
+					$data['folders'] = $directory['folders'];
+				}
+				
+				// Template
+				self::getTemplate('maps-directorylist');
+			}
+			else{
+				AdminServ::error($directory);
+			}
+		}
+		else{
+			AdminServ::error('Class "Folder" not exists');
+		}
+	}
+	
+	
+	/**
+	* Ititialise une page en back office
+	*/
+	public static function initBackPage() {
+		global $client, $data, $args;
+		
+		// Pages list
+		$pagesList = array(
+			'general',
+			'srvopts',
+			'gameinfos',
+			'chat',
+			'plugins-list',
+			'guestban',
+		);
+		$pagesList = array_merge($pagesList, array_keys(ExtensionConfig::$MAPSMENU) );
+		$firstPage = array_shift($pagesList);
+		
+		// Render page
+		if (in_array(USER_PAGE, $pagesList)) {
+			$pageKey = array_search(USER_PAGE, $pagesList);
+			if (AdminServAdminLevel::hasAccess($pagesList[$pageKey])) {
+				self::renderPage($pagesList[$pageKey]);
+			}
+			else {
+				$data = array(
+					'errorTitle' => Utils::t('Erreur d\'accès à la page'),
+					'errorMessage' => Utils::t('Vous n\'avez pas les droits requis pour accéder à cette page. Veuillez contacter votre administrateur.'),
+				);
+				self::renderPage('page-error');
+			}
+		}
+		else {
+			if (self::isPageType('config')) {
+				session_unset();
+				session_destroy();
+				Utils::redirection(false, './config/');
+			}
+			elseif (USER_PLUGIN) {
+				AdminServPlugin::renderPlugin();
+			}
+			else {
+				self::renderPage($firstPage);
+			}
+		}
+	}
+	
+	
+	/**
+	* Ititialise une page en front office
+	*/
+	public static function initFrontPage() {
+		// Render page
+		if (self::isPageType('config')) {
+			$pageTitle = 'Configuration';
+			$pageName = USER_PAGE;
+		}
+		else {
+			$pageTitle = 'Connection';
+			$pageName = 'connection';
+		}
+		$GLOBALS['page_title'] = Utils::t($pageTitle);
+		self::renderPage($pageName);
+	}
+	
+	
+	/**
+	* Inclue les fichiers pour le rendu d'une page
+	*/
+	public static function renderPage($pageName) {
+		global $client, $data, $args;
+		
+		// Preprocess
+		if (strstr($pageName, '-')) {
+			$pageNameEx = explode('-', $pageName);
+			$pagePreprocess = AdminServConfig::$PATH_RESOURCES.'process/'.$pageNameEx[0].'.preprocess.php';
+			if (file_exists($pagePreprocess)) {
+				require_once $pagePreprocess;
+			}
+		}
+		
+		// Process
+		$pageProcess = AdminServConfig::$PATH_RESOURCES.'process/'.$pageName.'.php';
+		if (file_exists($pageProcess)) {
+			require_once $pageProcess;
+		}
+		
+		// Terminate client
+		if (isset($client) && $client->socket != null) {
+			$client->Terminate();
+		}
+		
+		// Header
+		self::getHeader();
+		
+		// Template
+		self::getTemplate($pageName);
+		
+		// Footer
+		self::getFooter();
+		
+		AdminServLogs::add('access', (isset($GLOBALS['page_title'])) ? $GLOBALS['page_title'] : $pageName);
+	}
+	
+	
+	/**
+	* Vérifie si la page est du type demandé
+	*
+	* @param string $pageType -> Type de page à tester (config, plugin)
+	* @return bool
+	*/
+	public static function isPageType($pageType, $pageName = USER_PAGE){
+		$out = false;
+		
+		if (strstr($pageName, '-')) {
+			$pageNameEx = explode('-', $pageName);
+			if ($pageNameEx[0] === $pageType) {
+				$out = true;
+			}
+		}
+		
+		return $out;
+	}
+	
+	
+	/**
+	* Inclue un fichier template
+	*
+	* @param string $templateName -> Nom du fichier template sans les extensions
+	* @return template HTML ou null si le template n'existe pas
+	*/
+	public static function getTemplate($templateName){
+		global $data, $args;
+		
+		$tplFile = AdminServConfig::$PATH_RESOURCES.'templates/'.$templateName.'.tpl.php';
+		if (file_exists($tplFile)) {
+			require $tplFile;
+		}
+	}
+}
+?>
\ No newline at end of file
diff --git a/resources/css/displayserv.css b/resources/css/displayserv.css
new file mode 100644
index 0000000..bf6771b
--- /dev/null
+++ b/resources/css/displayserv.css
@@ -0,0 +1 @@
+/* Global DisplayServ-------------------------------*/.ds-servers-list {	margin: 0;	padding: 0;	-webkit-transition: all .2s ease-in-out;	-moz-transition: all .2s ease-in-out;	-o-transition: all .2s ease-in-out;	transition: all .2s ease-in-out;}.ds-servers-list .ds-server {	position: relative;	list-style: none;	margin: 10px 0;	padding: 10px;	min-height: 160px;	overflow: hidden;	background: #fff;	border: 1px solid #ddd;	-webkit-border-radius: 3px;	-moz-border-radius: 3px;	-o-border-radius: 3px;	border-radius: 3px;}.ds-servers-list .ds-server-join-wrap {	position: absolute;	bottom: -35px;	right: 0;	padding: 0 10px;	background: rgba(0, 0, 0, .75);	-webkit-border-radius: 3px 0 0;	-moz-border-radius: 3px 0 0;	-o-border-radius: 3px 0 0;	border-radius: 3px 0 0;	-webkit-transition: all .2s ease-in-out;	-moz-transition: all .2s ease-in-out;	-o-transition: all .2s ease-in-out;	transition: all .2s ease-in-out;}.ds-servers-list.loading .ds-server-join-wrap {	display: none !important;}.ds-servers-list .ds-server:hover .ds-server-join-wrap {	bottom: 0;}.ds-servers-list .ds-server-join-wrap ul {	margin: 0;	padding: 0;}.ds-servers-list .ds-server-join-wrap ul li {	display: block;	float: left;	list-style: none;	padding: 5px 0 7px;}.ds-servers-list .ds-server-join-wrap ul li + li {	margin-left: 10px;	padding-left: 10px;	border-left: 1px solid #555;}.ds-servers-list .ds-server-join-wrap ul li a {	color: #fff;	font-family: Helvetica, Arial, sans-serif;	font-size: 12px;	text-decoration: none;}.ds-servers-list .ds-server-join-wrap ul li a:hover {	border-bottom: 1px solid #eee;}.ds-servers-list.loading {	opacity: .5;}.ds-servers-list table {	width: 100%;	border-spacing: 0;}.ds-servers-list .ds-header th {	color: #5e9cd5;	font-family: Helvetica, Arial, sans-serif;	font-size: 14px;	font-weight: bold;	min-height: 20px;	font-variant: small-caps;	text-align: left;}.ds-servers-list .ds-header .ds-server-join {	border-left: 1px dotted #636363;	padding-left: 10px;}.ds-servers-list .ds-header .ds-server-join a {	color: #5e9cd5;	font-size: 10px;	font-variant: normal;	text-decoration: none;}.ds-servers-list .ds-header .ds-server-join a:hover {	text-decoration: underline;}.ds-servers-list .ds-content {	margin-top: 10px;	color: #666;	font-family: Helvetica, Arial, sans-serif;	font-size: 12px;}.ds-servers-list .ds-content ul {	margin: 0;	padding: 0;}.ds-servers-list .ds-content ul li {	padding: 0;	list-style: none;	line-height: 18px;}.ds-servers-list .ds-server-currentmap img {	margin-bottom: -3px;}.ds-servers-list .ds-space {	height: 10px;}.ds-servers-list .ds-space td {	border: 1px dotted #ccc;	border-width: 1px 0 0;	height: 10px;}.ds-servers-list tr,.ds-servers-list td,.ds-servers-list th,.ds-servers-list tr:hover,.ds-servers-list td:hover,.ds-servers-list th:hover {	background: none;	cursor: default;}.ds-servers-list td {	vertical-align: top;	text-align: left;}.ds-servers-list .ds-servers-players-list {	height: 125px;	overflow-x: hidden;	overflow-y: auto;}.ds-servers-list .ds-servers-players-list td {	border: 1px solid #f7f7f7;	border-width: 0 0 1px;}.ds-servers-list .ds-servers-players-list td.no-player {	text-align: center;	border: 0;	font-style: italic;}.ds-servers-list .ds-content .ds-part-left {	color: #888;	padding-right: 10px;	border-right: 1px dotted #636363;	text-align: right;	width: 17%;	min-width: 100px;}.ds-servers-list .ds-content .ds-part-middle {	padding-left: 10px;	width: 33%;	min-width: 100px;}.ds-servers-list .ds-content .ds-part-right {	width: 50%;}@media (max-width: 580px) {	.ds-servers-list .ds-header th.middle,	.ds-servers-list .ds-content .ds-part-left {		display: none;	}}@media (max-width: 380px) {	.ds-servers-list .ds-header th.middle,	.ds-servers-list .ds-header th.last,	.ds-servers-list .ds-content .ds-part-left,	.ds-servers-list .ds-content .ds-part-right {		display: none;	}}.ds-servers-list.max-width-580 .ds-header th.middle,.ds-servers-list.max-width-580 .ds-content .ds-part-left,.ds-servers-list.max-width-380 .ds-header th.middle,.ds-servers-list.max-width-380 .ds-header th.last,.ds-servers-list.max-width-380 .ds-content .ds-part-left,.ds-servers-list.max-width-380 .ds-content .ds-part-right {	display: none;}/* Couleurs GameMode & Jeux----------------------------- */.rounds {	color: #ffcc11;}.timeattack {	color: #d1321e;}.team {	color: #aabb00;}.laps {	color: #88aa11;}.stunts {	color: #5600da;}.cup {	color: #ff8c11;}.script,.other {	color: #444;}.maniaplanet {	color: #2277cc;}.tmforever {	color: #ad0000;}.team_-1,.team_0,.team_1 {	display: block;	float: left;	width: 7px;	height: 16px;	margin-right: 5px;	opacity: .8;}.team_-1 {	background: #000;}.team_0 {	background: #00f;}.team_1 {	background: #f00;}/* TmNick------------------------ */.tmnick_global {	font-style: normal;	font-weight: none;	letter-spacing: 0;}.tmnick_normal { letter-spacing: 0; }.tmnick_short { letter-spacing: -1px; }.tmnick_wide { letter-spacing: 2px; }.tmnick_raz { font-style: normal; font-weight: none; letter-spacing: 0; }.tmnick_italic { font-style: italic; }.tmnick_bold { font-weight: bold; letter-spacing: 1px; }.tmnick_upper { text-transform: uppercase; }.tmnick_shadowed { text-shadow: 1px 1px 1px #444; }a.tmnick_internallink, a.tmnick_internallink:visited {	color: inherit;	text-decoration: none;	border-bottom: thin solid Black;}a.tmnick_internallink:hover {	color: inherit;	text-decoration: none;	border-bottom: thin solid Blue;}a.tmnick_internallink_withlogin, a.tmnick_internallink_withlogin:visited  {	color: inherit;	text-decoration: none;	border-bottom: thin solid #f0e68c;}a.tmnick_internallink_withlogin:hover {	color: inherit;	text-decoration: none;	border-bottom: thin solid Gold;}a.tmnick_externallink, a.tmnick_externallink:visited {	color: inherit;	text-decoration: none;	border-bottom: thin solid Black;}a.tmnick_externallink:hover {	color: inherit;	text-decoration: none;	border-bottom: thin solid Orange;}
\ No newline at end of file
diff --git a/resources/css/fileuploader.css b/resources/css/fileuploader.css
new file mode 100644
index 0000000..474092e
--- /dev/null
+++ b/resources/css/fileuploader.css
@@ -0,0 +1 @@
+.qq-uploader {	position: relative;	width: 100%;	min-height: 120px;}.qq-upload-button {	position: absolute !important;	top: 90px;	width: 150px;	padding: 7px 0;	color: #fff;	font-variant: small-caps;	text-align: center;	background: #888;	border-right: 4px solid #ccc;	-webkit-border-radius: 3px;	-moz-border-radius: 3px;	-ms-border-radius: 3px;	-o-border-radius: 3px;	border-radius: 3px;}.qq-upload-button-hover {	background: #5e9cd5;}.qq-upload-button-focus {	outline: 1px dotted black}.qq-upload-drop-area {	display: block !important;	position: absolute;	top: 0;	left: 0;	z-index: 2;	width: 150px;	height: 82px;	text-align: center;	background: url("../images/32/blue_arrow_down.png") no-repeat center 85% #888;	border-right: 4px solid #ccc;	-webkit-border-radius: 3px;	-moz-border-radius: 3px;	-ms-border-radius: 3px;	-o-border-radius: 3px;	border-radius: 3px;}.qq-upload-drop-area span {	display: block;	position: absolute;	top: 7%;	width: 100%;	color: #fff;	font-size: 1em;	font-variant: small-caps;	cursor: default;}.qq-upload-drop-area-active {	background-color: #3182C0;}.qq-upload-list {	margin: 10px 0 0 170px;	padding: 0;	list-style: none outside none;}.qq-upload-list li {	margin: 0;	padding: 0;	line-height: 15px;	font-size: 1em;}.qq-upload-file,.qq-upload-spinner,.qq-upload-size,.qq-upload-cancel,.qq-upload-failed-text {	margin-right: 7px;}.qq-upload-file {	display: inline-block;	width: 160px;}.qq-upload-spinner {	display: inline-block;	position: relative;	width: 100px;	height: 15px;	vertical-align: text-bottom;	border: 1px solid #ddd;}.qq-progress-bar {	position: absolute;	top: 0;	left: 0;	height: 15px;	background: #3182c0;}.qq-upload-size,.qq-upload-cancel {	display: inline-block !important;	width: 68px;	font-size: .9em;	text-align: center;}.qq-upload-cancel {	margin-bottom: 2px;	padding: 2px 5px;	color: #999;	font-variant: small-caps;	text-decoration: none;	border: 1px solid #ddd;	-webkit-border-radius: 3px;	-moz-border-radius: 3px;	-ms-border-radius: 3px;	-o-border-radius: 3px;	border-radius: 3px;}.qq-upload-cancel:hover {	color: #fff;	background: #3182c0;	border-color: #3182c0;}.qq-upload-failed-text {	display: none;}.qq-upload-fail .qq-upload-failed-text {	display: inline;}
\ No newline at end of file
diff --git a/resources/css/global.css b/resources/css/global.css
new file mode 100644
index 0000000..9df9b3f
--- /dev/null
+++ b/resources/css/global.css
@@ -0,0 +1,2034 @@
+/* Global AdminServ
+-------------------------------*/
+html {
+	font-size: 100%;
+}
+body {
+	margin: 0;
+	padding: 0;
+	color: #666;
+	font-family: Helvetica, Arial, "Trebuchet MS", Verdana, Tahoma, Sans-Serif;
+	font-size: .8em;
+	background: #f2f2f2;
+}
+a img {
+	border: 0;
+}
+label {
+	cursor: pointer;
+}
+label span {
+	font-size: .8em;
+}
+ul {
+	margin: 0;
+	padding: 0;
+}
+li {
+	list-style: none;
+}
+[hidden="hidden"] {
+	display: none;
+}
+.fleft {
+	float: left;
+}
+.fright {
+	float: right;
+}
+.alignleft {
+	text-align: left;
+}
+.aligncenter {
+	text-align: center;
+}
+.alignright {
+	text-align: right;
+}
+.loading {
+	opacity: .5;
+}
+
+
+/* Taille du site
+-------------------------------*/
+#header-inner,
+#nav-inner,
+#connection-inner,
+#content-inner,
+#footer-inner {
+	width: 1000px;
+	margin: 0 auto;
+	position: relative;
+}
+
+
+/* Header
+-------------------------------*/
+header {
+	background: #555;
+}
+#header-inner {
+	height: 74px;
+}
+
+/* Logo - Titre */
+.logo-title {
+	float: left;
+}
+.logo-title a {
+	display: block;
+	text-decoration: none;
+}
+.logo-title a:hover #title {
+	color: #eee;
+}
+#logo {
+	float: left;
+	padding: 10px 10px 0;
+}
+.title-subtitle {
+	float: left;
+	font-family: "Trebuchet MS", Arial, Sans-serif;
+	font-weight: bold;
+}
+#title {
+	float: left;
+	margin-top: 8px;
+	line-height: 45px;
+	color: #ddd;
+	font-size: 3.7em;
+	letter-spacing: -2px;
+	-webkit-transition: color .2s ease-in-out;
+	-moz-transition: color .2s ease-in-out;
+	-ms-transition: color .2s ease-in-out;
+	-o-transition: color .2s ease-in-out;
+	transition: color .2s ease-in-out;
+}
+#title .title-color {
+	color: #5e9cd5;
+}
+#subtitle {
+	clear: both;
+	float: left;
+	color: #eee;
+	font-size: .9em;
+}
+
+/* SpeedAdmin */
+.speed-admin {
+	float: right;
+	margin-right: 78px;
+}
+.speed-admin ul {
+	padding: 3px 4px;
+	width: 89px;
+	background: #484848;
+	overflow: hidden;
+	-webkit-border-radius: 0 0 5px 5px;
+	-moz-border-radius: 0 0 5px 5px;
+	-ms-border-radius: 0 0 5px 5px;
+	-o-border-radius: 0 0 5px 5px;
+	border-radius: 0 0 5px 5px;
+}
+.speed-admin li + li a {
+	margin-left: 3px;
+}
+.speed-admin li a {
+	display: block;
+	float: left;
+	width: 20px;
+	height: 20px;
+	text-indent: -9999px;
+	background-repeat: no-repeat;
+}
+.speed-admin li a:hover {
+	background-position: 0 -20px;
+}
+.speed-admin li .locked {
+	cursor: default;
+	background-position: 0 -40px;
+}
+.speed-admin li .prev {
+	background-image: url("../images/16/bt_arrow_fastprev.png");
+}
+.speed-admin li .restart {
+	background-image: url("../images/16/bt_refresh.png");
+}
+.speed-admin li .next {
+	background-image: url("../images/16/bt_arrow_fastnext.png");
+}
+.speed-admin li .endround {
+	background-image: url("../images/16/bt_arrow_last.png");
+}
+
+/* Theme - lang */
+.theme-lang {
+	float: right;
+}
+.theme-lang div {
+	position: absolute;
+	top: 0;
+	right: 0;
+	z-index: 10;
+	padding: 4px;
+	height: 12px;
+	background: #444;
+	overflow: hidden;
+	-webkit-border-radius: 0 0 5px 5px;
+	-moz-border-radius: 0 0 5px 5px;
+	-ms-border-radius: 0 0 5px 5px;
+	-o-border-radius: 0 0 5px 5px;
+	border-radius: 0 0 5px 5px;
+	-webkit-transition: height .2s;
+	-moz-transition: height .2s;
+	-ms-transition: height .2s;
+	-o-transition: height .2s;
+	transition: height .2s;
+}
+#theme {
+	right: 30px;
+}
+.theme-lang li {
+	margin-bottom: 5px;
+}
+.theme-lang a {
+	display: block;
+	width: 16px;
+	height: 11px;
+	opacity: .75;
+	-webkit-border-radius: 1px;
+	-moz-border-radius: 1px;
+	-ms-border-radius: 1px;
+	-o-border-radius: 1px;
+	border-radius: 1px;
+	-webkit-transition: all .2s;
+	-moz-transition: all .2s;
+	-ms-transition: all .2s;
+	-o-transition: all .2s;
+	transition: all .2s;
+}
+.theme-lang a:hover {
+	opacity: 1;
+}
+
+/* Switch Server */
+.switch-server {
+	position: absolute;
+	top: 40px;
+	right: 3px;
+	z-index: 5;
+}
+#switchServerList {
+	padding: 2px 3px;
+	width: 172px;
+	color: #ddd;
+	background: #555;
+	border-color: #888;
+	-webkit-transition: background .3s ease-in-out;
+	-moz-transition: background .3s ease-in-out;
+	-o-transition: background .3s ease-in-out;
+	transition: background .3s ease-in-out;
+	-webkit-box-shadow: 4px 0 0 rgba(255, 255, 255, .2);
+	-moz-box-shadow: 4px 0 0 rgba(255, 255, 255, .2);
+	-ms-box-shadow: 4px 0 0 rgba(255, 255, 255, .2);
+	-o-box-shadow: 4px 0 0 rgba(255, 255, 255, .2);
+	box-shadow: 4px 0 0 rgba(255, 255, 255, .2);
+}
+#switchServerList:hover {
+	background: #444;
+}
+
+/* Ligne de couleur */
+#header-color-line {
+	background: #5e9cd5;
+	height: 10px;
+}
+
+
+/* Navigation
+-------------------------*/
+.horizontal-nav,
+#connection {
+	padding-bottom: 15px;
+	background: #f2f2f2;
+}
+#connection-inner,
+.menu-principal {
+	clear: both;
+	padding: 5px 0 9px;
+	background: #fff;
+	border: 1px solid #ddd;
+	border-width: 0 1px 1px;
+	overflow: hidden;
+	-webkit-border-radius: 0 0 5px 5px;
+	-moz-border-radius: 0 0 5px 5px;
+	-ms-border-radius: 0 0 5px 5px;
+	-o-border-radius: 0 0 5px 5px;
+	border-radius: 0 0 5px 5px;
+}
+.menu-principal .menu-left {
+	float: left;
+	padding-left: 5px;
+}
+.menu-principal .menu-right {
+	float: right;
+	padding-right: 5px;
+}
+.menu-principal li {
+	float: left;
+	margin: 0 2px;
+}
+.menu-principal a {
+	display: block;
+}
+
+
+/* Connexion
+-------------------------------*/
+#connection-inner {
+	padding: 0 5px;
+}
+#connection-inner .connection-label,
+.section-servers-online-config fieldset .connection-label {
+	float: left;
+	padding: 5px 0;
+	width: 89%;
+}
+#connection-inner label {
+	margin-left: 4px;
+}
+#as_server {
+	width: 32%;
+	margin: 1px 10px 0 0;
+}
+#as_password {
+	width: 18%;
+	margin: 1px 10px 0 0;
+}
+#as_adminlevel {
+	width: 15%;
+	margin: 1px 0 0;
+}
+#connection-inner .connection-login,
+.section-servers-online-config fieldset .connection-login {
+	float: right;
+	padding: 0 5px 0 10px;
+	height: 38px;
+	border-left: 1px solid #f5f5f5;
+}
+#connection-inner .connection-login input,
+.section-servers-online-config fieldset .connection-login input {
+	margin-top: 5px;
+}
+.section-servers-online-config fieldset {
+	margin: 30px 5px;
+	width: 513px;
+}
+.section-servers-online-config .no-server fieldset {
+	width: 450px;
+}
+.section-servers-online-config fieldset legend {
+	margin-bottom: 5px;
+}
+.section-servers-online-config fieldset .connection-label {
+	width: auto;
+}
+.section-servers-online-config  fieldset .connection-cancel {
+	float: right;
+	margin-top: 4px;
+	padding: 5px 10px 5px 0;
+}
+.section-servers-online-config #checkPassword,
+.section-servers-online-config #savePassword {
+	width: 200px;
+	height: 20px;
+}
+
+
+
+
+/* Erreurs - infos
+-------------------------------*/
+#error,
+#info {
+	position: absolute;
+	top: 50px;
+	left: 230px;
+	z-index: 1004;
+	padding: 5px;
+	width: 500px;
+	min-height: 20px;
+	font-size: 1.2em;
+	text-align: center;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	-ms-border-radius: 5px;
+	-o-border-radius: 5px;
+	border-radius: 5px;
+	-webkit-box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
+	-moz-box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
+	-ms-box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
+	-o-box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
+	box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
+}
+#error {
+	z-index: 1005;
+	color: #fff;
+	background-color: #d1321e;
+}
+#info {
+	color: #222;
+	background-color: #f4f398;
+}
+
+
+/* Bouttons - Input
+-------------------------------*/
+.button {
+	padding: 3px 5px;
+	font-size: .95em;
+	font-variant: small-caps;
+	background-color: #fff;
+	border: 1px solid;
+	border-bottom: 0;
+	cursor: pointer;
+	-webkit-border-radius: 3px;
+	-moz-border-radius: 3px;
+	-ms-border-radius: 3px;
+	-o-border-radius: 3px;
+	border-radius: 3px;
+}
+a.button {
+	text-decoration: none;
+}
+.button.light,
+.button.dark {
+	-webkit-box-shadow: 0 4px 0 #5e9cd5;
+	-moz-box-shadow: 0 4px 0 #5e9cd5;
+	-ms-box-shadow: 0 4px 0 #5e9cd5;
+	-o-box-shadow: 0 4px 0 #5e9cd5;
+	box-shadow: 0 4px 0 #5e9cd5;
+}
+.button.light:hover,
+.button.light.active,
+.button.dark:hover,
+.button.dark.active {
+	-webkit-box-shadow: 0 4px 0 #ddd;
+	-moz-box-shadow: 0 4px 0 #ddd;
+	-ms-box-shadow: 0 4px 0 #ddd;
+	-o-box-shadow: 0 4px 0 #ddd;
+	box-shadow: 0 4px 0 #ddd;
+	-webkit-transition: background .3s ease-in-out;
+	-moz-transition: background .3s ease-in-out;
+	-ms-transition: background .3s ease-in-out;
+	-o-transition: background .3s ease-in-out;
+	transition: background .3s ease-in-out;
+	-webkit-transition: border .2s ease-in-out;
+	-moz-transition: border .2s ease-in-out;
+	-ms-transition: border .2s ease-in-out;
+	-o-transition: border .2s ease-in-out;
+	transition: border .2s ease-in-out;
+}
+.button.light {
+	color: #999;
+	background-color: #fff;
+	border-color: #ddd;
+}
+.button.light:hover,
+.button.light.active {
+	color: #fff;
+	background-color: #666;
+	border-color: #666;
+}
+.button.dark {
+	color: #fff;
+	background-color: #666;
+	border-color: #666;
+}
+.button.dark:hover,
+.button.dark.active {
+	color: #999;
+	background-color: #fff;
+	border-color: #fff;
+}
+.save input.button {
+	margin: 0 10px 5px 0;
+	width: 150px;
+}
+
+input.text,
+textarea,
+select {
+	color: #777;
+	padding: 3px 5px;
+	background: #f9f9f9;
+	border: 1px solid #ddd;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	-ms-border-radius: 5px;
+	-o-border-radius: 5px;
+	border-radius: 5px;
+	-webkit-box-shadow: 4px 0 0 rgba(0, 0, 0, .1);
+	-moz-box-shadow: 4px 0 0 rgba(0, 0, 0, .1);
+	-ms-box-shadow: 4px 0 0 rgba(0, 0, 0, .1);
+	-o-box-shadow: 4px 0 0 rgba(0, 0, 0, .1);
+	box-shadow: 4px 0 0 rgba(0, 0, 0, .1);
+}
+input.text:hover,
+input.text:focus,
+textarea:hover,
+textarea:focus,
+select:hover,
+select:focus {
+	color: #444;
+	background: #fff;
+	-webkit-transition: background .3s ease-in-out;
+	-moz-transition: background .3s ease-in-out;
+	-ms-transition: background .3s ease-in-out;
+	-o-transition: background .3s ease-in-out;
+	transition: background .3s ease-in-out;
+	-webkit-transition: color .2s ease-in-out;
+	-moz-transition: color .2s ease-in-out;
+	-ms-transition: color .2s ease-in-out;
+	-o-transition: color .2s ease-in-out;
+	transition: color .2s ease-in-out;
+}
+textarea {
+	font-family: "MS Trebuchet", Arial, Sans-Serif;
+	font-size: 1.05em;
+}
+input[type="checkbox"],
+input[type="radio"] {
+	display: block;
+	cursor: pointer;
+}
+input[type="checkbox"].inline {
+	display: inline;
+	margin: -2px 7px 0 0;
+	vertical-align: middle;
+}
+input[disabled="disabled"],
+input[readonly="readonly"] {
+	cursor: default;
+}
+input[readonly="readonly"]:focus,
+input[readonly="readonly"]:hover {
+	color: #777;
+	background: #f9f9f9;
+}
+input.width1,
+textarea.width1,
+select.width1 {
+	width: 86%;
+}
+select.width1 {
+	width: 96%;
+}
+input.width2,
+textarea.width2 {
+	width: 80%;
+}
+select.width2 {
+	width: 84.75%;
+}
+input.width3,
+textarea.width3,
+select.width3 {
+	width: 95%;
+}
+
+
+/* Fielset
+-------------------------------*/
+fieldset {
+	margin: 10px 5px;
+	background: #fff;
+	border: 1px solid #ddd;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	-ms-border-radius: 5px;
+	-o-border-radius: 5px;
+	border-radius: 5px;
+}
+fieldset legend {
+	padding: 0 5px;
+	font-weight: bold;
+	font-variant: small-caps;
+	background: #f5f5f5;
+	border: 1px solid #ddd;
+	border-width: 1px 1px 0;
+	-webkit-border-radius: 5px 5px 0 0;
+	-moz-border-radius: 5px 5px 0 0;
+	-ms-border-radius: 5px 5px 0 0;
+	-o-border-radius: 5px 5px 0 0;
+	border-radius: 5px 5px 0 0;
+	-webkit-box-shadow: 0 3px #5e9cd5;
+	-moz-box-shadow: 0 3px #5e9cd5;
+	-ms-box-shadow: 0 3px #5e9cd5;
+	-o-box-shadow: 0 3px #5e9cd5;
+	box-shadow: 0 3px #5e9cd5;
+}
+fieldset legend img {
+	margin: 2px 3px -5px 0;
+	opacity: .8;
+}
+
+
+/* Titres
+-------------------------------*/
+h1 {
+	margin: 0 0 10px;
+	line-height: 22px;
+	color: #fff;
+	font-size: 1.2em;
+	font-variant: small-caps;
+	text-indent: 10px;
+	text-shadow: 1px 1px 3px #777;
+	background: #5e9cd5;
+	border-bottom: 1px solid #ddd;
+	-webkit-border-radius: 2px 2px 2px 6px;
+	-moz-border-radius: 2px 2px 2px 6px;
+	-ms-border-radius: 2px 2px 2px 6px;
+	-o-border-radius: 2px 2px 2px 6px;
+	border-radius: 2px 2px 2px 6px;
+	-webkit-box-shadow: -4px 0 0 #ddd;
+	-moz-box-shadow: -4px 0 0 #ddd;
+	-ms-box-shadow: -4px 0 0 #ddd;
+	-o-box-shadow: -4px 0 0 #ddd;
+	box-shadow: -4px 0 0 #ddd;
+}
+h2 {
+	display: block;
+	margin: 20px 0 10px;
+	color: #5e9cd5;
+	font-size: .9em;
+	text-indent: 10px;
+	text-transform: uppercase;
+	border-bottom: 1px solid #ddd;
+}
+h3 {
+	display: block;
+	margin: 10px 0 5px;
+	color: #5e9cd5;
+	font-size: .9em;
+	text-indent: 2px;
+	border-bottom: 1px dotted #ccc;
+}
+.title-detail {
+	position: absolute;
+	top: 14px;
+	right: 10px;
+	color: #fff;
+	font-size: .9em;
+}
+.title-detail li {
+	float: left;
+	padding: 0 6px 0 7px;
+	height: 15px;
+	border-right: 1px solid #eee;
+}
+.title-detail li.last {
+	border: 0;
+}
+.title-detail a {
+	color: #fff;
+	text-decoration: none;
+}
+.title-detail a:hover {
+	text-decoration: underline;
+	text-shadow: 1px 1px 5px #777;
+}
+.title-detail input[type="checkbox"] {
+	float: right;
+	margin: 1px 0 0;
+}
+
+
+/* Tableaux
+---------------------*/
+table {
+	width: 100%;
+	border-spacing: 0;
+}
+th {
+	color: #d1321e;
+	font-size: .9em;
+	font-weight: normal;
+	font-variant: small-caps;
+	background: #f5f5f5;
+}
+th a {
+	color: #d1321e;
+	text-decoration: none;
+}
+th a:hover {
+	text-decoration: underline;
+}
+.thleft {
+	-webkit-border-radius: 5px 0 0 5px;
+	-moz-border-radius: 5px 0 0 5px;
+	-ms-border-radius: 5px 0 0 5px;
+	-o-border-radius: 5px 0 0 5px;
+	border-radius: 5px 0 0 5px;
+}
+.thright {
+	-webkit-border-radius: 0 5px 5px 0;
+	-moz-border-radius: 0 5px 5px 0;
+	-ms-border-radius: 0 5px 5px 0;
+	-o-border-radius: 0 5px 5px 0;
+	border-radius: 0 5px 5px 0;
+}
+tr {
+	height: 20px;
+}
+tr.table-separation {
+	height: 5px !important;
+}
+tr.no-line {
+	font-style: italic;
+	text-align: center;
+}
+tr.no-line:hover,
+tr.table-separation {
+	background: none !important;
+	cursor: auto !important;
+}
+tbody tr.recent {
+	background: #f7f59e;
+}
+tbody tr:hover {
+	width: 100%;
+	background: #f5f5f5;
+	border: 1px solid #eee;
+	cursor: pointer;
+}
+tbody tr.current,
+tbody tr.current:hover {
+	background: #f7f59e;
+	border: 0;
+	cursor: default;
+}
+tbody tr.selected {
+	background: #d9e8ff;
+}
+.section-index .cadre.left tbody tr:hover,
+fieldset tbody tr:hover {
+	background: none;
+	border: 0;
+	cursor: default;
+}
+td {
+	text-align: center;
+}
+td.imgleft {
+	text-align: left;
+
+}
+td.imgleft img,
+td.imgcenter img {
+	margin: 0 5px -3px;
+	opacity: .8;
+}
+td.checkbox {
+	width: 22px;
+}
+td.key {
+	padding: 0 9px;
+	width: 170px;
+	color: #888;
+	text-align: right;
+}
+td.value {
+	padding-left: 9px;
+	text-align: left;
+	border-left: 1px dotted #636363;
+}
+td.info {
+	color: #aaa;
+	font-size: .9em;
+	font-style: italic;
+	text-align: left;
+}
+td .detailModeTd {
+	display: block;
+	font-size: .7em;
+}
+
+
+/* Option de lignes selectionnées
+-------------------------------*/
+.options {
+	position: relative;
+	margin-top: 15px;
+	padding: 6px 10px 0;
+	min-height: 24px;
+	background: #888;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	-ms-border-radius: 5px;
+	-o-border-radius: 5px;
+	border-radius: 5px;
+	-webkit-box-shadow: -4px 0 0 #444;
+	-moz-box-shadow: -4px 0 0 #444;
+	-ms-box-shadow: -4px 0 0 #444;
+	-o-box-shadow: -4px 0 0 #444;
+	box-shadow: -4px 0 0 #444;
+}
+.options.form {
+	overflow: hidden;
+}
+.options input {
+	margin-right: 5px;
+	font-size: .9em;
+}
+.options .nb-line {
+	color: #fff;
+	text-transform: lowercase;
+}
+.selected-files-label {
+	display: block;
+}
+.selected-files-label span {
+	color: #fff;
+	font-size: 1em;
+	text-align: right;
+	cursor: default;
+}
+.selected-files-label.locked span {
+	color: #bbb;
+	border-color: #bbb;
+}
+.selected-files-label span.selected-files-title {
+	font-style: italic;
+	border-bottom: 1px solid #ddd;
+}
+.selected-files-label span.selected-files-count {
+	padding-left: 3px;
+}
+.selected-files-label.optHover span,
+.selected-files-label:hover span,
+.selected-files-label.locked:hover .selected-files-option {
+	display: none;
+}
+.selected-files-label.optHover .selected-files-option,
+.selected-files-label:hover .selected-files-option {
+	display: block;
+}
+.selected-files-label.optHover .button.active {
+	-webkit-box-shadow: 0 8px 0 #ddd;
+	-moz-box-shadow: 0 8px 0 #ddd;
+	-ms-box-shadow: 0 8px 0 #ddd;
+	-o-box-shadow: 0 8px 0 #ddd;
+	box-shadow: 0 8px 0 #ddd;
+	-webkit-border-radius: 3px 3px 0 0;
+	-moz-border-radius: 3px 3px 0 0;
+	-ms-border-radius: 3px 3px 0 0;
+	-o-border-radius: 3px 3px 0 0;
+	border-radius: 3px 3px 0 0;
+}
+.selected-files-label.locked:hover span {
+	display: inline;
+}
+.selected-files-option {
+	display: none;
+	position: absolute;
+	top: -18px;
+	right: -25px;
+	padding: 25px;
+	text-align: right;
+}
+.options-checkbox {
+	margin-left: 10px;
+	padding-left: 20px;
+	border-left: 3px solid #5e9cd5;
+}
+.options-checkbox li {
+	margin-bottom: 6px;
+}
+.options-checkbox .disabled label {
+	color: #aaa;
+}
+.option-form {
+	clear: both;
+	margin: 32px 0 10px;
+	padding: 5px;
+	background: rgba(255, 255, 255, .5);
+	-webkit-border-radius: 4px;
+	-moz-border-radius: 4px;
+	-ms-border-radius: 4px;
+	-o-border-radius: 4px;
+	border-radius: 4px;
+}
+.option-form li {
+	line-height: 32px;
+}
+.option-form li span {
+	display: block;
+	float: left;
+	margin-top: 6px;
+}
+.option-form li .rename-map-name {
+	padding: 0 5px;
+	width: 39%;
+	height: 22px;
+	line-height: 22px;
+	color: #ddd;
+	text-align: right;
+	background: #555;
+	overflow: hidden;
+	-webkit-border-radius: 3px 0 0 3px;
+	-moz-border-radius: 3px 0 0 3px;
+	-ms-border-radius: 3px 0 0 3px;
+	-o-border-radius: 3px 0 0 3px;
+	border-radius: 3px 0 0 3px;
+}
+.option-form li .rename-map-arrow {
+	margin-right: 6px;
+	width: 0;
+	height: 0;
+	border-top: 11px solid transparent;
+	border-bottom: 11px solid transparent;
+	border-left: 11px solid #555;
+}
+.option-form input.text {
+	height: 20px;
+	border: 0;
+	-webkit-border-radius: 3px 0 0 3px;
+	-moz-border-radius: 3px 0 0 3px;
+	-ms-border-radius: 3px 0 0 3px;
+	-o-border-radius: 3px 0 0 3px;
+	border-radius: 3px 0 0 3px;
+}
+.option-form .form-input-submit {
+	margin: 8px 0 4px;
+	padding-top: 5px;
+	text-align: right;
+	border-top: 1px solid #ddd;
+}
+#form-move-map label,
+#moveFolderForm label {
+	display: block;
+	margin: 12px 0 -2px 5px;
+	padding: 5px;
+	width: 95.6%;
+	color: #ddd;
+	background: #555;
+	-webkit-border-radius: 3px 3px 0 0;
+	-moz-border-radius: 3px 3px 0 0;
+	-ms-border-radius: 3px 3px 0 0;
+	-o-border-radius: 3px 3px 0 0;
+	border-radius: 3px 3px 0 0;
+}
+#form-move-map select {
+	width: 99%;
+}
+#renameFolderForm.option-form input.text {
+	margin-top: 6px;
+	height: auto;
+	border: 1px solid #ddd;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	-ms-border-radius: 5px;
+	-o-border-radius: 5px;
+	border-radius: 5px;
+}
+#renameFolderForm.option-form li .rename-map-name {
+	height: 24px;
+}
+#renameFolderForm.option-form li .rename-map-arrow {
+	border-top-width: 12px;
+	border-bottom-width: 12px;
+	border-left-width: 12px;
+}
+#moveFolderForm label {
+	width: 94.6%;
+	margin-left: 6px;
+}
+#moveFolderForm select {
+	width: 100%;
+	font-size: 13.3333px;
+}
+
+/* Option de type radio en ligne
+---------------------------------*/
+.options-radio-inline {
+	margin-bottom: 30px;
+	overflow: hidden;
+}
+.options-radio-inline li {
+	display: block;
+	float: left;
+	padding: 5px;
+	width: 177px;
+	background: #eee;
+	border: 1px solid #ddd;
+	cursor: pointer;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	-ms-border-radius: 5px;
+	-o-border-radius: 5px;
+	border-radius: 5px;
+	-webkit-transition: all .2s;
+	-moz-transition: all .2s;
+	-ms-transition: all .2s;
+	-o-transition: all .2s;
+	transition: all .2s;
+}
+.options-radio-inline li:hover,
+.options-radio-inline li.selected {
+	background: #d9e8ff;
+}
+.options-radio-inline li +li {
+	margin-left: 20px;
+}
+.options-radio-inline li input {
+	float: left;
+	margin: 0 0 0 8px;
+	height: 32px;
+}
+.options-radio-inline li .name {
+	float: left;
+	margin-left: 9%;
+	width: 70%;
+	font-size: .8em;
+}
+.options-radio-inline li .name span {
+	display: block;
+	font-size: 1.2em;
+	font-weight: bold;
+}
+.options-radio-inline li .icon {
+	float: right;
+}
+.options-radio-inline li .icon .ui-icon {
+	width: 14px;
+	height: 14px;
+	border: 1px solid transparent;
+}
+.options-radio-inline li .icon .ui-icon.active,
+.options-radio-inline li .icon .ui-icon:hover {
+	background-color: #ddd;
+	border-color: #ccc;
+	-webkit-border-radius: 3px;
+	-moz-border-radius: 3px;
+	-ms-border-radius: 3px;
+	-o-border-radius: 3px;
+	border-radius: 3px;
+}
+
+
+/* Contenu
+-------------------------------*/
+#content {
+	clear: both;
+	min-height: 559px;
+}
+.cadre {
+	position: relative;
+	margin-bottom: 25px;
+	padding: 10px;
+	background: #fff;
+	border: 1px solid #ddd;
+	overflow: hidden;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	-ms-border-radius: 5px;
+	-o-border-radius: 5px;
+	border-radius: 5px;
+}
+.cadre.left {
+	float: left;
+	z-index: 10;
+	width: 48%;
+	-webkit-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
+	-moz-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
+	-ms-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
+	-o-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
+	box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
+}
+.cadre.right {
+	float: right;
+	z-index: 5;
+	margin-left: -10px;
+	padding-left: 20px;
+	width: 47.5%;
+	background: #fefefe;
+	border-color: #dfdfdf;
+}
+.cadre.left.menu {
+	width: 15%;
+}
+.cadre.middle.folders {
+	float: left;
+	z-index: 7;
+	margin-left: -10px;
+	padding-left: 18px;
+	width: 17%;
+	-webkit-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
+	-moz-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
+	-ms-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
+	-o-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
+	box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
+}
+.hasMenu .cadre.right {
+	width: 80.5%;
+}
+.hasMenu.hasFolders .cadre.right {
+	width: 61%;
+}
+
+.content {
+	margin: 0 0 20px;
+	background: #f9f9f9;
+	border: 2px solid #f6f6f6;
+	overflow: hidden;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	-ms-border-radius: 5px;
+	-o-border-radius: 5px;
+	border-radius: 5px;
+}
+.content.last {
+	margin: 0;
+}
+.content p {
+	margin: 12px;
+}
+.content p a {
+	color: #666;
+	text-decoration: none;
+	border-bottom: 1px solid #5e9cd5;
+}
+.content p a:hover {
+	border: 0;
+}
+
+
+/* Footer
+----------------------------*/
+footer {
+	clear: both;
+	height: 50px;
+	background: -webkit-linear-gradient(top, #f7f7f7 0%, #f2f2f2 100%);
+	background: -moz-linear-gradient(top, #f7f7f7 0%, #f2f2f2 100%);
+	background: -ms-linear-gradient(top, #f7f7f7 0%, #f2f2f2 100%);
+	background: -o-linear-gradient(top, #f7f7f7 0%, #f2f2f2 100%);
+	background: linear-gradient(top, #f7f7f7 0%, #f2f2f2 100%);
+	border-top: 3px solid #eee;
+}
+#footer-inner {
+	padding-top: 10px;
+	color: #aaa;
+	font-size: .8em;
+	text-align: center;
+}
+#footer-inner a {
+	color: #aaa;
+	text-decoration: none;
+}
+#footer-inner a:hover {
+	text-decoration: underline;
+}
+
+
+/* Page Config
+---------------------- */
+.section-config-addserver table .key {
+	width: 200px;
+}
+.section-config-addserver table .value {
+	width: 340px;
+}
+.section-config-addserver input.width3 {
+	width: 90%;
+}
+.section-config-password input.width3 {
+	width: 30%;
+}
+.section-config-servers table tbody tr,
+.section-config-adminlevel table tbody tr {
+	height: 22px;
+}
+.section-config-servers table tbody tr input,
+.section-config-adminlevel table tbody tr input {
+	margin-bottom: 4px;
+}
+.section-config-addlevel input.width3 {
+	width: 29.4%;
+}
+.section-config-addlevel select {
+	width: 31%;
+}
+.adminlevelSortableList td.value {
+	padding: 0 20px;
+	width: 40%;
+	vertical-align: top;
+}
+.adminlevelSortableList .ui-sortable {
+	position: relative;
+	padding: 2px;
+	min-height: 200px;
+	background: #f9f9f9;
+	border: 2px solid #f6f6f6;
+	-webkit-border-radius: 3px;
+	-moz-border-radius: 3px;
+	-ms-border-radius: 3px;
+	-o-border-radius: 3px;
+	border-radius: 3px;
+}
+.adminlevelSortableList .ui-sortable:after {
+	content: "";
+	position: absolute;
+	top: 90px;
+	right: -20px;
+	z-index: 5;
+	width: 0;
+	height: 0;
+	border-style: solid;
+	border-width: 10px 10px 10px 0;
+	border-color: transparent #ccc transparent transparent;
+}
+.adminlevelSortableList #selectedAccess.ui-sortable:after,
+.adminlevelSortableList #selectedPermission.ui-sortable:after {
+	right: auto;
+	left: -20px;
+	border-width: 10px 0 10px 10px;
+	border-color: transparent transparent transparent #ccc;
+}
+.adminlevelSortableList .ui-sortable li {
+	margin: 0;
+	padding: 3px 5px;
+	min-height: 14px;
+}
+
+
+/* Page General
+---------------------- */
+.current_map {
+	float: left;
+	width: 70%;
+}
+#map_enviro img {
+	margin: 0 0 -3px 5px;
+}
+#map_thumbnail {
+	position: absolute;
+	top: 0;
+	right: 0;
+	padding: 8px;
+	min-width: 128px;
+	min-height: 128px;
+	background: #fff;
+	border: 1px solid #ddd;
+	border-width: 0 0 1px 1px;
+	-webkit-border-radius: 0 5px;
+	-moz-border-radius: 0 5px;
+	-ms-border-radius: 0 5px;
+	-o-border-radius: 0 5px;
+	border-radius: 0 5px;
+}
+#map_thumbnail img {
+	display: block;
+	width: 128px;
+}
+#map_currentcallvote {
+	display: block;
+	width: 157%;
+	height: 35px;
+	line-height: 35px;
+}
+#CancelVote {
+	float: right;
+	margin-top: 3px;
+}
+#map_teamscore {
+	display: block;
+	padding: 5px 0 4px 9px;
+	width: 160%;
+	height: 28px;
+}
+#map_teamscore span {
+	margin-top: 6px;
+}
+#map_teamscore .text {
+	float: left;
+	margin-top: 2px;
+	width: 15%;
+	text-align: center;
+}
+#ScoreTeamBlue {
+	margin-right: 25px;
+}
+#ForceScores {
+	float: right;
+}
+#playerlist {
+	min-height: 433px;
+}
+.section-index .cadre.left {
+	min-height: 511px;
+}
+.section-index .selected-files-option {
+	top: auto;
+	bottom: -25px;
+	width: 50%;
+}
+.section-index .isTeamGameMode .selected-files-option {
+	width: 75%;
+}
+.section-index .options input {
+	margin-top: 10px;
+}
+.section-index .scriptName {
+	color: #888;
+	font-size: .85em;
+}
+
+
+/* Page Server options
+---------------------- */
+.section-srvopts tr,
+.section-gameinfos tr {
+	height: 30px;
+}
+.srvopts_general .serverComment textarea {
+	height: 102px;
+}
+.srvopts_general .serverComment .key {
+	padding-top: 5px;
+	vertical-align: top;
+}
+.section-srvopts tr td.key:first-child {
+	width: 22%;
+}
+.section-srvopts tr td.value.col2,
+.section-srvopts tr td.key.col3 {
+	width: 100px;
+}
+.section-srvopts .preview {
+	padding: 5px 0 0 10px;
+	width: 40%;
+	text-align: left;
+	vertical-align: top;
+}
+#CallVoteRatio {
+	width: 12%;
+}
+.section-srvopts .srvopts_changeauthpassword select,
+.section-srvopts .srvopts_changeauthpassword .text {
+	float: left;
+	width: 19.7%;
+}
+.section-srvopts .srvopts_changeauthpassword .changeauthpassword-arrow {
+	display: block;
+	float: left;
+	margin: 6px 10px 6px 15px;
+	width: 0;
+	height: 0;
+	border-style: solid;
+	border-width: 7px 0 7px 20px;
+	border-color: transparent transparent transparent rgba(0, 0, 0, .2);
+}
+.section-srvopts .returnDefaultValue {
+	line-height: 12px;
+	color: #aaa;
+	font-size: .85em;
+}
+.section-srvopts .returnDefaultValue:hover {
+	color: #888;
+	text-decoration: none;
+}
+#ClientInputsMaxLatency,
+#callVoteRatioDisabled {
+	margin: 1px 12px 0 0;
+	width: 22%;
+}
+#ClientInputsMaxLatencyValue,
+#CallVoteRatio {
+	margin: 1px 12px 0 0;
+	width: 20.4%;
+}
+.srvopts_importexport input,
+.srvopts_importexport select {
+	float: left;
+}
+.srvopts_importexport input[type="radio"] {
+	height: 21px;
+}
+.srvopts_importexport #srvoptsImportName,
+.srvopts_importexport #srvoptsExportName {
+	margin-left: 10px;
+}
+
+
+/* Page Game infos
+---------------------- */
+.section-gameinfos td.key,
+.section-gameinfos td.value {
+	width: 27%;
+}
+.section-gameinfos .preview,
+.section-maps-creatematchset .preview {
+	text-align: left;
+}
+.section-gameinfos .preview a,
+.section-maps-creatematchset .preview a {
+	display: block;
+	line-height: 12px;
+	color: #aaa;
+	font-size: .85em;
+}
+.section-gameinfos .preview a:hover,
+.section-maps-creatematchset .preview a:hover {
+	color: #888;
+	text-decoration: none;
+}
+.section-gameinfos .content.gameinfos {
+	min-height: 500px;
+}
+#getScriptSettingsDialog {
+	color: #666;
+	font-size: .95em;
+}
+#getScriptSettingsDialog tr:hover,
+#getScriptSettingsDialog td:hover {
+	background: none;
+	cursor: default;
+}
+#getScriptSettingsDialog td.key {
+	width: 170px;
+}
+#getScriptSettingsDialog td.value {
+	width: auto;
+}
+#dialogScriptSettings thead tr {
+	height: 20px;
+}
+#dialogScriptSettings tbody td {
+	border-bottom: 1px solid #f5f5f5;
+}
+#dialogScriptSettings tbody td.first {
+	padding: 0 9px;
+	width: 170px;
+	text-align: right;
+	border-right: 1px dotted #636363;
+}
+#dialogScriptSettings tbody td.middle {
+	padding-left: 10px;
+	width: 200px;
+	text-align: left;
+}
+#dialogScriptSettings tbody td.last {
+	font-style: italic;
+	text-align: left;
+}
+
+
+/* Page Chat
+---------------------- */
+.section-chat #chat {
+	min-height: 432px;
+}
+.section-chat #chat .tmnick_global {
+	display: block;
+	line-height: 17px;
+	overflow: hidden;
+}
+.section-chat .options {
+	padding: 6px 10px;
+}
+.section-chat .options input.text,
+.section-chat .options select {
+	float: left;
+	margin-right: 20px;
+	height: 20px;
+	color: #aaa;
+	border: 0;
+	-webkit-border-radius: 3px 0 0 3px;
+	-moz-border-radius: 3px 0 0 3px;
+	-ms-border-radius: 3px 0 0 3px;
+	-o-border-radius: 3px 0 0 3px;
+	border-radius: 3px 0 0 3px;
+	-webkit-box-shadow: 4px 0 0 #b0b0b0;
+	-moz-box-shadow: 4px 0 0 #b0b0b0;
+	-ms-box-shadow: 4px 0 0 #b0b0b0;
+	-o-box-shadow: 4px 0 0 #b0b0b0;
+	box-shadow: 4px 0 0 #b0b0b0;
+}
+.section-chat .options input.text:hover,
+.section-chat .options select:hover,
+.section-chat .options input.text:focus,
+.section-chat .options select:focus {
+	color: inherit;
+}
+.section-chat .options select {
+	padding: 5px 5px 3px;
+	height: 26px;
+	font-size: .9em;
+}
+.section-chat #chatColor,
+.section-chat #chatDestination,
+.section-chat #chatSend {
+	width: 12%;
+}
+.section-chat #chatNickname {
+	width: 15%;
+}
+.section-chat #chatMessage {
+	width: 38%;
+}
+.section-chat #chatSend {
+	margin: 0;
+}
+
+/* Page Maps
+----------------------- */
+.menu .vertical-nav li a,
+.folders .folder-list li a {
+	display: block;
+	padding: 8px 10px;
+	height: auto;
+	line-height: 14px;
+	color: #888;
+	font-size: 1.1em;
+	font-weight: bold;
+	font-variant: small-caps;
+	text-decoration: none;
+	border-bottom: 1px solid #d9e8ff;
+	-webkit-border-radius: 2px;
+	-moz-border-radius: 2px;
+	-ms-border-radius: 2px;
+	-o-border-radius: 2px;
+	border-radius: 2px;
+}
+.menu .vertical-nav li:last-child a {
+	border: 0;
+}
+.menu .vertical-nav li a.active,
+.menu .vertical-nav li a:hover {
+	color: #fff;
+	background: #5e9cd5;
+}
+
+/* Dossiers */
+.folders .title-detail {
+	right: 15px;
+	font-size: .8em;
+}
+.folders .folder-list {
+	margin-bottom: 16px;
+}
+.folders .folder-list li a {
+	padding: 6px 10px;
+	border-bottom-color: #f4f398;
+}
+.folders .folder-list li a.active,
+.folders .folder-list li a:hover {
+	background: #f7f6b6;
+}
+.folders .folder-list li a .dir-name {
+	font-size: .8em;
+	font-variant: normal;
+}
+.folders .folder-list li a .dir-info {
+	float: right;
+	font-size: .8em;
+	font-weight: normal;
+}
+.folders .folder-list li a img {
+	margin: 0 7px -3px 0;
+}
+.folders .folder-list .no-result {
+	padding: 8px 0;
+	font-style: italic;
+	text-align: center;
+}
+.path {
+	width: 400px;
+	text-align: right;
+	white-space: nowrap;
+	overflow: hidden;
+}
+/* Nouveau dossier */
+#form-new-folder {
+	display: block;
+	margin: 6px 0;
+}
+#form-new-folder[hidden=hidden] {
+	display: none !important;
+}
+#form-new-folder input.text {
+	margin-right: 8px;
+	width: 105px;
+	height: 17px;
+	vertical-align: top;
+}
+#form-new-folder input.button {
+	padding: 2px;
+}
+/* Option de dossier */
+.folders .option-folder-list h3 {
+	cursor: pointer;
+}
+.folders .option-folder-list .arrow-down,
+.folders .option-folder-list .arrow-up {
+	display: block;
+	float: right;
+	margin: 5px 10px 0 0;
+	width: 0;
+	height: 0;
+	border-style: solid;
+}
+.folders .option-folder-list .arrow-down {
+	border-width: 5px 5px 0 5px;
+	border-color: #5e9cd5 transparent transparent transparent;
+}
+.folders .option-folder-list .arrow-up {
+	border-width: 0 5px 5px 5px;
+	border-color: transparent transparent #5e9cd5 transparent;
+}
+.folders .option-folder-list li {
+	margin-bottom: 1px;
+}
+.folders .option-folder-list a {
+	display: block;
+	padding-left: 30px;
+	background-repeat: no-repeat;
+	background-position: 5px center;
+	border: 0;
+}
+.folders .option-folder-list a:hover {
+	background-color: #999;
+}
+.folders .option-folder-list .button.light,
+.folders .option-folder-list .button.light:hover {
+	-webkit-box-shadow: none;
+	-moz-box-shadow: none;
+	-ms-box-shadow: none;
+	-o-box-shadow: none;
+	box-shadow: none;
+}
+.folders .option-folder-list .rename {
+	background-image: url("../images/16/edit.png");
+}
+.folders .option-folder-list .move {
+	background-image: url("../images/16/blue_arrow_up.png");
+}
+.folders .option-folder-list .delete {
+	background-image: url("../images/16/delete.png");
+}
+#renameFolderForm {
+	margin: 10% 0;
+	height: 36px !important;
+	overflow: hidden;
+}
+#moveFolderForm {
+	margin: 10% 0;
+	height: 72px !important;
+	overflow: hidden;
+}
+
+
+/* Page Maps-local
+------------------*/
+.section-maps-local .options-checkbox {
+	margin-top: 10px;
+}
+#renameFolderNewName {
+	width: 50%;
+}
+#renameMapList {
+	width: 53%;
+}
+
+
+/* Page upload
+------------------*/
+.section-maps-upload .path {
+	margin-right: 5px;
+}
+.section-maps-upload .options-checkbox {
+	margin-bottom: 30px;
+}
+
+
+/* Page Maps-Order
+---------------------- */
+.ui-sortable li {
+	margin: 2px 0;
+	padding: 5px;
+	min-height: 17px;
+	color: #666;
+	font-weight: normal;
+	overflow: hidden;
+	cursor: pointer;
+	-webkit-border-radius: 3px;
+	-moz-border-radius: 3px;
+	-ms-border-radius: 3px;
+	-o-border-radius: 3px;
+	border-radius: 3px;
+}
+.ui-sortable li:hover {
+	background: #d9e8ff;
+}
+.ui-sortable li div {
+	float: left;
+}
+.ui-sortable li .order-map-name,
+.ui-sortable li .order-server-name {
+	padding: 0 10px;
+	width: 50%;
+}
+.ui-sortable li .order-server-name {
+	font-weight: bold;
+}
+.ui-sortable li .order-server-addr-port,
+.ui-sortable li .order-map-env,
+.ui-sortable li .order-map-author {
+	padding: 0 10px;
+	width: 20%;
+}
+.ui-sortable li .order-map-env img,
+.ui-sortable li .order-map-author img {
+	margin: 0 5px -3px 0;
+}
+.autoSortMode.options-radio-inline li {
+	width: 174px;
+	color: #666;
+}
+.autoSortMode.options-radio-inline li .name {
+	margin-top: 8px;
+	width: 100px;
+	font-size: .9em;
+}
+
+
+/* Page Maps Create MatchSettings
+---------------------- */
+#matchSettingName {
+	width: 250px;
+}
+#matchSettingNameExists {
+	float: right;
+	margin: 4px 0;
+	padding: 0 3px 0 2px;
+	line-height: 16px;
+	font-size: .85em;
+	-webkit-border-radius: 3px;
+	-moz-border-radius: 3px;
+	-ms-border-radius: 3px;
+	-o-border-radius: 3px;
+	border-radius: 3px;
+}
+#matchSettingNameExists span {
+	float: left;
+	margin-right: 3px;
+}
+.section-maps-creatematchset td.key,
+.section-maps-creatematchset td.value {
+	width: 40%;
+}
+.section-maps-creatematchset .mapsSelection {
+	margin: 10px 0 20px;
+	height: 30px;
+	overflow: hidden;
+}
+.section-maps-creatematchset .mapsSelection select {
+	width: 200px;
+}
+.section-maps-creatematchset .mapsSelection input {
+	float: right;
+	margin-left: 10px;
+}
+.section-maps-creatematchset .mapsSelection input + input {
+	margin: 0;
+}
+.section-maps-creatematchset .mapsSelected {
+	padding-top: 10px;
+	height: 30px;
+	border-top: 1px solid #ddd;
+	overflow: hidden;
+}
+.section-maps-creatematchset .mapsSelected p {
+	float: left;
+	margin: 4px 0 0;
+}
+.section-maps-creatematchset .mapsSelected input {
+	float: right;
+}
+.section-maps-creatematchset #mapSelectionDialog tr {
+	cursor: default;
+}
+
+
+/* Page plugins
+--------------------*/
+.section-plugins-list .content ul {
+	margin: 12px 0;
+	padding-left: 40px;
+}
+.section-plugins-list .content li {
+	list-style-type: disc;
+}
+
+
+/* Page Guest-Ban
+---------------------- */
+#banlist,
+#blacklist,
+#guestlist,
+#ignorelist,
+#playlists {
+	position: relative;
+}
+#banlist .title-detail,
+#blacklist .title-detail,
+#guestlist .title-detail,
+#ignorelist .title-detail,
+#playlists .title-detail {
+	top: 4px;
+	right: 0;
+}
+.section-guestban table {
+	margin-bottom: 25px;
+}
+.section-guestban .addPlayer {
+	margin-bottom: 25px;
+	padding: 5px;
+}
+.section-guestban .addPlayer select,
+.section-guestban .addPlayer .text {
+	float: left;
+	margin-right: 24px;
+}
+.section-guestban .addPlayer .text {
+	width: 41%;
+}
+.section-guestban .addPlayer #addPlayerList {
+	width: 44%;
+}
+.section-guestban .addPlayer .addPlayerTypeList {
+	width: 120px;
+}
+.section-guestban .addPlayer .button {
+	width: 90px;
+	margin: 0;
+}
+#form-new-playlist {
+	display: block;
+	margin: 6px 0 8px;
+}
+#form-new-playlist[hidden=hidden] {
+	display: none !important;
+}
+#form-new-playlist select {
+	width: 120px;
+	margin-right: 12px;
+	padding: 3px 5px 2px;
+	vertical-align: top;
+}
+#form-new-playlist .text {
+	width: 202px;
+	height: 17px;
+	margin-right: 12px;
+	vertical-align: top;
+}
+#form-new-playlist .button {
+	width: 90px;
+	font-size: .9em;
+}
+
+/* Couleurs GameMode & Jeux
+----------------------------- */
+.rounds {
+	color: #ffcc11;
+}
+.timeattack {
+	color: #d1321e;
+}
+.team {
+	color: #aabb00;
+}
+.laps {
+	color: #88aa11;
+}
+.stunts {
+	color: #5600da;
+}
+.cup {
+	color: #ff8c11;
+}
+.script,
+.other {
+	color: #444;
+}
+.maniaplanet {
+	color: #2277cc;
+}
+.tmforever {
+	color: #ad0000;
+}
+.team_-1,
+.team_0,
+.team_1 {
+	display: block;
+	float: left;
+	margin-right: 5px;
+	width: 7px;
+	height: 16px;
+	opacity: .8;
+}
+.team_-1 {
+	background: #000;
+}
+.team_0 {
+	background: #00f;
+}
+.team_1 {
+	background: #f00;
+}
+
+
+/* TmNick
+------------------------ */
+.tmnick_global {
+	font-weight: none;
+	font-style: normal;
+	letter-spacing: 0;
+}
+.tmnick_normal {
+	letter-spacing: 0;
+}
+.tmnick_short {
+	letter-spacing: -1px;
+}
+.tmnick_wide {
+	letter-spacing: 2px;
+}
+.tmnick_raz {
+	font-weight: none;
+	font-style: normal;
+	letter-spacing: 0;
+}
+.tmnick_italic {
+	font-style: italic;
+}
+.tmnick_bold {
+	font-weight: bold;
+	letter-spacing: 1px;
+}
+.tmnick_upper {
+	text-transform: uppercase;
+}
+.tmnick_shadowed {
+	text-shadow: 1px 1px 1px #444;
+}
+.tmnick_internallink,
+.tmnick_internallink:visited {
+	color: inherit;
+	text-decoration: none;
+	border-bottom: 1px solid #000;
+}
+.tmnick_internallink:hover {
+	color: inherit;
+	text-decoration: none;
+	border-bottom: 1px solid Blue;
+}
+.tmnick_internallink_withlogin,
+.tmnick_internallink_withlogin:visited  {
+	color: inherit;
+	text-decoration: none;
+	border-bottom: 1px solid #f0e68c;
+}
+.tmnick_internallink_withlogin:hover {
+	color: inherit;
+	text-decoration: none;
+	border-bottom: 1px solid Gold;
+}
+.tmnick_externallink {
+	line-height: 18px;
+	color: inherit;
+	text-decoration: none;
+	border-bottom: 1px solid  #75481e;
+}
+.tmnick_externallink:hover {
+	color: inherit;
+	border-color: Orange;
+}
+
+
+/* ColorPicker
+------------------------*/
+.section-gameinfos .colorSelectorWrapper {
+	float: right;
+	position: relative;
+}
+.section-gameinfos .colorSelector {
+	position: absolute;
+	top: 0;
+	right: 38px;
+	border-width: 2px 0 2px 2px;
+}
+.colorSelector {
+	position: relative;
+	width: 20px;
+	height: 20px;
+	border: 2px solid #ddd;
+	cursor: pointer;
+}
+.colorpicker {
+	display: none;
+	position: absolute;
+	top: 22px;
+	left: -2px;
+	z-index: 1000;
+	width: 47px;
+	height: 169px;
+	background: #ddd;
+	overflow: hidden;
+}
+.colorpicker_hue {
+	position: absolute;
+	top: 9px;
+	left: 6px;
+	width: 35px;
+	height: 150px;
+	background: url("../images/colorpicker/slider.png") no-repeat center top;
+	cursor: n-resize;
+}
+.colorpicker_hue > div {
+	position: absolute;
+	left: 0;
+	margin: -4px 0 0;
+	width: 35px;
+	height: 9px;
+	background: url("../images/colorpicker/picker.png") no-repeat;
+	overflow: hidden;
+}
+.colorpicker_color,
+.colorpicker_new_color,
+.colorpicker_field,
+.colorpicker_hex,
+.colorpicker_submit,
+.colorpicker_current_color {
+	display: none;
+}
+
+
+/* DisplayServ
+-------------------- */
+#displayserv {
+	width: 80%;
+	margin: 20px auto 30px;
+}
+
+
+/* Danish
+------------------------*/
+html[lang="dk"] #connection-inner .connection-label {
+	width: 85%;
+}
+html[lang="dk"] .section-servers-online-config fieldset {
+	width: 575px;
+}
\ No newline at end of file
diff --git a/resources/css/ie.css b/resources/css/ie.css
new file mode 100644
index 0000000..deaf32b
--- /dev/null
+++ b/resources/css/ie.css
@@ -0,0 +1,12 @@
+.title-detail #detailMode {
+	vertical-align: middle;
+}
+.title-detail .last input {
+	margin-top: -3px;
+}
+.tmnick_shadowed {
+	color: #666 !important;
+}
+.options-radio-inline li .name {
+	width: 127px;
+}
\ No newline at end of file
diff --git a/resources/css/jqueryui/black.css b/resources/css/jqueryui/black.css
new file mode 100644
index 0000000..bdc8a20
--- /dev/null
+++ b/resources/css/jqueryui/black.css
@@ -0,0 +1,1177 @@
+/*! jQuery UI - v1.10.3 - 2013-06-08
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%23727272&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%23727272&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%23727272&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%23727272&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%23727272&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23ccc&fcHighlight=%23444444&iconColorHighlight=%23727272&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+	display: none;
+}
+.ui-helper-hidden-accessible {
+	border: 0;
+	clip: rect(0 0 0 0);
+	height: 1px;
+	margin: -1px;
+	overflow: hidden;
+	padding: 0;
+	position: absolute;
+	width: 1px;
+}
+.ui-helper-reset {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	outline: 0;
+	line-height: 1.3;
+	text-decoration: none;
+	font-size: 100%;
+	list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+	content: "";
+	display: table;
+	border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+	clear: both;
+}
+.ui-helper-clearfix {
+	min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+	width: 100%;
+	height: 100%;
+	top: 0;
+	left: 0;
+	position: absolute;
+	opacity: 0;
+	filter:Alpha(Opacity=0);
+}
+
+.ui-front {
+	z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+	cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	display: block;
+	text-indent: -99999px;
+	overflow: hidden;
+	background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+}
+.ui-resizable {
+	position: relative;
+}
+.ui-resizable-handle {
+	position: absolute;
+	font-size: 0.1px;
+	display: block;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+	display: none;
+}
+.ui-resizable-n {
+	cursor: n-resize;
+	height: 7px;
+	width: 100%;
+	top: -5px;
+	left: 0;
+}
+.ui-resizable-s {
+	cursor: s-resize;
+	height: 7px;
+	width: 100%;
+	bottom: -5px;
+	left: 0;
+}
+.ui-resizable-e {
+	cursor: e-resize;
+	width: 7px;
+	right: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-w {
+	cursor: w-resize;
+	width: 7px;
+	left: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-se {
+	cursor: se-resize;
+	width: 12px;
+	height: 12px;
+	right: 1px;
+	bottom: 1px;
+}
+.ui-resizable-sw {
+	cursor: sw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	bottom: -5px;
+}
+.ui-resizable-nw {
+	cursor: nw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	top: -5px;
+}
+.ui-resizable-ne {
+	cursor: ne-resize;
+	width: 9px;
+	height: 9px;
+	right: -5px;
+	top: -5px;
+}
+.ui-selectable-helper {
+	position: absolute;
+	z-index: 100;
+	border: 1px dotted black;
+}
+.ui-accordion .ui-accordion-header {
+	display: block;
+	cursor: pointer;
+	position: relative;
+	margin-top: 2px;
+	padding: .5em .5em .5em .7em;
+	min-height: 0; /* support: IE7 */
+}
+.ui-accordion .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-noicons {
+	padding-left: .7em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+	position: absolute;
+	left: .5em;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+	padding: 1em 2.2em;
+	border-top: 0;
+	overflow: auto;
+}
+.ui-autocomplete {
+	position: absolute;
+	top: 0;
+	left: 0;
+	cursor: default;
+}
+.ui-button {
+	display: inline-block;
+	position: relative;
+	padding: 0;
+	line-height: normal;
+	margin-right: .1em;
+	cursor: pointer;
+	vertical-align: middle;
+	text-align: center;
+	overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+	text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+	width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+	width: 2.4em;
+}
+.ui-button-icons-only {
+	width: 3.4em;
+}
+button.ui-button-icons-only {
+	width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+	display: block;
+	line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+	padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+	padding: .4em;
+	text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+	padding-left: 2.1em;
+	padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+	padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+	position: absolute;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+	left: 50%;
+	margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+	left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+	right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+	margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+	margin-left: 0;
+	margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+	border: 0;
+	padding: 0;
+}
+.ui-datepicker {
+	width: 17em;
+	padding: .2em .2em 0;
+	display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+	position: relative;
+	padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+	position: absolute;
+	top: 2px;
+	width: 1.8em;
+	height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+	top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+	left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+	right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+	left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+	right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+	display: block;
+	position: absolute;
+	left: 50%;
+	margin-left: -8px;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+	margin: 0 2.3em;
+	line-height: 1.8em;
+	text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+	font-size: 1em;
+	margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month-year {
+	width: 100%;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+	width: 49%;
+}
+.ui-datepicker table {
+	width: 100%;
+	font-size: .9em;
+	border-collapse: collapse;
+	margin: 0 0 .4em;
+}
+.ui-datepicker th {
+	padding: .7em .3em;
+	text-align: center;
+	font-weight: bold;
+	border: 0;
+}
+.ui-datepicker td {
+	border: 0;
+	padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+	display: block;
+	padding: .2em;
+	text-align: right;
+	text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+	background-image: none;
+	margin: .7em 0 0 0;
+	padding: 0 .2em;
+	border-left: 0;
+	border-right: 0;
+	border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+	float: right;
+	margin: .5em .2em .4em;
+	cursor: pointer;
+	padding: .2em .6em .3em .6em;
+	width: auto;
+	overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+	float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+	width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+	float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+	width: 95%;
+	margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+	width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+	width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+	width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+	border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+	clear: left;
+}
+.ui-datepicker-row-break {
+	clear: both;
+	width: 100%;
+	font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+	direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+	right: 2px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+	left: 2px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+	right: 1px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+	left: 1px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+	clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+	float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+	float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+	border-right-width: 0;
+	border-left-width: 1px;
+}
+.ui-dialog {
+	position: absolute;
+	top: 0;
+	left: 0;
+	padding: .2em;
+	outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+	padding: .4em 1em;
+	position: relative;
+}
+.ui-dialog .ui-dialog-title {
+	float: left;
+	margin: .1em 0;
+	white-space: nowrap;
+	width: 90%;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+	position: absolute;
+	right: .3em;
+	top: 50%;
+	width: 21px;
+	margin: -10px 0 0 0;
+	padding: 1px;
+	height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+	position: relative;
+	border: 0;
+	padding: .5em 1em;
+	background: none;
+	overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+	text-align: left;
+	border-width: 1px 0 0 0;
+	background-image: none;
+	margin-top: .5em;
+	padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+	float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+	margin: .5em .4em .5em 0;
+	cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+	width: 12px;
+	height: 12px;
+	right: -5px;
+	bottom: -5px;
+	background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+	cursor: move;
+}
+.ui-menu {
+	list-style: none;
+	padding: 2px;
+	margin: 0;
+	display: block;
+	outline: none;
+}
+.ui-menu .ui-menu {
+	margin-top: -3px;
+	position: absolute;
+}
+.ui-menu .ui-menu-item {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	/* support: IE10, see #8844 */
+	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
+}
+.ui-menu .ui-menu-divider {
+	margin: 5px -2px 5px -2px;
+	height: 0;
+	font-size: 0;
+	line-height: 0;
+	border-width: 1px 0 0 0;
+}
+.ui-menu .ui-menu-item a {
+	text-decoration: none;
+	display: block;
+	padding: 2px .4em;
+	line-height: 1.5;
+	min-height: 0; /* support: IE7 */
+	font-weight: normal;
+}
+.ui-menu .ui-menu-item a.ui-state-focus,
+.ui-menu .ui-menu-item a.ui-state-active {
+	font-weight: normal;
+	margin: -1px;
+}
+
+.ui-menu .ui-state-disabled {
+	font-weight: normal;
+	margin: .4em 0 .2em;
+	line-height: 1.5;
+}
+.ui-menu .ui-state-disabled a {
+	cursor: default;
+}
+
+/* icon support */
+.ui-menu-icons {
+	position: relative;
+}
+.ui-menu-icons .ui-menu-item a {
+	position: relative;
+	padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+	position: absolute;
+	top: .2em;
+	left: .2em;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+	position: static;
+	float: right;
+}
+.ui-progressbar {
+	height: 2em;
+	text-align: left;
+	overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+	margin: -1px;
+	height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+	background: url("../../images/jqueryui/black/animated-overlay.gif");
+	height: 100%;
+	filter: alpha(opacity=25);
+	opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+	background-image: none;
+}
+.ui-slider {
+	position: relative;
+	text-align: left;
+}
+.ui-slider .ui-slider-handle {
+	position: absolute;
+	z-index: 2;
+	width: 1.2em;
+	height: 1.2em;
+	cursor: default;
+}
+.ui-slider .ui-slider-range {
+	position: absolute;
+	z-index: 1;
+	font-size: .7em;
+	display: block;
+	border: 0;
+	background-position: 0 0;
+}
+
+/* For IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+	filter: inherit;
+}
+
+.ui-slider-horizontal {
+	height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+	top: -.3em;
+	margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+	top: 0;
+	height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+	left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+	right: 0;
+}
+
+.ui-slider-vertical {
+	width: .8em;
+	height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+	left: -.3em;
+	margin-left: 0;
+	margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+	left: 0;
+	width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+	bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+	top: 0;
+}
+.ui-spinner {
+	position: relative;
+	display: inline-block;
+	overflow: hidden;
+	padding: 0;
+	vertical-align: middle;
+}
+.ui-spinner-input {
+	border: none;
+	background: none;
+	color: inherit;
+	padding: 0;
+	margin: .2em 0;
+	vertical-align: middle;
+	margin-left: .4em;
+	margin-right: 22px;
+}
+.ui-spinner-button {
+	width: 16px;
+	height: 50%;
+	font-size: .5em;
+	padding: 0;
+	margin: 0;
+	text-align: center;
+	position: absolute;
+	cursor: default;
+	display: block;
+	overflow: hidden;
+	right: 0;
+}
+/* more specificity required here to overide default borders */
+.ui-spinner a.ui-spinner-button {
+	border-top: none;
+	border-bottom: none;
+	border-right: none;
+}
+/* vertical centre icon */
+.ui-spinner .ui-icon {
+	position: absolute;
+	margin-top: -8px;
+	top: 50%;
+	left: 0;
+}
+.ui-spinner-up {
+	top: 0;
+}
+.ui-spinner-down {
+	bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+	/* need to fix icons sprite */
+	background-position: -65px -16px;
+}
+.ui-tabs {
+	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+	padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+	margin: 0;
+	padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+	list-style: none;
+	float: left;
+	position: relative;
+	top: 0;
+	margin: 1px .2em 0 0;
+	border-bottom-width: 0;
+	padding: 0;
+	white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav li a {
+	float: left;
+	padding: .5em 1em;
+	text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+	margin-bottom: -1px;
+	padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
+	cursor: text;
+}
+.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
+	cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+	display: block;
+	border-width: 0;
+	padding: 1em 1.4em;
+	background: none;
+}
+.ui-tooltip {
+	padding: 8px;
+	position: absolute;
+	z-index: 9999;
+	max-width: 300px;
+	-webkit-box-shadow: 0 0 5px #aaa;
+	box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+	border-width: 2px;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+	font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1em;
+}
+.ui-widget-content {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/black/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-widget-content a {
+	color: #444444;
+}
+.ui-widget-header {
+	border: 1px solid #dddddd;
+	background: #dddddd url("../../images/jqueryui/black/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
+	color: #444444;
+	font-weight: bold;
+}
+.ui-widget-header a {
+	color: #444444;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+	border: 1px solid #dddddd;
+	background: #f6f6f6 url("../../images/jqueryui/black/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #444;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+	color: #444;
+	text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+	border: 1px solid #727272;
+	background: #727272 url("../../images/jqueryui/black/ui-bg_highlight-soft_25_727272_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #ffffff;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited {
+	color: #ffffff;
+	text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/black/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #727272;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+	color: #727272;
+	text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+	border: 1px solid #ccc;
+	background: #ffffff url("../../images/jqueryui/black/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+	color: #444444;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+	border: 1px solid #EA4F4F;
+	background: #ffffff url("../../images/jqueryui/black/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #222222;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+	color: #222222;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+	color: #222222;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+	font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+	opacity: .7;
+	filter:Alpha(Opacity=70);
+	font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+	opacity: .35;
+	filter:Alpha(Opacity=35);
+	background-image: none;
+}
+.ui-state-disabled .ui-icon {
+	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	width: 16px;
+	height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+	background-image: url("../../images/jqueryui/black/ui-icons_727272_256x240.png");
+}
+.ui-widget-header .ui-icon {
+	background-image: url("../../images/jqueryui/black/ui-icons_727272_256x240.png");
+}
+.ui-state-default .ui-icon {
+	background-image: url("../../images/jqueryui/black/ui-icons_666666_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+	background-image: url("../../images/jqueryui/black/ui-icons_ffffff_256x240.png");
+}
+.ui-state-active .ui-icon {
+	background-image: url("../../images/jqueryui/black/ui-icons_454545_256x240.png");
+}
+.ui-state-highlight .ui-icon {
+	background-image: url("../../images/jqueryui/black/ui-icons_727272_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+	background-image: url("../../images/jqueryui/black/ui-icons_EA4F4F_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -97px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+	border-top-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+	border-top-right-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+	border-bottom-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+	border-bottom-right-radius: 2px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+	background: #eeeeee url("../../images/jqueryui/black/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
+	opacity: .8;
+	filter: Alpha(Opacity=80);
+}
+.ui-widget-shadow {
+	margin: -4px 0 0 -4px;
+	padding: 4px;
+	background: #aaaaaa url("../../images/jqueryui/black/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
+	opacity: .6;
+	filter: Alpha(Opacity=60);
+	border-radius: 0px;
+}
diff --git a/resources/css/jqueryui/blue.css b/resources/css/jqueryui/blue.css
new file mode 100644
index 0000000..f546588
--- /dev/null
+++ b/resources/css/jqueryui/blue.css
@@ -0,0 +1,1177 @@
+/*! jQuery UI - v1.10.3 - 2013-06-08
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%235e9cd5&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%235e9cd5&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%235e9cd5&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%235e9cd5&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%235e9cd5&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23cccccc&fcHighlight=%23444444&iconColorHighlight=%235e9cd5&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+	display: none;
+}
+.ui-helper-hidden-accessible {
+	border: 0;
+	clip: rect(0 0 0 0);
+	height: 1px;
+	margin: -1px;
+	overflow: hidden;
+	padding: 0;
+	position: absolute;
+	width: 1px;
+}
+.ui-helper-reset {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	outline: 0;
+	line-height: 1.3;
+	text-decoration: none;
+	font-size: 100%;
+	list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+	content: "";
+	display: table;
+	border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+	clear: both;
+}
+.ui-helper-clearfix {
+	min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+	width: 100%;
+	height: 100%;
+	top: 0;
+	left: 0;
+	position: absolute;
+	opacity: 0;
+	filter:Alpha(Opacity=0);
+}
+
+.ui-front {
+	z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+	cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	display: block;
+	text-indent: -99999px;
+	overflow: hidden;
+	background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+}
+.ui-resizable {
+	position: relative;
+}
+.ui-resizable-handle {
+	position: absolute;
+	font-size: 0.1px;
+	display: block;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+	display: none;
+}
+.ui-resizable-n {
+	cursor: n-resize;
+	height: 7px;
+	width: 100%;
+	top: -5px;
+	left: 0;
+}
+.ui-resizable-s {
+	cursor: s-resize;
+	height: 7px;
+	width: 100%;
+	bottom: -5px;
+	left: 0;
+}
+.ui-resizable-e {
+	cursor: e-resize;
+	width: 7px;
+	right: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-w {
+	cursor: w-resize;
+	width: 7px;
+	left: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-se {
+	cursor: se-resize;
+	width: 12px;
+	height: 12px;
+	right: 1px;
+	bottom: 1px;
+}
+.ui-resizable-sw {
+	cursor: sw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	bottom: -5px;
+}
+.ui-resizable-nw {
+	cursor: nw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	top: -5px;
+}
+.ui-resizable-ne {
+	cursor: ne-resize;
+	width: 9px;
+	height: 9px;
+	right: -5px;
+	top: -5px;
+}
+.ui-selectable-helper {
+	position: absolute;
+	z-index: 100;
+	border: 1px dotted black;
+}
+.ui-accordion .ui-accordion-header {
+	display: block;
+	cursor: pointer;
+	position: relative;
+	margin-top: 2px;
+	padding: .5em .5em .5em .7em;
+	min-height: 0; /* support: IE7 */
+}
+.ui-accordion .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-noicons {
+	padding-left: .7em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+	position: absolute;
+	left: .5em;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+	padding: 1em 2.2em;
+	border-top: 0;
+	overflow: auto;
+}
+.ui-autocomplete {
+	position: absolute;
+	top: 0;
+	left: 0;
+	cursor: default;
+}
+.ui-button {
+	display: inline-block;
+	position: relative;
+	padding: 0;
+	line-height: normal;
+	margin-right: .1em;
+	cursor: pointer;
+	vertical-align: middle;
+	text-align: center;
+	overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+	text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+	width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+	width: 2.4em;
+}
+.ui-button-icons-only {
+	width: 3.4em;
+}
+button.ui-button-icons-only {
+	width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+	display: block;
+	line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+	padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+	padding: .4em;
+	text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+	padding-left: 2.1em;
+	padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+	padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+	position: absolute;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+	left: 50%;
+	margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+	left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+	right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+	margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+	margin-left: 0;
+	margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+	border: 0;
+	padding: 0;
+}
+.ui-datepicker {
+	width: 17em;
+	padding: .2em .2em 0;
+	display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+	position: relative;
+	padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+	position: absolute;
+	top: 2px;
+	width: 1.8em;
+	height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+	top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+	left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+	right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+	left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+	right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+	display: block;
+	position: absolute;
+	left: 50%;
+	margin-left: -8px;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+	margin: 0 2.3em;
+	line-height: 1.8em;
+	text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+	font-size: 1em;
+	margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month-year {
+	width: 100%;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+	width: 49%;
+}
+.ui-datepicker table {
+	width: 100%;
+	font-size: .9em;
+	border-collapse: collapse;
+	margin: 0 0 .4em;
+}
+.ui-datepicker th {
+	padding: .7em .3em;
+	text-align: center;
+	font-weight: bold;
+	border: 0;
+}
+.ui-datepicker td {
+	border: 0;
+	padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+	display: block;
+	padding: .2em;
+	text-align: right;
+	text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+	background-image: none;
+	margin: .7em 0 0 0;
+	padding: 0 .2em;
+	border-left: 0;
+	border-right: 0;
+	border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+	float: right;
+	margin: .5em .2em .4em;
+	cursor: pointer;
+	padding: .2em .6em .3em .6em;
+	width: auto;
+	overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+	float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+	width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+	float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+	width: 95%;
+	margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+	width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+	width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+	width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+	border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+	clear: left;
+}
+.ui-datepicker-row-break {
+	clear: both;
+	width: 100%;
+	font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+	direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+	right: 2px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+	left: 2px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+	right: 1px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+	left: 1px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+	clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+	float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+	float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+	border-right-width: 0;
+	border-left-width: 1px;
+}
+.ui-dialog {
+	position: absolute;
+	top: 0;
+	left: 0;
+	padding: .2em;
+	outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+	padding: .4em 1em;
+	position: relative;
+}
+.ui-dialog .ui-dialog-title {
+	float: left;
+	margin: .1em 0;
+	white-space: nowrap;
+	width: 90%;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+	position: absolute;
+	right: .3em;
+	top: 50%;
+	width: 21px;
+	margin: -10px 0 0 0;
+	padding: 1px;
+	height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+	position: relative;
+	border: 0;
+	padding: .5em 1em;
+	background: none;
+	overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+	text-align: left;
+	border-width: 1px 0 0 0;
+	background-image: none;
+	margin-top: .5em;
+	padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+	float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+	margin: .5em .4em .5em 0;
+	cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+	width: 12px;
+	height: 12px;
+	right: -5px;
+	bottom: -5px;
+	background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+	cursor: move;
+}
+.ui-menu {
+	list-style: none;
+	padding: 2px;
+	margin: 0;
+	display: block;
+	outline: none;
+}
+.ui-menu .ui-menu {
+	margin-top: -3px;
+	position: absolute;
+}
+.ui-menu .ui-menu-item {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	/* support: IE10, see #8844 */
+	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
+}
+.ui-menu .ui-menu-divider {
+	margin: 5px -2px 5px -2px;
+	height: 0;
+	font-size: 0;
+	line-height: 0;
+	border-width: 1px 0 0 0;
+}
+.ui-menu .ui-menu-item a {
+	text-decoration: none;
+	display: block;
+	padding: 2px .4em;
+	line-height: 1.5;
+	min-height: 0; /* support: IE7 */
+	font-weight: normal;
+}
+.ui-menu .ui-menu-item a.ui-state-focus,
+.ui-menu .ui-menu-item a.ui-state-active {
+	font-weight: normal;
+	margin: -1px;
+}
+
+.ui-menu .ui-state-disabled {
+	font-weight: normal;
+	margin: .4em 0 .2em;
+	line-height: 1.5;
+}
+.ui-menu .ui-state-disabled a {
+	cursor: default;
+}
+
+/* icon support */
+.ui-menu-icons {
+	position: relative;
+}
+.ui-menu-icons .ui-menu-item a {
+	position: relative;
+	padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+	position: absolute;
+	top: .2em;
+	left: .2em;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+	position: static;
+	float: right;
+}
+.ui-progressbar {
+	height: 2em;
+	text-align: left;
+	overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+	margin: -1px;
+	height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+	background: url("../../images/jqueryui/blue/animated-overlay.gif");
+	height: 100%;
+	filter: alpha(opacity=25);
+	opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+	background-image: none;
+}
+.ui-slider {
+	position: relative;
+	text-align: left;
+}
+.ui-slider .ui-slider-handle {
+	position: absolute;
+	z-index: 2;
+	width: 1.2em;
+	height: 1.2em;
+	cursor: default;
+}
+.ui-slider .ui-slider-range {
+	position: absolute;
+	z-index: 1;
+	font-size: .7em;
+	display: block;
+	border: 0;
+	background-position: 0 0;
+}
+
+/* For IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+	filter: inherit;
+}
+
+.ui-slider-horizontal {
+	height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+	top: -.3em;
+	margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+	top: 0;
+	height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+	left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+	right: 0;
+}
+
+.ui-slider-vertical {
+	width: .8em;
+	height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+	left: -.3em;
+	margin-left: 0;
+	margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+	left: 0;
+	width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+	bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+	top: 0;
+}
+.ui-spinner {
+	position: relative;
+	display: inline-block;
+	overflow: hidden;
+	padding: 0;
+	vertical-align: middle;
+}
+.ui-spinner-input {
+	border: none;
+	background: none;
+	color: inherit;
+	padding: 0;
+	margin: .2em 0;
+	vertical-align: middle;
+	margin-left: .4em;
+	margin-right: 22px;
+}
+.ui-spinner-button {
+	width: 16px;
+	height: 50%;
+	font-size: .5em;
+	padding: 0;
+	margin: 0;
+	text-align: center;
+	position: absolute;
+	cursor: default;
+	display: block;
+	overflow: hidden;
+	right: 0;
+}
+/* more specificity required here to overide default borders */
+.ui-spinner a.ui-spinner-button {
+	border-top: none;
+	border-bottom: none;
+	border-right: none;
+}
+/* vertical centre icon */
+.ui-spinner .ui-icon {
+	position: absolute;
+	margin-top: -8px;
+	top: 50%;
+	left: 0;
+}
+.ui-spinner-up {
+	top: 0;
+}
+.ui-spinner-down {
+	bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+	/* need to fix icons sprite */
+	background-position: -65px -16px;
+}
+.ui-tabs {
+	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+	padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+	margin: 0;
+	padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+	list-style: none;
+	float: left;
+	position: relative;
+	top: 0;
+	margin: 1px .2em 0 0;
+	border-bottom-width: 0;
+	padding: 0;
+	white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav li a {
+	float: left;
+	padding: .5em 1em;
+	text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+	margin-bottom: -1px;
+	padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
+	cursor: text;
+}
+.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
+	cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+	display: block;
+	border-width: 0;
+	padding: 1em 1.4em;
+	background: none;
+}
+.ui-tooltip {
+	padding: 8px;
+	position: absolute;
+	z-index: 9999;
+	max-width: 300px;
+	-webkit-box-shadow: 0 0 5px #aaa;
+	box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+	border-width: 2px;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+	font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1em;
+}
+.ui-widget-content {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/blue/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-widget-content a {
+	color: #444444;
+}
+.ui-widget-header {
+	border: 1px solid #dddddd;
+	background: #dddddd url("../../images/jqueryui/blue/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
+	color: #444444;
+	font-weight: bold;
+}
+.ui-widget-header a {
+	color: #444444;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+	border: 1px solid #dddddd;
+	background: #f6f6f6 url("../../images/jqueryui/blue/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #444;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+	color: #444;
+	text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+	border: 1px solid #5e9cd5;
+	background: #5e9cd5 url("../../images/jqueryui/blue/ui-bg_highlight-soft_25_5e9cd5_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #ffffff;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited {
+	color: #ffffff;
+	text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/blue/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #5e9cd5;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+	color: #5e9cd5;
+	text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+	border: 1px solid #cccccc;
+	background: #ffffff url("../../images/jqueryui/blue/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+	color: #444444;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+	border: 1px solid #EA4F4F;
+	background: #ffffff url("../../images/jqueryui/blue/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #222222;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+	color: #222222;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+	color: #222222;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+	font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+	opacity: .7;
+	filter:Alpha(Opacity=70);
+	font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+	opacity: .35;
+	filter:Alpha(Opacity=35);
+	background-image: none;
+}
+.ui-state-disabled .ui-icon {
+	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	width: 16px;
+	height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+	background-image: url("../../images/jqueryui/blue/ui-icons_5e9cd5_256x240.png");
+}
+.ui-widget-header .ui-icon {
+	background-image: url("../../images/jqueryui/blue/ui-icons_5e9cd5_256x240.png");
+}
+.ui-state-default .ui-icon {
+	background-image: url("../../images/jqueryui/blue/ui-icons_666666_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+	background-image: url("../../images/jqueryui/blue/ui-icons_ffffff_256x240.png");
+}
+.ui-state-active .ui-icon {
+	background-image: url("../../images/jqueryui/blue/ui-icons_454545_256x240.png");
+}
+.ui-state-highlight .ui-icon {
+	background-image: url("../../images/jqueryui/blue/ui-icons_5e9cd5_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+	background-image: url("../../images/jqueryui/blue/ui-icons_EA4F4F_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -97px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+	border-top-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+	border-top-right-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+	border-bottom-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+	border-bottom-right-radius: 2px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+	background: #eeeeee url("../../images/jqueryui/blue/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
+	opacity: .8;
+	filter: Alpha(Opacity=80);
+}
+.ui-widget-shadow {
+	margin: -4px 0 0 -4px;
+	padding: 4px;
+	background: #aaaaaa url("../../images/jqueryui/blue/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
+	opacity: .6;
+	filter: Alpha(Opacity=60);
+	border-radius: 0px;
+}
diff --git a/resources/css/jqueryui/green.css b/resources/css/jqueryui/green.css
new file mode 100644
index 0000000..e3a3fff
--- /dev/null
+++ b/resources/css/jqueryui/green.css
@@ -0,0 +1,1177 @@
+/*! jQuery UI - v1.10.3 - 2013-06-08
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%238aca1b&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%238aca1b&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%238aca1b&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%238aca1b&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%238aca1b&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23ccc&fcHighlight=%23444444&iconColorHighlight=%238aca1b&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+	display: none;
+}
+.ui-helper-hidden-accessible {
+	border: 0;
+	clip: rect(0 0 0 0);
+	height: 1px;
+	margin: -1px;
+	overflow: hidden;
+	padding: 0;
+	position: absolute;
+	width: 1px;
+}
+.ui-helper-reset {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	outline: 0;
+	line-height: 1.3;
+	text-decoration: none;
+	font-size: 100%;
+	list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+	content: "";
+	display: table;
+	border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+	clear: both;
+}
+.ui-helper-clearfix {
+	min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+	width: 100%;
+	height: 100%;
+	top: 0;
+	left: 0;
+	position: absolute;
+	opacity: 0;
+	filter:Alpha(Opacity=0);
+}
+
+.ui-front {
+	z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+	cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	display: block;
+	text-indent: -99999px;
+	overflow: hidden;
+	background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+}
+.ui-resizable {
+	position: relative;
+}
+.ui-resizable-handle {
+	position: absolute;
+	font-size: 0.1px;
+	display: block;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+	display: none;
+}
+.ui-resizable-n {
+	cursor: n-resize;
+	height: 7px;
+	width: 100%;
+	top: -5px;
+	left: 0;
+}
+.ui-resizable-s {
+	cursor: s-resize;
+	height: 7px;
+	width: 100%;
+	bottom: -5px;
+	left: 0;
+}
+.ui-resizable-e {
+	cursor: e-resize;
+	width: 7px;
+	right: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-w {
+	cursor: w-resize;
+	width: 7px;
+	left: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-se {
+	cursor: se-resize;
+	width: 12px;
+	height: 12px;
+	right: 1px;
+	bottom: 1px;
+}
+.ui-resizable-sw {
+	cursor: sw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	bottom: -5px;
+}
+.ui-resizable-nw {
+	cursor: nw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	top: -5px;
+}
+.ui-resizable-ne {
+	cursor: ne-resize;
+	width: 9px;
+	height: 9px;
+	right: -5px;
+	top: -5px;
+}
+.ui-selectable-helper {
+	position: absolute;
+	z-index: 100;
+	border: 1px dotted black;
+}
+.ui-accordion .ui-accordion-header {
+	display: block;
+	cursor: pointer;
+	position: relative;
+	margin-top: 2px;
+	padding: .5em .5em .5em .7em;
+	min-height: 0; /* support: IE7 */
+}
+.ui-accordion .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-noicons {
+	padding-left: .7em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+	position: absolute;
+	left: .5em;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+	padding: 1em 2.2em;
+	border-top: 0;
+	overflow: auto;
+}
+.ui-autocomplete {
+	position: absolute;
+	top: 0;
+	left: 0;
+	cursor: default;
+}
+.ui-button {
+	display: inline-block;
+	position: relative;
+	padding: 0;
+	line-height: normal;
+	margin-right: .1em;
+	cursor: pointer;
+	vertical-align: middle;
+	text-align: center;
+	overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+	text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+	width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+	width: 2.4em;
+}
+.ui-button-icons-only {
+	width: 3.4em;
+}
+button.ui-button-icons-only {
+	width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+	display: block;
+	line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+	padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+	padding: .4em;
+	text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+	padding-left: 2.1em;
+	padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+	padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+	position: absolute;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+	left: 50%;
+	margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+	left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+	right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+	margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+	margin-left: 0;
+	margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+	border: 0;
+	padding: 0;
+}
+.ui-datepicker {
+	width: 17em;
+	padding: .2em .2em 0;
+	display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+	position: relative;
+	padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+	position: absolute;
+	top: 2px;
+	width: 1.8em;
+	height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+	top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+	left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+	right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+	left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+	right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+	display: block;
+	position: absolute;
+	left: 50%;
+	margin-left: -8px;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+	margin: 0 2.3em;
+	line-height: 1.8em;
+	text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+	font-size: 1em;
+	margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month-year {
+	width: 100%;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+	width: 49%;
+}
+.ui-datepicker table {
+	width: 100%;
+	font-size: .9em;
+	border-collapse: collapse;
+	margin: 0 0 .4em;
+}
+.ui-datepicker th {
+	padding: .7em .3em;
+	text-align: center;
+	font-weight: bold;
+	border: 0;
+}
+.ui-datepicker td {
+	border: 0;
+	padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+	display: block;
+	padding: .2em;
+	text-align: right;
+	text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+	background-image: none;
+	margin: .7em 0 0 0;
+	padding: 0 .2em;
+	border-left: 0;
+	border-right: 0;
+	border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+	float: right;
+	margin: .5em .2em .4em;
+	cursor: pointer;
+	padding: .2em .6em .3em .6em;
+	width: auto;
+	overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+	float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+	width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+	float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+	width: 95%;
+	margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+	width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+	width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+	width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+	border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+	clear: left;
+}
+.ui-datepicker-row-break {
+	clear: both;
+	width: 100%;
+	font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+	direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+	right: 2px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+	left: 2px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+	right: 1px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+	left: 1px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+	clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+	float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+	float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+	border-right-width: 0;
+	border-left-width: 1px;
+}
+.ui-dialog {
+	position: absolute;
+	top: 0;
+	left: 0;
+	padding: .2em;
+	outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+	padding: .4em 1em;
+	position: relative;
+}
+.ui-dialog .ui-dialog-title {
+	float: left;
+	margin: .1em 0;
+	white-space: nowrap;
+	width: 90%;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+	position: absolute;
+	right: .3em;
+	top: 50%;
+	width: 21px;
+	margin: -10px 0 0 0;
+	padding: 1px;
+	height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+	position: relative;
+	border: 0;
+	padding: .5em 1em;
+	background: none;
+	overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+	text-align: left;
+	border-width: 1px 0 0 0;
+	background-image: none;
+	margin-top: .5em;
+	padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+	float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+	margin: .5em .4em .5em 0;
+	cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+	width: 12px;
+	height: 12px;
+	right: -5px;
+	bottom: -5px;
+	background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+	cursor: move;
+}
+.ui-menu {
+	list-style: none;
+	padding: 2px;
+	margin: 0;
+	display: block;
+	outline: none;
+}
+.ui-menu .ui-menu {
+	margin-top: -3px;
+	position: absolute;
+}
+.ui-menu .ui-menu-item {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	/* support: IE10, see #8844 */
+	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
+}
+.ui-menu .ui-menu-divider {
+	margin: 5px -2px 5px -2px;
+	height: 0;
+	font-size: 0;
+	line-height: 0;
+	border-width: 1px 0 0 0;
+}
+.ui-menu .ui-menu-item a {
+	text-decoration: none;
+	display: block;
+	padding: 2px .4em;
+	line-height: 1.5;
+	min-height: 0; /* support: IE7 */
+	font-weight: normal;
+}
+.ui-menu .ui-menu-item a.ui-state-focus,
+.ui-menu .ui-menu-item a.ui-state-active {
+	font-weight: normal;
+	margin: -1px;
+}
+
+.ui-menu .ui-state-disabled {
+	font-weight: normal;
+	margin: .4em 0 .2em;
+	line-height: 1.5;
+}
+.ui-menu .ui-state-disabled a {
+	cursor: default;
+}
+
+/* icon support */
+.ui-menu-icons {
+	position: relative;
+}
+.ui-menu-icons .ui-menu-item a {
+	position: relative;
+	padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+	position: absolute;
+	top: .2em;
+	left: .2em;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+	position: static;
+	float: right;
+}
+.ui-progressbar {
+	height: 2em;
+	text-align: left;
+	overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+	margin: -1px;
+	height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+	background: url("../../images/jqueryui/green/animated-overlay.gif");
+	height: 100%;
+	filter: alpha(opacity=25);
+	opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+	background-image: none;
+}
+.ui-slider {
+	position: relative;
+	text-align: left;
+}
+.ui-slider .ui-slider-handle {
+	position: absolute;
+	z-index: 2;
+	width: 1.2em;
+	height: 1.2em;
+	cursor: default;
+}
+.ui-slider .ui-slider-range {
+	position: absolute;
+	z-index: 1;
+	font-size: .7em;
+	display: block;
+	border: 0;
+	background-position: 0 0;
+}
+
+/* For IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+	filter: inherit;
+}
+
+.ui-slider-horizontal {
+	height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+	top: -.3em;
+	margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+	top: 0;
+	height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+	left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+	right: 0;
+}
+
+.ui-slider-vertical {
+	width: .8em;
+	height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+	left: -.3em;
+	margin-left: 0;
+	margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+	left: 0;
+	width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+	bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+	top: 0;
+}
+.ui-spinner {
+	position: relative;
+	display: inline-block;
+	overflow: hidden;
+	padding: 0;
+	vertical-align: middle;
+}
+.ui-spinner-input {
+	border: none;
+	background: none;
+	color: inherit;
+	padding: 0;
+	margin: .2em 0;
+	vertical-align: middle;
+	margin-left: .4em;
+	margin-right: 22px;
+}
+.ui-spinner-button {
+	width: 16px;
+	height: 50%;
+	font-size: .5em;
+	padding: 0;
+	margin: 0;
+	text-align: center;
+	position: absolute;
+	cursor: default;
+	display: block;
+	overflow: hidden;
+	right: 0;
+}
+/* more specificity required here to overide default borders */
+.ui-spinner a.ui-spinner-button {
+	border-top: none;
+	border-bottom: none;
+	border-right: none;
+}
+/* vertical centre icon */
+.ui-spinner .ui-icon {
+	position: absolute;
+	margin-top: -8px;
+	top: 50%;
+	left: 0;
+}
+.ui-spinner-up {
+	top: 0;
+}
+.ui-spinner-down {
+	bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+	/* need to fix icons sprite */
+	background-position: -65px -16px;
+}
+.ui-tabs {
+	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+	padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+	margin: 0;
+	padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+	list-style: none;
+	float: left;
+	position: relative;
+	top: 0;
+	margin: 1px .2em 0 0;
+	border-bottom-width: 0;
+	padding: 0;
+	white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav li a {
+	float: left;
+	padding: .5em 1em;
+	text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+	margin-bottom: -1px;
+	padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
+	cursor: text;
+}
+.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
+	cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+	display: block;
+	border-width: 0;
+	padding: 1em 1.4em;
+	background: none;
+}
+.ui-tooltip {
+	padding: 8px;
+	position: absolute;
+	z-index: 9999;
+	max-width: 300px;
+	-webkit-box-shadow: 0 0 5px #aaa;
+	box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+	border-width: 2px;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+	font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1em;
+}
+.ui-widget-content {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/green/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-widget-content a {
+	color: #444444;
+}
+.ui-widget-header {
+	border: 1px solid #dddddd;
+	background: #dddddd url("../../images/jqueryui/green/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
+	color: #444444;
+	font-weight: bold;
+}
+.ui-widget-header a {
+	color: #444444;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+	border: 1px solid #dddddd;
+	background: #f6f6f6 url("../../images/jqueryui/green/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #444;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+	color: #444;
+	text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+	border: 1px solid #8aca1b;
+	background: #8aca1b url("../../images/jqueryui/green/ui-bg_highlight-soft_25_8aca1b_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #ffffff;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited {
+	color: #ffffff;
+	text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/green/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #8aca1b;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+	color: #8aca1b;
+	text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+	border: 1px solid #ccc;
+	background: #ffffff url("../../images/jqueryui/green/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+	color: #444444;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+	border: 1px solid #EA4F4F;
+	background: #ffffff url("../../images/jqueryui/green/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #222222;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+	color: #222222;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+	color: #222222;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+	font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+	opacity: .7;
+	filter:Alpha(Opacity=70);
+	font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+	opacity: .35;
+	filter:Alpha(Opacity=35);
+	background-image: none;
+}
+.ui-state-disabled .ui-icon {
+	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	width: 16px;
+	height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+	background-image: url("../../images/jqueryui/green/ui-icons_8aca1b_256x240.png");
+}
+.ui-widget-header .ui-icon {
+	background-image: url("../../images/jqueryui/green/ui-icons_8aca1b_256x240.png");
+}
+.ui-state-default .ui-icon {
+	background-image: url("../../images/jqueryui/green/ui-icons_666666_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+	background-image: url("../../images/jqueryui/green/ui-icons_ffffff_256x240.png");
+}
+.ui-state-active .ui-icon {
+	background-image: url("../../images/jqueryui/green/ui-icons_454545_256x240.png");
+}
+.ui-state-highlight .ui-icon {
+	background-image: url("../../images/jqueryui/green/ui-icons_8aca1b_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+	background-image: url("../../images/jqueryui/green/ui-icons_EA4F4F_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -97px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+	border-top-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+	border-top-right-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+	border-bottom-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+	border-bottom-right-radius: 2px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+	background: #eeeeee url("../../images/jqueryui/green/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
+	opacity: .8;
+	filter: Alpha(Opacity=80);
+}
+.ui-widget-shadow {
+	margin: -4px 0 0 -4px;
+	padding: 4px;
+	background: #aaaaaa url("../../images/jqueryui/green/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
+	opacity: .6;
+	filter: Alpha(Opacity=60);
+	border-radius: 0px;
+}
diff --git a/resources/css/jqueryui/orange.css b/resources/css/jqueryui/orange.css
new file mode 100644
index 0000000..9313e47
--- /dev/null
+++ b/resources/css/jqueryui/orange.css
@@ -0,0 +1,1177 @@
+/*! jQuery UI - v1.10.3 - 2013-06-08
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%23ffa600&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%23ffa600&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%23ffa600&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%23ffa600&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%23ffa600&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23ccc&fcHighlight=%23444444&iconColorHighlight=%23ffa600&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+	display: none;
+}
+.ui-helper-hidden-accessible {
+	border: 0;
+	clip: rect(0 0 0 0);
+	height: 1px;
+	margin: -1px;
+	overflow: hidden;
+	padding: 0;
+	position: absolute;
+	width: 1px;
+}
+.ui-helper-reset {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	outline: 0;
+	line-height: 1.3;
+	text-decoration: none;
+	font-size: 100%;
+	list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+	content: "";
+	display: table;
+	border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+	clear: both;
+}
+.ui-helper-clearfix {
+	min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+	width: 100%;
+	height: 100%;
+	top: 0;
+	left: 0;
+	position: absolute;
+	opacity: 0;
+	filter:Alpha(Opacity=0);
+}
+
+.ui-front {
+	z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+	cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	display: block;
+	text-indent: -99999px;
+	overflow: hidden;
+	background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+}
+.ui-resizable {
+	position: relative;
+}
+.ui-resizable-handle {
+	position: absolute;
+	font-size: 0.1px;
+	display: block;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+	display: none;
+}
+.ui-resizable-n {
+	cursor: n-resize;
+	height: 7px;
+	width: 100%;
+	top: -5px;
+	left: 0;
+}
+.ui-resizable-s {
+	cursor: s-resize;
+	height: 7px;
+	width: 100%;
+	bottom: -5px;
+	left: 0;
+}
+.ui-resizable-e {
+	cursor: e-resize;
+	width: 7px;
+	right: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-w {
+	cursor: w-resize;
+	width: 7px;
+	left: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-se {
+	cursor: se-resize;
+	width: 12px;
+	height: 12px;
+	right: 1px;
+	bottom: 1px;
+}
+.ui-resizable-sw {
+	cursor: sw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	bottom: -5px;
+}
+.ui-resizable-nw {
+	cursor: nw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	top: -5px;
+}
+.ui-resizable-ne {
+	cursor: ne-resize;
+	width: 9px;
+	height: 9px;
+	right: -5px;
+	top: -5px;
+}
+.ui-selectable-helper {
+	position: absolute;
+	z-index: 100;
+	border: 1px dotted black;
+}
+.ui-accordion .ui-accordion-header {
+	display: block;
+	cursor: pointer;
+	position: relative;
+	margin-top: 2px;
+	padding: .5em .5em .5em .7em;
+	min-height: 0; /* support: IE7 */
+}
+.ui-accordion .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-noicons {
+	padding-left: .7em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+	position: absolute;
+	left: .5em;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+	padding: 1em 2.2em;
+	border-top: 0;
+	overflow: auto;
+}
+.ui-autocomplete {
+	position: absolute;
+	top: 0;
+	left: 0;
+	cursor: default;
+}
+.ui-button {
+	display: inline-block;
+	position: relative;
+	padding: 0;
+	line-height: normal;
+	margin-right: .1em;
+	cursor: pointer;
+	vertical-align: middle;
+	text-align: center;
+	overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+	text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+	width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+	width: 2.4em;
+}
+.ui-button-icons-only {
+	width: 3.4em;
+}
+button.ui-button-icons-only {
+	width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+	display: block;
+	line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+	padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+	padding: .4em;
+	text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+	padding-left: 2.1em;
+	padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+	padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+	position: absolute;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+	left: 50%;
+	margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+	left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+	right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+	margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+	margin-left: 0;
+	margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+	border: 0;
+	padding: 0;
+}
+.ui-datepicker {
+	width: 17em;
+	padding: .2em .2em 0;
+	display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+	position: relative;
+	padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+	position: absolute;
+	top: 2px;
+	width: 1.8em;
+	height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+	top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+	left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+	right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+	left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+	right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+	display: block;
+	position: absolute;
+	left: 50%;
+	margin-left: -8px;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+	margin: 0 2.3em;
+	line-height: 1.8em;
+	text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+	font-size: 1em;
+	margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month-year {
+	width: 100%;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+	width: 49%;
+}
+.ui-datepicker table {
+	width: 100%;
+	font-size: .9em;
+	border-collapse: collapse;
+	margin: 0 0 .4em;
+}
+.ui-datepicker th {
+	padding: .7em .3em;
+	text-align: center;
+	font-weight: bold;
+	border: 0;
+}
+.ui-datepicker td {
+	border: 0;
+	padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+	display: block;
+	padding: .2em;
+	text-align: right;
+	text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+	background-image: none;
+	margin: .7em 0 0 0;
+	padding: 0 .2em;
+	border-left: 0;
+	border-right: 0;
+	border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+	float: right;
+	margin: .5em .2em .4em;
+	cursor: pointer;
+	padding: .2em .6em .3em .6em;
+	width: auto;
+	overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+	float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+	width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+	float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+	width: 95%;
+	margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+	width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+	width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+	width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+	border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+	clear: left;
+}
+.ui-datepicker-row-break {
+	clear: both;
+	width: 100%;
+	font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+	direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+	right: 2px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+	left: 2px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+	right: 1px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+	left: 1px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+	clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+	float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+	float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+	border-right-width: 0;
+	border-left-width: 1px;
+}
+.ui-dialog {
+	position: absolute;
+	top: 0;
+	left: 0;
+	padding: .2em;
+	outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+	padding: .4em 1em;
+	position: relative;
+}
+.ui-dialog .ui-dialog-title {
+	float: left;
+	margin: .1em 0;
+	white-space: nowrap;
+	width: 90%;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+	position: absolute;
+	right: .3em;
+	top: 50%;
+	width: 21px;
+	margin: -10px 0 0 0;
+	padding: 1px;
+	height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+	position: relative;
+	border: 0;
+	padding: .5em 1em;
+	background: none;
+	overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+	text-align: left;
+	border-width: 1px 0 0 0;
+	background-image: none;
+	margin-top: .5em;
+	padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+	float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+	margin: .5em .4em .5em 0;
+	cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+	width: 12px;
+	height: 12px;
+	right: -5px;
+	bottom: -5px;
+	background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+	cursor: move;
+}
+.ui-menu {
+	list-style: none;
+	padding: 2px;
+	margin: 0;
+	display: block;
+	outline: none;
+}
+.ui-menu .ui-menu {
+	margin-top: -3px;
+	position: absolute;
+}
+.ui-menu .ui-menu-item {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	/* support: IE10, see #8844 */
+	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
+}
+.ui-menu .ui-menu-divider {
+	margin: 5px -2px 5px -2px;
+	height: 0;
+	font-size: 0;
+	line-height: 0;
+	border-width: 1px 0 0 0;
+}
+.ui-menu .ui-menu-item a {
+	text-decoration: none;
+	display: block;
+	padding: 2px .4em;
+	line-height: 1.5;
+	min-height: 0; /* support: IE7 */
+	font-weight: normal;
+}
+.ui-menu .ui-menu-item a.ui-state-focus,
+.ui-menu .ui-menu-item a.ui-state-active {
+	font-weight: normal;
+	margin: -1px;
+}
+
+.ui-menu .ui-state-disabled {
+	font-weight: normal;
+	margin: .4em 0 .2em;
+	line-height: 1.5;
+}
+.ui-menu .ui-state-disabled a {
+	cursor: default;
+}
+
+/* icon support */
+.ui-menu-icons {
+	position: relative;
+}
+.ui-menu-icons .ui-menu-item a {
+	position: relative;
+	padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+	position: absolute;
+	top: .2em;
+	left: .2em;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+	position: static;
+	float: right;
+}
+.ui-progressbar {
+	height: 2em;
+	text-align: left;
+	overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+	margin: -1px;
+	height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+	background: url("../../images/jqueryui/orange/animated-overlay.gif");
+	height: 100%;
+	filter: alpha(opacity=25);
+	opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+	background-image: none;
+}
+.ui-slider {
+	position: relative;
+	text-align: left;
+}
+.ui-slider .ui-slider-handle {
+	position: absolute;
+	z-index: 2;
+	width: 1.2em;
+	height: 1.2em;
+	cursor: default;
+}
+.ui-slider .ui-slider-range {
+	position: absolute;
+	z-index: 1;
+	font-size: .7em;
+	display: block;
+	border: 0;
+	background-position: 0 0;
+}
+
+/* For IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+	filter: inherit;
+}
+
+.ui-slider-horizontal {
+	height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+	top: -.3em;
+	margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+	top: 0;
+	height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+	left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+	right: 0;
+}
+
+.ui-slider-vertical {
+	width: .8em;
+	height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+	left: -.3em;
+	margin-left: 0;
+	margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+	left: 0;
+	width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+	bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+	top: 0;
+}
+.ui-spinner {
+	position: relative;
+	display: inline-block;
+	overflow: hidden;
+	padding: 0;
+	vertical-align: middle;
+}
+.ui-spinner-input {
+	border: none;
+	background: none;
+	color: inherit;
+	padding: 0;
+	margin: .2em 0;
+	vertical-align: middle;
+	margin-left: .4em;
+	margin-right: 22px;
+}
+.ui-spinner-button {
+	width: 16px;
+	height: 50%;
+	font-size: .5em;
+	padding: 0;
+	margin: 0;
+	text-align: center;
+	position: absolute;
+	cursor: default;
+	display: block;
+	overflow: hidden;
+	right: 0;
+}
+/* more specificity required here to overide default borders */
+.ui-spinner a.ui-spinner-button {
+	border-top: none;
+	border-bottom: none;
+	border-right: none;
+}
+/* vertical centre icon */
+.ui-spinner .ui-icon {
+	position: absolute;
+	margin-top: -8px;
+	top: 50%;
+	left: 0;
+}
+.ui-spinner-up {
+	top: 0;
+}
+.ui-spinner-down {
+	bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+	/* need to fix icons sprite */
+	background-position: -65px -16px;
+}
+.ui-tabs {
+	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+	padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+	margin: 0;
+	padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+	list-style: none;
+	float: left;
+	position: relative;
+	top: 0;
+	margin: 1px .2em 0 0;
+	border-bottom-width: 0;
+	padding: 0;
+	white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav li a {
+	float: left;
+	padding: .5em 1em;
+	text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+	margin-bottom: -1px;
+	padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
+	cursor: text;
+}
+.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
+	cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+	display: block;
+	border-width: 0;
+	padding: 1em 1.4em;
+	background: none;
+}
+.ui-tooltip {
+	padding: 8px;
+	position: absolute;
+	z-index: 9999;
+	max-width: 300px;
+	-webkit-box-shadow: 0 0 5px #aaa;
+	box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+	border-width: 2px;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+	font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1em;
+}
+.ui-widget-content {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/orange/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-widget-content a {
+	color: #444444;
+}
+.ui-widget-header {
+	border: 1px solid #dddddd;
+	background: #dddddd url("../../images/jqueryui/orange/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
+	color: #444444;
+	font-weight: bold;
+}
+.ui-widget-header a {
+	color: #444444;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+	border: 1px solid #dddddd;
+	background: #f6f6f6 url("../../images/jqueryui/orange/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #444;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+	color: #444;
+	text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+	border: 1px solid #ffa600;
+	background: #ffa600 url("../../images/jqueryui/orange/ui-bg_highlight-soft_25_ffa600_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #ffffff;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited {
+	color: #ffffff;
+	text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/orange/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #ffa600;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+	color: #ffa600;
+	text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+	border: 1px solid #ccc;
+	background: #ffffff url("../../images/jqueryui/orange/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+	color: #444444;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+	border: 1px solid #EA4F4F;
+	background: #ffffff url("../../images/jqueryui/orange/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #222222;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+	color: #222222;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+	color: #222222;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+	font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+	opacity: .7;
+	filter:Alpha(Opacity=70);
+	font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+	opacity: .35;
+	filter:Alpha(Opacity=35);
+	background-image: none;
+}
+.ui-state-disabled .ui-icon {
+	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	width: 16px;
+	height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+	background-image: url("../../images/jqueryui/orange/ui-icons_ffa600_256x240.png");
+}
+.ui-widget-header .ui-icon {
+	background-image: url("../../images/jqueryui/orange/ui-icons_ffa600_256x240.png");
+}
+.ui-state-default .ui-icon {
+	background-image: url("../../images/jqueryui/orange/ui-icons_666666_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+	background-image: url("../../images/jqueryui/orange/ui-icons_ffffff_256x240.png");
+}
+.ui-state-active .ui-icon {
+	background-image: url("../../images/jqueryui/orange/ui-icons_454545_256x240.png");
+}
+.ui-state-highlight .ui-icon {
+	background-image: url("../../images/jqueryui/orange/ui-icons_ffa600_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+	background-image: url("../../images/jqueryui/orange/ui-icons_EA4F4F_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -97px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+	border-top-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+	border-top-right-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+	border-bottom-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+	border-bottom-right-radius: 2px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+	background: #eeeeee url("../../images/jqueryui/orange/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
+	opacity: .8;
+	filter: Alpha(Opacity=80);
+}
+.ui-widget-shadow {
+	margin: -4px 0 0 -4px;
+	padding: 4px;
+	background: #aaaaaa url("../../images/jqueryui/orange/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
+	opacity: .6;
+	filter: Alpha(Opacity=60);
+	border-radius: 0px;
+}
diff --git a/resources/css/jqueryui/purple.css b/resources/css/jqueryui/purple.css
new file mode 100644
index 0000000..5d9fad0
--- /dev/null
+++ b/resources/css/jqueryui/purple.css
@@ -0,0 +1,1177 @@
+/*! jQuery UI - v1.10.3 - 2013-06-08
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%23b15cd5&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%23b15cd5&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%23b15cd5&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%23b15cd5&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%23b15cd5&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23ccc&fcHighlight=%23444444&iconColorHighlight=%23b15cd5&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+	display: none;
+}
+.ui-helper-hidden-accessible {
+	border: 0;
+	clip: rect(0 0 0 0);
+	height: 1px;
+	margin: -1px;
+	overflow: hidden;
+	padding: 0;
+	position: absolute;
+	width: 1px;
+}
+.ui-helper-reset {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	outline: 0;
+	line-height: 1.3;
+	text-decoration: none;
+	font-size: 100%;
+	list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+	content: "";
+	display: table;
+	border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+	clear: both;
+}
+.ui-helper-clearfix {
+	min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+	width: 100%;
+	height: 100%;
+	top: 0;
+	left: 0;
+	position: absolute;
+	opacity: 0;
+	filter:Alpha(Opacity=0);
+}
+
+.ui-front {
+	z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+	cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	display: block;
+	text-indent: -99999px;
+	overflow: hidden;
+	background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+}
+.ui-resizable {
+	position: relative;
+}
+.ui-resizable-handle {
+	position: absolute;
+	font-size: 0.1px;
+	display: block;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+	display: none;
+}
+.ui-resizable-n {
+	cursor: n-resize;
+	height: 7px;
+	width: 100%;
+	top: -5px;
+	left: 0;
+}
+.ui-resizable-s {
+	cursor: s-resize;
+	height: 7px;
+	width: 100%;
+	bottom: -5px;
+	left: 0;
+}
+.ui-resizable-e {
+	cursor: e-resize;
+	width: 7px;
+	right: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-w {
+	cursor: w-resize;
+	width: 7px;
+	left: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-se {
+	cursor: se-resize;
+	width: 12px;
+	height: 12px;
+	right: 1px;
+	bottom: 1px;
+}
+.ui-resizable-sw {
+	cursor: sw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	bottom: -5px;
+}
+.ui-resizable-nw {
+	cursor: nw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	top: -5px;
+}
+.ui-resizable-ne {
+	cursor: ne-resize;
+	width: 9px;
+	height: 9px;
+	right: -5px;
+	top: -5px;
+}
+.ui-selectable-helper {
+	position: absolute;
+	z-index: 100;
+	border: 1px dotted black;
+}
+.ui-accordion .ui-accordion-header {
+	display: block;
+	cursor: pointer;
+	position: relative;
+	margin-top: 2px;
+	padding: .5em .5em .5em .7em;
+	min-height: 0; /* support: IE7 */
+}
+.ui-accordion .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-noicons {
+	padding-left: .7em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+	position: absolute;
+	left: .5em;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+	padding: 1em 2.2em;
+	border-top: 0;
+	overflow: auto;
+}
+.ui-autocomplete {
+	position: absolute;
+	top: 0;
+	left: 0;
+	cursor: default;
+}
+.ui-button {
+	display: inline-block;
+	position: relative;
+	padding: 0;
+	line-height: normal;
+	margin-right: .1em;
+	cursor: pointer;
+	vertical-align: middle;
+	text-align: center;
+	overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+	text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+	width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+	width: 2.4em;
+}
+.ui-button-icons-only {
+	width: 3.4em;
+}
+button.ui-button-icons-only {
+	width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+	display: block;
+	line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+	padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+	padding: .4em;
+	text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+	padding-left: 2.1em;
+	padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+	padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+	position: absolute;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+	left: 50%;
+	margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+	left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+	right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+	margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+	margin-left: 0;
+	margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+	border: 0;
+	padding: 0;
+}
+.ui-datepicker {
+	width: 17em;
+	padding: .2em .2em 0;
+	display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+	position: relative;
+	padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+	position: absolute;
+	top: 2px;
+	width: 1.8em;
+	height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+	top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+	left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+	right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+	left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+	right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+	display: block;
+	position: absolute;
+	left: 50%;
+	margin-left: -8px;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+	margin: 0 2.3em;
+	line-height: 1.8em;
+	text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+	font-size: 1em;
+	margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month-year {
+	width: 100%;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+	width: 49%;
+}
+.ui-datepicker table {
+	width: 100%;
+	font-size: .9em;
+	border-collapse: collapse;
+	margin: 0 0 .4em;
+}
+.ui-datepicker th {
+	padding: .7em .3em;
+	text-align: center;
+	font-weight: bold;
+	border: 0;
+}
+.ui-datepicker td {
+	border: 0;
+	padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+	display: block;
+	padding: .2em;
+	text-align: right;
+	text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+	background-image: none;
+	margin: .7em 0 0 0;
+	padding: 0 .2em;
+	border-left: 0;
+	border-right: 0;
+	border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+	float: right;
+	margin: .5em .2em .4em;
+	cursor: pointer;
+	padding: .2em .6em .3em .6em;
+	width: auto;
+	overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+	float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+	width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+	float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+	width: 95%;
+	margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+	width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+	width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+	width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+	border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+	clear: left;
+}
+.ui-datepicker-row-break {
+	clear: both;
+	width: 100%;
+	font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+	direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+	right: 2px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+	left: 2px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+	right: 1px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+	left: 1px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+	clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+	float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+	float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+	border-right-width: 0;
+	border-left-width: 1px;
+}
+.ui-dialog {
+	position: absolute;
+	top: 0;
+	left: 0;
+	padding: .2em;
+	outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+	padding: .4em 1em;
+	position: relative;
+}
+.ui-dialog .ui-dialog-title {
+	float: left;
+	margin: .1em 0;
+	white-space: nowrap;
+	width: 90%;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+	position: absolute;
+	right: .3em;
+	top: 50%;
+	width: 21px;
+	margin: -10px 0 0 0;
+	padding: 1px;
+	height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+	position: relative;
+	border: 0;
+	padding: .5em 1em;
+	background: none;
+	overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+	text-align: left;
+	border-width: 1px 0 0 0;
+	background-image: none;
+	margin-top: .5em;
+	padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+	float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+	margin: .5em .4em .5em 0;
+	cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+	width: 12px;
+	height: 12px;
+	right: -5px;
+	bottom: -5px;
+	background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+	cursor: move;
+}
+.ui-menu {
+	list-style: none;
+	padding: 2px;
+	margin: 0;
+	display: block;
+	outline: none;
+}
+.ui-menu .ui-menu {
+	margin-top: -3px;
+	position: absolute;
+}
+.ui-menu .ui-menu-item {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	/* support: IE10, see #8844 */
+	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
+}
+.ui-menu .ui-menu-divider {
+	margin: 5px -2px 5px -2px;
+	height: 0;
+	font-size: 0;
+	line-height: 0;
+	border-width: 1px 0 0 0;
+}
+.ui-menu .ui-menu-item a {
+	text-decoration: none;
+	display: block;
+	padding: 2px .4em;
+	line-height: 1.5;
+	min-height: 0; /* support: IE7 */
+	font-weight: normal;
+}
+.ui-menu .ui-menu-item a.ui-state-focus,
+.ui-menu .ui-menu-item a.ui-state-active {
+	font-weight: normal;
+	margin: -1px;
+}
+
+.ui-menu .ui-state-disabled {
+	font-weight: normal;
+	margin: .4em 0 .2em;
+	line-height: 1.5;
+}
+.ui-menu .ui-state-disabled a {
+	cursor: default;
+}
+
+/* icon support */
+.ui-menu-icons {
+	position: relative;
+}
+.ui-menu-icons .ui-menu-item a {
+	position: relative;
+	padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+	position: absolute;
+	top: .2em;
+	left: .2em;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+	position: static;
+	float: right;
+}
+.ui-progressbar {
+	height: 2em;
+	text-align: left;
+	overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+	margin: -1px;
+	height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+	background: url("../../images/jqueryui/purple/animated-overlay.gif");
+	height: 100%;
+	filter: alpha(opacity=25);
+	opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+	background-image: none;
+}
+.ui-slider {
+	position: relative;
+	text-align: left;
+}
+.ui-slider .ui-slider-handle {
+	position: absolute;
+	z-index: 2;
+	width: 1.2em;
+	height: 1.2em;
+	cursor: default;
+}
+.ui-slider .ui-slider-range {
+	position: absolute;
+	z-index: 1;
+	font-size: .7em;
+	display: block;
+	border: 0;
+	background-position: 0 0;
+}
+
+/* For IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+	filter: inherit;
+}
+
+.ui-slider-horizontal {
+	height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+	top: -.3em;
+	margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+	top: 0;
+	height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+	left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+	right: 0;
+}
+
+.ui-slider-vertical {
+	width: .8em;
+	height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+	left: -.3em;
+	margin-left: 0;
+	margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+	left: 0;
+	width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+	bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+	top: 0;
+}
+.ui-spinner {
+	position: relative;
+	display: inline-block;
+	overflow: hidden;
+	padding: 0;
+	vertical-align: middle;
+}
+.ui-spinner-input {
+	border: none;
+	background: none;
+	color: inherit;
+	padding: 0;
+	margin: .2em 0;
+	vertical-align: middle;
+	margin-left: .4em;
+	margin-right: 22px;
+}
+.ui-spinner-button {
+	width: 16px;
+	height: 50%;
+	font-size: .5em;
+	padding: 0;
+	margin: 0;
+	text-align: center;
+	position: absolute;
+	cursor: default;
+	display: block;
+	overflow: hidden;
+	right: 0;
+}
+/* more specificity required here to overide default borders */
+.ui-spinner a.ui-spinner-button {
+	border-top: none;
+	border-bottom: none;
+	border-right: none;
+}
+/* vertical centre icon */
+.ui-spinner .ui-icon {
+	position: absolute;
+	margin-top: -8px;
+	top: 50%;
+	left: 0;
+}
+.ui-spinner-up {
+	top: 0;
+}
+.ui-spinner-down {
+	bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+	/* need to fix icons sprite */
+	background-position: -65px -16px;
+}
+.ui-tabs {
+	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+	padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+	margin: 0;
+	padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+	list-style: none;
+	float: left;
+	position: relative;
+	top: 0;
+	margin: 1px .2em 0 0;
+	border-bottom-width: 0;
+	padding: 0;
+	white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav li a {
+	float: left;
+	padding: .5em 1em;
+	text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+	margin-bottom: -1px;
+	padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
+	cursor: text;
+}
+.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
+	cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+	display: block;
+	border-width: 0;
+	padding: 1em 1.4em;
+	background: none;
+}
+.ui-tooltip {
+	padding: 8px;
+	position: absolute;
+	z-index: 9999;
+	max-width: 300px;
+	-webkit-box-shadow: 0 0 5px #aaa;
+	box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+	border-width: 2px;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+	font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1em;
+}
+.ui-widget-content {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/purple/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-widget-content a {
+	color: #444444;
+}
+.ui-widget-header {
+	border: 1px solid #dddddd;
+	background: #dddddd url("../../images/jqueryui/purple/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
+	color: #444444;
+	font-weight: bold;
+}
+.ui-widget-header a {
+	color: #444444;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+	border: 1px solid #dddddd;
+	background: #f6f6f6 url("../../images/jqueryui/purple/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #444;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+	color: #444;
+	text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+	border: 1px solid #b15cd5;
+	background: #b15cd5 url("../../images/jqueryui/purple/ui-bg_highlight-soft_25_b15cd5_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #ffffff;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited {
+	color: #ffffff;
+	text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/purple/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #b15cd5;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+	color: #b15cd5;
+	text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+	border: 1px solid #ccc;
+	background: #ffffff url("../../images/jqueryui/purple/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+	color: #444444;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+	border: 1px solid #EA4F4F;
+	background: #ffffff url("../../images/jqueryui/purple/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #222222;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+	color: #222222;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+	color: #222222;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+	font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+	opacity: .7;
+	filter:Alpha(Opacity=70);
+	font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+	opacity: .35;
+	filter:Alpha(Opacity=35);
+	background-image: none;
+}
+.ui-state-disabled .ui-icon {
+	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	width: 16px;
+	height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+	background-image: url("../../images/jqueryui/purple/ui-icons_b15cd5_256x240.png");
+}
+.ui-widget-header .ui-icon {
+	background-image: url("../../images/jqueryui/purple/ui-icons_b15cd5_256x240.png");
+}
+.ui-state-default .ui-icon {
+	background-image: url("../../images/jqueryui/purple/ui-icons_666666_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+	background-image: url("../../images/jqueryui/purple/ui-icons_ffffff_256x240.png");
+}
+.ui-state-active .ui-icon {
+	background-image: url("../../images/jqueryui/purple/ui-icons_454545_256x240.png");
+}
+.ui-state-highlight .ui-icon {
+	background-image: url("../../images/jqueryui/purple/ui-icons_b15cd5_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+	background-image: url("../../images/jqueryui/purple/ui-icons_EA4F4F_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -97px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+	border-top-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+	border-top-right-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+	border-bottom-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+	border-bottom-right-radius: 2px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+	background: #eeeeee url("../../images/jqueryui/purple/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
+	opacity: .8;
+	filter: Alpha(Opacity=80);
+}
+.ui-widget-shadow {
+	margin: -4px 0 0 -4px;
+	padding: 4px;
+	background: #aaaaaa url("../../images/jqueryui/purple/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
+	opacity: .6;
+	filter: Alpha(Opacity=60);
+	border-radius: 0px;
+}
diff --git a/resources/css/jqueryui/red.css b/resources/css/jqueryui/red.css
new file mode 100644
index 0000000..3d523b6
--- /dev/null
+++ b/resources/css/jqueryui/red.css
@@ -0,0 +1,1177 @@
+/*! jQuery UI - v1.10.3 - 2013-06-08
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%23EA4F4F&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%23EA4F4F&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%23EA4F4F&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%23EA4F4F&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%23EA4F4F&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23cccccc&fcHighlight=%23444444&iconColorHighlight=%23EA4F4F&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+	display: none;
+}
+.ui-helper-hidden-accessible {
+	border: 0;
+	clip: rect(0 0 0 0);
+	height: 1px;
+	margin: -1px;
+	overflow: hidden;
+	padding: 0;
+	position: absolute;
+	width: 1px;
+}
+.ui-helper-reset {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	outline: 0;
+	line-height: 1.3;
+	text-decoration: none;
+	font-size: 100%;
+	list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+	content: "";
+	display: table;
+	border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+	clear: both;
+}
+.ui-helper-clearfix {
+	min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+	width: 100%;
+	height: 100%;
+	top: 0;
+	left: 0;
+	position: absolute;
+	opacity: 0;
+	filter:Alpha(Opacity=0);
+}
+
+.ui-front {
+	z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+	cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	display: block;
+	text-indent: -99999px;
+	overflow: hidden;
+	background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+}
+.ui-resizable {
+	position: relative;
+}
+.ui-resizable-handle {
+	position: absolute;
+	font-size: 0.1px;
+	display: block;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+	display: none;
+}
+.ui-resizable-n {
+	cursor: n-resize;
+	height: 7px;
+	width: 100%;
+	top: -5px;
+	left: 0;
+}
+.ui-resizable-s {
+	cursor: s-resize;
+	height: 7px;
+	width: 100%;
+	bottom: -5px;
+	left: 0;
+}
+.ui-resizable-e {
+	cursor: e-resize;
+	width: 7px;
+	right: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-w {
+	cursor: w-resize;
+	width: 7px;
+	left: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-se {
+	cursor: se-resize;
+	width: 12px;
+	height: 12px;
+	right: 1px;
+	bottom: 1px;
+}
+.ui-resizable-sw {
+	cursor: sw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	bottom: -5px;
+}
+.ui-resizable-nw {
+	cursor: nw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	top: -5px;
+}
+.ui-resizable-ne {
+	cursor: ne-resize;
+	width: 9px;
+	height: 9px;
+	right: -5px;
+	top: -5px;
+}
+.ui-selectable-helper {
+	position: absolute;
+	z-index: 100;
+	border: 1px dotted black;
+}
+.ui-accordion .ui-accordion-header {
+	display: block;
+	cursor: pointer;
+	position: relative;
+	margin-top: 2px;
+	padding: .5em .5em .5em .7em;
+	min-height: 0; /* support: IE7 */
+}
+.ui-accordion .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-noicons {
+	padding-left: .7em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+	position: absolute;
+	left: .5em;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+	padding: 1em 2.2em;
+	border-top: 0;
+	overflow: auto;
+}
+.ui-autocomplete {
+	position: absolute;
+	top: 0;
+	left: 0;
+	cursor: default;
+}
+.ui-button {
+	display: inline-block;
+	position: relative;
+	padding: 0;
+	line-height: normal;
+	margin-right: .1em;
+	cursor: pointer;
+	vertical-align: middle;
+	text-align: center;
+	overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+	text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+	width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+	width: 2.4em;
+}
+.ui-button-icons-only {
+	width: 3.4em;
+}
+button.ui-button-icons-only {
+	width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+	display: block;
+	line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+	padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+	padding: .4em;
+	text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+	padding-left: 2.1em;
+	padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+	padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+	position: absolute;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+	left: 50%;
+	margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+	left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+	right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+	margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+	margin-left: 0;
+	margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+	border: 0;
+	padding: 0;
+}
+.ui-datepicker {
+	width: 17em;
+	padding: .2em .2em 0;
+	display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+	position: relative;
+	padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+	position: absolute;
+	top: 2px;
+	width: 1.8em;
+	height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+	top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+	left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+	right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+	left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+	right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+	display: block;
+	position: absolute;
+	left: 50%;
+	margin-left: -8px;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+	margin: 0 2.3em;
+	line-height: 1.8em;
+	text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+	font-size: 1em;
+	margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month-year {
+	width: 100%;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+	width: 49%;
+}
+.ui-datepicker table {
+	width: 100%;
+	font-size: .9em;
+	border-collapse: collapse;
+	margin: 0 0 .4em;
+}
+.ui-datepicker th {
+	padding: .7em .3em;
+	text-align: center;
+	font-weight: bold;
+	border: 0;
+}
+.ui-datepicker td {
+	border: 0;
+	padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+	display: block;
+	padding: .2em;
+	text-align: right;
+	text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+	background-image: none;
+	margin: .7em 0 0 0;
+	padding: 0 .2em;
+	border-left: 0;
+	border-right: 0;
+	border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+	float: right;
+	margin: .5em .2em .4em;
+	cursor: pointer;
+	padding: .2em .6em .3em .6em;
+	width: auto;
+	overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+	float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+	width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+	float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+	width: 95%;
+	margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+	width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+	width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+	width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+	border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+	clear: left;
+}
+.ui-datepicker-row-break {
+	clear: both;
+	width: 100%;
+	font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+	direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+	right: 2px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+	left: 2px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+	right: 1px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+	left: 1px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+	clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+	float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+	float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+	border-right-width: 0;
+	border-left-width: 1px;
+}
+.ui-dialog {
+	position: absolute;
+	top: 0;
+	left: 0;
+	padding: .2em;
+	outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+	padding: .4em 1em;
+	position: relative;
+}
+.ui-dialog .ui-dialog-title {
+	float: left;
+	margin: .1em 0;
+	white-space: nowrap;
+	width: 90%;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+	position: absolute;
+	right: .3em;
+	top: 50%;
+	width: 21px;
+	margin: -10px 0 0 0;
+	padding: 1px;
+	height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+	position: relative;
+	border: 0;
+	padding: .5em 1em;
+	background: none;
+	overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+	text-align: left;
+	border-width: 1px 0 0 0;
+	background-image: none;
+	margin-top: .5em;
+	padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+	float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+	margin: .5em .4em .5em 0;
+	cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+	width: 12px;
+	height: 12px;
+	right: -5px;
+	bottom: -5px;
+	background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+	cursor: move;
+}
+.ui-menu {
+	list-style: none;
+	padding: 2px;
+	margin: 0;
+	display: block;
+	outline: none;
+}
+.ui-menu .ui-menu {
+	margin-top: -3px;
+	position: absolute;
+}
+.ui-menu .ui-menu-item {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	/* support: IE10, see #8844 */
+	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
+}
+.ui-menu .ui-menu-divider {
+	margin: 5px -2px 5px -2px;
+	height: 0;
+	font-size: 0;
+	line-height: 0;
+	border-width: 1px 0 0 0;
+}
+.ui-menu .ui-menu-item a {
+	text-decoration: none;
+	display: block;
+	padding: 2px .4em;
+	line-height: 1.5;
+	min-height: 0; /* support: IE7 */
+	font-weight: normal;
+}
+.ui-menu .ui-menu-item a.ui-state-focus,
+.ui-menu .ui-menu-item a.ui-state-active {
+	font-weight: normal;
+	margin: -1px;
+}
+
+.ui-menu .ui-state-disabled {
+	font-weight: normal;
+	margin: .4em 0 .2em;
+	line-height: 1.5;
+}
+.ui-menu .ui-state-disabled a {
+	cursor: default;
+}
+
+/* icon support */
+.ui-menu-icons {
+	position: relative;
+}
+.ui-menu-icons .ui-menu-item a {
+	position: relative;
+	padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+	position: absolute;
+	top: .2em;
+	left: .2em;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+	position: static;
+	float: right;
+}
+.ui-progressbar {
+	height: 2em;
+	text-align: left;
+	overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+	margin: -1px;
+	height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+	background: url("../../images/jqueryui/red/animated-overlay.gif");
+	height: 100%;
+	filter: alpha(opacity=25);
+	opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+	background-image: none;
+}
+.ui-slider {
+	position: relative;
+	text-align: left;
+}
+.ui-slider .ui-slider-handle {
+	position: absolute;
+	z-index: 2;
+	width: 1.2em;
+	height: 1.2em;
+	cursor: default;
+}
+.ui-slider .ui-slider-range {
+	position: absolute;
+	z-index: 1;
+	font-size: .7em;
+	display: block;
+	border: 0;
+	background-position: 0 0;
+}
+
+/* For IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+	filter: inherit;
+}
+
+.ui-slider-horizontal {
+	height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+	top: -.3em;
+	margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+	top: 0;
+	height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+	left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+	right: 0;
+}
+
+.ui-slider-vertical {
+	width: .8em;
+	height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+	left: -.3em;
+	margin-left: 0;
+	margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+	left: 0;
+	width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+	bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+	top: 0;
+}
+.ui-spinner {
+	position: relative;
+	display: inline-block;
+	overflow: hidden;
+	padding: 0;
+	vertical-align: middle;
+}
+.ui-spinner-input {
+	border: none;
+	background: none;
+	color: inherit;
+	padding: 0;
+	margin: .2em 0;
+	vertical-align: middle;
+	margin-left: .4em;
+	margin-right: 22px;
+}
+.ui-spinner-button {
+	width: 16px;
+	height: 50%;
+	font-size: .5em;
+	padding: 0;
+	margin: 0;
+	text-align: center;
+	position: absolute;
+	cursor: default;
+	display: block;
+	overflow: hidden;
+	right: 0;
+}
+/* more specificity required here to overide default borders */
+.ui-spinner a.ui-spinner-button {
+	border-top: none;
+	border-bottom: none;
+	border-right: none;
+}
+/* vertical centre icon */
+.ui-spinner .ui-icon {
+	position: absolute;
+	margin-top: -8px;
+	top: 50%;
+	left: 0;
+}
+.ui-spinner-up {
+	top: 0;
+}
+.ui-spinner-down {
+	bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+	/* need to fix icons sprite */
+	background-position: -65px -16px;
+}
+.ui-tabs {
+	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+	padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+	margin: 0;
+	padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+	list-style: none;
+	float: left;
+	position: relative;
+	top: 0;
+	margin: 1px .2em 0 0;
+	border-bottom-width: 0;
+	padding: 0;
+	white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav li a {
+	float: left;
+	padding: .5em 1em;
+	text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+	margin-bottom: -1px;
+	padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
+	cursor: text;
+}
+.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
+	cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+	display: block;
+	border-width: 0;
+	padding: 1em 1.4em;
+	background: none;
+}
+.ui-tooltip {
+	padding: 8px;
+	position: absolute;
+	z-index: 9999;
+	max-width: 300px;
+	-webkit-box-shadow: 0 0 5px #aaa;
+	box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+	border-width: 2px;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+	font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+	font-family: Helvetica,Arial,sans-serif;
+	font-size: 1em;
+}
+.ui-widget-content {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/red/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-widget-content a {
+	color: #444444;
+}
+.ui-widget-header {
+	border: 1px solid #dddddd;
+	background: #dddddd url("../../images/jqueryui/red/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
+	color: #444444;
+	font-weight: bold;
+}
+.ui-widget-header a {
+	color: #444444;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+	border: 1px solid #dddddd;
+	background: #f6f6f6 url("../../images/jqueryui/red/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #444;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+	color: #444;
+	text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+	border: 1px solid #EA4F4F;
+	background: #EA4F4F url("../../images/jqueryui/red/ui-bg_highlight-soft_25_EA4F4F_1x100.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #ffffff;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited {
+	color: #ffffff;
+	text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+	border: 1px solid #dddddd;
+	background: #ffffff url("../../images/jqueryui/red/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
+	font-weight: bold;
+	color: #EA4F4F;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+	color: #EA4F4F;
+	text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+	border: 1px solid #cccccc;
+	background: #ffffff url("../../images/jqueryui/red/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #444444;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+	color: #444444;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+	border: 1px solid #EA4F4F;
+	background: #ffffff url("../../images/jqueryui/red/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
+	color: #222222;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+	color: #222222;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+	color: #222222;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+	font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+	opacity: .7;
+	filter:Alpha(Opacity=70);
+	font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+	opacity: .35;
+	filter:Alpha(Opacity=35);
+	background-image: none;
+}
+.ui-state-disabled .ui-icon {
+	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	width: 16px;
+	height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+	background-image: url("../../images/jqueryui/red/ui-icons_EA4F4F_256x240.png");
+}
+.ui-widget-header .ui-icon {
+	background-image: url("../../images/jqueryui/red/ui-icons_EA4F4F_256x240.png");
+}
+.ui-state-default .ui-icon {
+	background-image: url("../../images/jqueryui/red/ui-icons_666666_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+	background-image: url("../../images/jqueryui/red/ui-icons_ffffff_256x240.png");
+}
+.ui-state-active .ui-icon {
+	background-image: url("../../images/jqueryui/red/ui-icons_454545_256x240.png");
+}
+.ui-state-highlight .ui-icon {
+	background-image: url("../../images/jqueryui/red/ui-icons_EA4F4F_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+	background-image: url("../../images/jqueryui/red/ui-icons_EA4F4F_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -97px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+	border-top-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+	border-top-right-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+	border-bottom-left-radius: 2px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+	border-bottom-right-radius: 2px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+	background: #eeeeee url("../../images/jqueryui/red/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
+	opacity: .8;
+	filter: Alpha(Opacity=80);
+}
+.ui-widget-shadow {
+	margin: -4px 0 0 -4px;
+	padding: 4px;
+	background: #aaaaaa url("../../images/jqueryui/red/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
+	opacity: .6;
+	filter: Alpha(Opacity=60);
+	border-radius: 0px;
+}
diff --git a/resources/css/mobile.css b/resources/css/mobile.css
new file mode 100644
index 0000000..82292d6
--- /dev/null
+++ b/resources/css/mobile.css
@@ -0,0 +1,198 @@
+#page-inner {
+	position: relative;
+	padding-bottom: 170px;
+	overflow: hidden;
+}
+#header-inner,
+#nav-inner,
+#connection-inner,
+#content-inner,
+#footer-inner {
+	width: 99%;
+}
+footer,
+#theme,
+#lang,
+#newfolder,
+.menu-principal ul li.accesslink,
+.section-chat #chatColor,
+.section-chat #chatDestination,
+.section-chat #chatSend,
+.options-radio-inline li .icon,
+.connection-label label {
+	display: none;
+}
+#content {
+	margin-top: 50px;
+}
+#as_server,
+#as_password,
+#as_adminlevel {
+	clear: both;
+	float: left;
+	margin: 5px 0;
+	padding: 5px 10px;
+	width: 100%;
+}
+#as_password {
+	width: 97.5%;
+}
+#connection-inner,
+.menu-principal {
+	height: 100%;
+}
+#connection-inner .connection-label,
+#connection-inner .connection-login {
+	width: 99%;
+}
+#as_login {
+	width: 100%;
+}
+
+.speed-admin {
+	position: absolute;
+	left: 0;
+	top: 84px;
+	width: 60%;
+}
+.speed-admin ul {
+	width: 100%;
+	height: 27px;
+	background: #555;
+}
+.speed-admin ul li {
+	display: block;
+	float: left;
+}
+.speed-admin ul li + li {
+	margin-left: 2px;
+}
+.speed-admin ul li a {
+	padding: 5px 22px 0;
+	background-position: 20px 5px;
+}
+.speed-admin ul li a:hover,
+.speed-admin ul li a.locked {
+	background-position: 20px 5px;
+}
+.speed-admin ul li + li a {
+	margin: 0;
+}
+.switch-server {
+	top: 84px;
+	right: 0;
+	width: 40%;
+}
+.switch-server #switchServerList {
+	padding: 7px 10px 8px;
+	width: 100%;
+	border: 0;
+	-webkit-border-radius: 0 0 5px 5px;
+	-moz-border-radius: 0 0 5px 5px;
+	-ms-border-radius: 0 0 5px 5px;
+	-o-border-radius: 0 0 5px 5px;
+	border-radius: 0 0 5px 5px;
+}
+
+.horizontal-nav {
+	position: absolute;
+	bottom: 0;
+	padding-bottom: 5px;
+	width: 100%;
+}
+.menu-principal {
+	height: 140px;
+	border-width: 1px;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	-ms-border-radius: 5px;
+	-o-border-radius: 5px;
+	border-radius: 5px;
+}
+.menu-principal ul {
+	width: 102%;
+}
+.menu-principal .menu-right {
+	clear: both;
+	float: left;
+	padding-left: 5px;
+}
+.menu-principal ul li {
+	margin-bottom: 4px;
+	width: 48.5%;
+}
+.menu-principal ul li.accessgeneral {
+	width: 99%;
+}
+.menu-principal .menu-right li {
+	width: 32%;
+}
+.menu-principal ul li a {
+	height: 25px;
+	line-height: 25px;
+	font-size: 1.05em;
+	-webkit-border-radius: 0;
+	-moz-border-radius: 0;
+	-ms-border-radius: 0;
+	-o-border-radius: 0;
+	border-radius: 0;
+}
+.section-index .cadre.left,
+.section-guestban .cadre.left,
+.hasMenu.hasFolders .cadre.left.menu {
+	margin-bottom: 10px;
+	width: 97.5%;
+}
+.section-index .cadre.right,
+.section-guestban .cadre.right {
+	clear: both;
+	float: left;
+	margin: -10px 0 0;
+	padding-top: 20px;
+	padding-left: 10px;
+	width: 97.5%;
+}
+.section-index .title-detail,
+.section-guestban .title-detail {
+	top: 24px;
+}
+#playerlist {
+	min-height: 150px;
+}
+.section-chat #chatNickname {
+	width: 18%;
+}
+.section-chat #chatSend {
+	width: 20%;
+}
+.section-chat #chatMessage {
+	margin: 0;
+	width: 68%;
+}
+
+.hasMenu .cadre.right,
+.hasMenu.hasFolders .cadre.right {
+	width: 71%;
+}
+.cadre.left.menu {
+	margin-bottom: 0;
+}
+.cadre.middle.folders {
+	clear: left;
+	width: 15.5%;
+}
+.options-radio-inline li {
+	width: 22%;
+}
+.options-radio-inline li .name {
+	width: 100%;
+}
+.section-maps-order .options-radio-inline li {
+	width: 14%;
+}
+.section-maps-order .save {
+	margin-top: 10px;
+}
+.path {
+	width: 200px;
+}
\ No newline at end of file
diff --git a/resources/css/theme.php b/resources/css/theme.php
new file mode 100644
index 0000000..64bc9bc
--- /dev/null
+++ b/resources/css/theme.php
@@ -0,0 +1 @@
+<?php	// Includes	session_start();	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';	require_once $configPath.'adminserv.cfg.php';	require_once $configPath.'extension.cfg.php';		// Thème	$themeColor = (isset($_GET['th'])) ? addslashes($_GET['th']) : AdminServConfig::DEFAULT_THEME;?><?php if($themeColor != null): ?>	<?php		$color1 = ExtensionConfig::$THEMES[$themeColor][0];		$color2 = ExtensionConfig::$THEMES[$themeColor][1];				// CSS		header('Content-type: text/css');	?>/* Color */#title .title-color,h2,h3 {	color: <?php echo $color1; ?>;}/* Background color */#header-color-line,h1,.menu .vertical-nav ul li a.active,.menu .vertical-nav ul li a:hover,.qq-upload-button-hover,.qq-upload-drop-area-active,.qq-progress-bar {	background-color: <?php echo $color1; ?>;}tbody tr.selected,.options-radio-inline li:hover,.options-radio-inline li.selected,.ui-sortable li:hover {	background-color: <?php echo $color2; ?>;}/* Others */.button.light,.button.dark {	-webkit-box-shadow: 0 4px 0 <?php echo $color1; ?>;	-moz-box-shadow: 0 4px 0 <?php echo $color1; ?>;	-ms-box-shadow: 0 4px 0 <?php echo $color1; ?>;	-o-box-shadow: 0 4px 0 <?php echo $color1; ?>;	box-shadow: 0 4px 0 <?php echo $color1; ?>;}fieldset legend {	-webkit-box-shadow: 0 3px <?php echo $color1; ?>;	-moz-box-shadow: 0 3px <?php echo $color1; ?>;	-ms-box-shadow: 0 3px <?php echo $color1; ?>;	-o-box-shadow: 0 3px <?php echo $color1; ?>;	box-shadow: 0 3px <?php echo $color1; ?>;}.menu .vertical-nav ul li a {	border-bottom-color: <?php echo $color2; ?>;}.options-checkbox {	border-left-color: <?php echo $color1; ?>;}.folders .option-folder-list .arrow-down {	border-color: <?php echo $color1; ?> transparent transparent;}.folders .option-folder-list .arrow-up {	border-color: transparent transparent <?php echo $color1; ?>;}.content p a {	border-color: <?php echo $color1; ?>;}<?php endif; ?>
\ No newline at end of file
diff --git a/resources/images/16/back.png b/resources/images/16/back.png
new file mode 100644
index 0000000..0160e9d
Binary files /dev/null and b/resources/images/16/back.png differ
diff --git a/resources/images/16/blue_arrow_up.png b/resources/images/16/blue_arrow_up.png
new file mode 100644
index 0000000..4a0a5a9
Binary files /dev/null and b/resources/images/16/blue_arrow_up.png differ
diff --git a/resources/images/16/bt_arrow_fastnext.png b/resources/images/16/bt_arrow_fastnext.png
new file mode 100644
index 0000000..7a0a08d
Binary files /dev/null and b/resources/images/16/bt_arrow_fastnext.png differ
diff --git a/resources/images/16/bt_arrow_fastprev.png b/resources/images/16/bt_arrow_fastprev.png
new file mode 100644
index 0000000..be7354a
Binary files /dev/null and b/resources/images/16/bt_arrow_fastprev.png differ
diff --git a/resources/images/16/bt_arrow_last.png b/resources/images/16/bt_arrow_last.png
new file mode 100644
index 0000000..eb56808
Binary files /dev/null and b/resources/images/16/bt_arrow_last.png differ
diff --git a/resources/images/16/bt_refresh.png b/resources/images/16/bt_refresh.png
new file mode 100644
index 0000000..2620955
Binary files /dev/null and b/resources/images/16/bt_refresh.png differ
diff --git a/resources/images/16/delete.png b/resources/images/16/delete.png
new file mode 100644
index 0000000..97b7ca4
Binary files /dev/null and b/resources/images/16/delete.png differ
diff --git a/resources/images/16/edit.png b/resources/images/16/edit.png
new file mode 100644
index 0000000..6ed8d25
Binary files /dev/null and b/resources/images/16/edit.png differ
diff --git a/resources/images/16/finishgrey.png b/resources/images/16/finishgrey.png
new file mode 100644
index 0000000..8360984
Binary files /dev/null and b/resources/images/16/finishgrey.png differ
diff --git a/resources/images/16/leagueladder.png b/resources/images/16/leagueladder.png
new file mode 100644
index 0000000..99de3ac
Binary files /dev/null and b/resources/images/16/leagueladder.png differ
diff --git a/resources/images/16/loadmap.png b/resources/images/16/loadmap.png
new file mode 100644
index 0000000..e6e705e
Binary files /dev/null and b/resources/images/16/loadmap.png differ
diff --git a/resources/images/16/map.png b/resources/images/16/map.png
new file mode 100644
index 0000000..959389a
Binary files /dev/null and b/resources/images/16/map.png differ
diff --git a/resources/images/16/mapauthor.png b/resources/images/16/mapauthor.png
new file mode 100644
index 0000000..967a553
Binary files /dev/null and b/resources/images/16/mapauthor.png differ
diff --git a/resources/images/16/options.png b/resources/images/16/options.png
new file mode 100644
index 0000000..d14b46a
Binary files /dev/null and b/resources/images/16/options.png differ
diff --git a/resources/images/16/players.png b/resources/images/16/players.png
new file mode 100644
index 0000000..ac0365a
Binary files /dev/null and b/resources/images/16/players.png differ
diff --git a/resources/images/16/restartrace.png b/resources/images/16/restartrace.png
new file mode 100644
index 0000000..e3f9762
Binary files /dev/null and b/resources/images/16/restartrace.png differ
diff --git a/resources/images/16/rt_cup.png b/resources/images/16/rt_cup.png
new file mode 100644
index 0000000..75c107c
Binary files /dev/null and b/resources/images/16/rt_cup.png differ
diff --git a/resources/images/16/rt_laps.png b/resources/images/16/rt_laps.png
new file mode 100644
index 0000000..69327dc
Binary files /dev/null and b/resources/images/16/rt_laps.png differ
diff --git a/resources/images/16/rt_rounds.png b/resources/images/16/rt_rounds.png
new file mode 100644
index 0000000..98d8793
Binary files /dev/null and b/resources/images/16/rt_rounds.png differ
diff --git a/resources/images/16/rt_stunts.png b/resources/images/16/rt_stunts.png
new file mode 100644
index 0000000..b0ecd8a
Binary files /dev/null and b/resources/images/16/rt_stunts.png differ
diff --git a/resources/images/16/rt_team.png b/resources/images/16/rt_team.png
new file mode 100644
index 0000000..eda2d60
Binary files /dev/null and b/resources/images/16/rt_team.png differ
diff --git a/resources/images/16/rt_timeattack.png b/resources/images/16/rt_timeattack.png
new file mode 100644
index 0000000..e7353f1
Binary files /dev/null and b/resources/images/16/rt_timeattack.png differ
diff --git a/resources/images/16/servers.png b/resources/images/16/servers.png
new file mode 100644
index 0000000..aeabb2d
Binary files /dev/null and b/resources/images/16/servers.png differ
diff --git a/resources/images/16/solo.png b/resources/images/16/solo.png
new file mode 100644
index 0000000..0281f85
Binary files /dev/null and b/resources/images/16/solo.png differ
diff --git a/resources/images/32/blue_arrow_down.png b/resources/images/32/blue_arrow_down.png
new file mode 100644
index 0000000..7486dbf
Binary files /dev/null and b/resources/images/32/blue_arrow_down.png differ
diff --git a/resources/images/32/favicon.png b/resources/images/32/favicon.png
new file mode 100644
index 0000000..5778d22
Binary files /dev/null and b/resources/images/32/favicon.png differ
diff --git a/resources/images/colorpicker/picker.png b/resources/images/colorpicker/picker.png
new file mode 100644
index 0000000..f678b55
Binary files /dev/null and b/resources/images/colorpicker/picker.png differ
diff --git a/resources/images/colorpicker/slider.png b/resources/images/colorpicker/slider.png
new file mode 100644
index 0000000..9abe9ab
Binary files /dev/null and b/resources/images/colorpicker/slider.png differ
diff --git a/resources/images/env/bay.png b/resources/images/env/bay.png
new file mode 100644
index 0000000..137f824
Binary files /dev/null and b/resources/images/env/bay.png differ
diff --git a/resources/images/env/canyon.png b/resources/images/env/canyon.png
new file mode 100644
index 0000000..7fe43e6
Binary files /dev/null and b/resources/images/env/canyon.png differ
diff --git a/resources/images/env/coast.png b/resources/images/env/coast.png
new file mode 100644
index 0000000..4d456eb
Binary files /dev/null and b/resources/images/env/coast.png differ
diff --git a/resources/images/env/desert.png b/resources/images/env/desert.png
new file mode 100644
index 0000000..88bdc9f
Binary files /dev/null and b/resources/images/env/desert.png differ
diff --git a/resources/images/env/island.png b/resources/images/env/island.png
new file mode 100644
index 0000000..d141a78
Binary files /dev/null and b/resources/images/env/island.png differ
diff --git a/resources/images/env/rally.png b/resources/images/env/rally.png
new file mode 100644
index 0000000..2b0d9f5
Binary files /dev/null and b/resources/images/env/rally.png differ
diff --git a/resources/images/env/snow.png b/resources/images/env/snow.png
new file mode 100644
index 0000000..e59cef7
Binary files /dev/null and b/resources/images/env/snow.png differ
diff --git a/resources/images/env/stadium.png b/resources/images/env/stadium.png
new file mode 100644
index 0000000..c2625d5
Binary files /dev/null and b/resources/images/env/stadium.png differ
diff --git a/resources/images/env/storm.png b/resources/images/env/storm.png
new file mode 100644
index 0000000..a4b7b63
Binary files /dev/null and b/resources/images/env/storm.png differ
diff --git a/resources/images/env/valley.png b/resources/images/env/valley.png
new file mode 100644
index 0000000..bcd9f1f
Binary files /dev/null and b/resources/images/env/valley.png differ
diff --git a/resources/images/jqueryui/black/animated-overlay.gif b/resources/images/jqueryui/black/animated-overlay.gif
new file mode 100644
index 0000000..d441f75
Binary files /dev/null and b/resources/images/jqueryui/black/animated-overlay.gif differ
diff --git a/resources/images/jqueryui/black/ui-bg_flat_0_aaaaaa_40x100.png b/resources/images/jqueryui/black/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 0000000..0165536
Binary files /dev/null and b/resources/images/jqueryui/black/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/resources/images/jqueryui/black/ui-bg_flat_0_eeeeee_40x100.png b/resources/images/jqueryui/black/ui-bg_flat_0_eeeeee_40x100.png
new file mode 100644
index 0000000..ccf1bb8
Binary files /dev/null and b/resources/images/jqueryui/black/ui-bg_flat_0_eeeeee_40x100.png differ
diff --git a/resources/images/jqueryui/black/ui-bg_flat_55_ffffff_40x100.png b/resources/images/jqueryui/black/ui-bg_flat_55_ffffff_40x100.png
new file mode 100644
index 0000000..18cfcd6
Binary files /dev/null and b/resources/images/jqueryui/black/ui-bg_flat_55_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/black/ui-bg_flat_75_ffffff_40x100.png b/resources/images/jqueryui/black/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 0000000..3a5db85
Binary files /dev/null and b/resources/images/jqueryui/black/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/black/ui-bg_glass_65_ffffff_1x400.png b/resources/images/jqueryui/black/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 0000000..48782e8
Binary files /dev/null and b/resources/images/jqueryui/black/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/resources/images/jqueryui/black/ui-bg_highlight-soft_100_f6f6f6_1x100.png b/resources/images/jqueryui/black/ui-bg_highlight-soft_100_f6f6f6_1x100.png
new file mode 100644
index 0000000..3388cc2
Binary files /dev/null and b/resources/images/jqueryui/black/ui-bg_highlight-soft_100_f6f6f6_1x100.png differ
diff --git a/resources/images/jqueryui/black/ui-bg_highlight-soft_25_727272_1x100.png b/resources/images/jqueryui/black/ui-bg_highlight-soft_25_727272_1x100.png
new file mode 100644
index 0000000..1b95450
Binary files /dev/null and b/resources/images/jqueryui/black/ui-bg_highlight-soft_25_727272_1x100.png differ
diff --git a/resources/images/jqueryui/black/ui-bg_highlight-soft_50_dddddd_1x100.png b/resources/images/jqueryui/black/ui-bg_highlight-soft_50_dddddd_1x100.png
new file mode 100644
index 0000000..95551e2
Binary files /dev/null and b/resources/images/jqueryui/black/ui-bg_highlight-soft_50_dddddd_1x100.png differ
diff --git a/resources/images/jqueryui/black/ui-icons_454545_256x240.png b/resources/images/jqueryui/black/ui-icons_454545_256x240.png
new file mode 100644
index 0000000..b6db1ac
Binary files /dev/null and b/resources/images/jqueryui/black/ui-icons_454545_256x240.png differ
diff --git a/resources/images/jqueryui/black/ui-icons_666666_256x240.png b/resources/images/jqueryui/black/ui-icons_666666_256x240.png
new file mode 100644
index 0000000..76cecfc
Binary files /dev/null and b/resources/images/jqueryui/black/ui-icons_666666_256x240.png differ
diff --git a/resources/images/jqueryui/black/ui-icons_727272_256x240.png b/resources/images/jqueryui/black/ui-icons_727272_256x240.png
new file mode 100644
index 0000000..5a71da4
Binary files /dev/null and b/resources/images/jqueryui/black/ui-icons_727272_256x240.png differ
diff --git a/resources/images/jqueryui/black/ui-icons_EA4F4F_256x240.png b/resources/images/jqueryui/black/ui-icons_EA4F4F_256x240.png
new file mode 100644
index 0000000..7ff0bfb
Binary files /dev/null and b/resources/images/jqueryui/black/ui-icons_EA4F4F_256x240.png differ
diff --git a/resources/images/jqueryui/black/ui-icons_ffffff_256x240.png b/resources/images/jqueryui/black/ui-icons_ffffff_256x240.png
new file mode 100644
index 0000000..4f624bb
Binary files /dev/null and b/resources/images/jqueryui/black/ui-icons_ffffff_256x240.png differ
diff --git a/resources/images/jqueryui/blue/animated-overlay.gif b/resources/images/jqueryui/blue/animated-overlay.gif
new file mode 100644
index 0000000..d441f75
Binary files /dev/null and b/resources/images/jqueryui/blue/animated-overlay.gif differ
diff --git a/resources/images/jqueryui/blue/ui-bg_flat_0_aaaaaa_40x100.png b/resources/images/jqueryui/blue/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 0000000..0165536
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/resources/images/jqueryui/blue/ui-bg_flat_0_eeeeee_40x100.png b/resources/images/jqueryui/blue/ui-bg_flat_0_eeeeee_40x100.png
new file mode 100644
index 0000000..ccf1bb8
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-bg_flat_0_eeeeee_40x100.png differ
diff --git a/resources/images/jqueryui/blue/ui-bg_flat_55_ffffff_40x100.png b/resources/images/jqueryui/blue/ui-bg_flat_55_ffffff_40x100.png
new file mode 100644
index 0000000..18cfcd6
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-bg_flat_55_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/blue/ui-bg_flat_75_ffffff_40x100.png b/resources/images/jqueryui/blue/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 0000000..3a5db85
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/blue/ui-bg_glass_65_ffffff_1x400.png b/resources/images/jqueryui/blue/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 0000000..48782e8
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/resources/images/jqueryui/blue/ui-bg_highlight-soft_100_f6f6f6_1x100.png b/resources/images/jqueryui/blue/ui-bg_highlight-soft_100_f6f6f6_1x100.png
new file mode 100644
index 0000000..3388cc2
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-bg_highlight-soft_100_f6f6f6_1x100.png differ
diff --git a/resources/images/jqueryui/blue/ui-bg_highlight-soft_25_5e9cd5_1x100.png b/resources/images/jqueryui/blue/ui-bg_highlight-soft_25_5e9cd5_1x100.png
new file mode 100644
index 0000000..d880da4
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-bg_highlight-soft_25_5e9cd5_1x100.png differ
diff --git a/resources/images/jqueryui/blue/ui-bg_highlight-soft_50_dddddd_1x100.png b/resources/images/jqueryui/blue/ui-bg_highlight-soft_50_dddddd_1x100.png
new file mode 100644
index 0000000..95551e2
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-bg_highlight-soft_50_dddddd_1x100.png differ
diff --git a/resources/images/jqueryui/blue/ui-icons_454545_256x240.png b/resources/images/jqueryui/blue/ui-icons_454545_256x240.png
new file mode 100644
index 0000000..b6db1ac
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-icons_454545_256x240.png differ
diff --git a/resources/images/jqueryui/blue/ui-icons_5e9cd5_256x240.png b/resources/images/jqueryui/blue/ui-icons_5e9cd5_256x240.png
new file mode 100644
index 0000000..e06e173
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-icons_5e9cd5_256x240.png differ
diff --git a/resources/images/jqueryui/blue/ui-icons_666666_256x240.png b/resources/images/jqueryui/blue/ui-icons_666666_256x240.png
new file mode 100644
index 0000000..76cecfc
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-icons_666666_256x240.png differ
diff --git a/resources/images/jqueryui/blue/ui-icons_EA4F4F_256x240.png b/resources/images/jqueryui/blue/ui-icons_EA4F4F_256x240.png
new file mode 100644
index 0000000..7ff0bfb
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-icons_EA4F4F_256x240.png differ
diff --git a/resources/images/jqueryui/blue/ui-icons_ffffff_256x240.png b/resources/images/jqueryui/blue/ui-icons_ffffff_256x240.png
new file mode 100644
index 0000000..4f624bb
Binary files /dev/null and b/resources/images/jqueryui/blue/ui-icons_ffffff_256x240.png differ
diff --git a/resources/images/jqueryui/green/animated-overlay.gif b/resources/images/jqueryui/green/animated-overlay.gif
new file mode 100644
index 0000000..d441f75
Binary files /dev/null and b/resources/images/jqueryui/green/animated-overlay.gif differ
diff --git a/resources/images/jqueryui/green/ui-bg_flat_0_aaaaaa_40x100.png b/resources/images/jqueryui/green/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 0000000..0165536
Binary files /dev/null and b/resources/images/jqueryui/green/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/resources/images/jqueryui/green/ui-bg_flat_0_eeeeee_40x100.png b/resources/images/jqueryui/green/ui-bg_flat_0_eeeeee_40x100.png
new file mode 100644
index 0000000..ccf1bb8
Binary files /dev/null and b/resources/images/jqueryui/green/ui-bg_flat_0_eeeeee_40x100.png differ
diff --git a/resources/images/jqueryui/green/ui-bg_flat_55_ffffff_40x100.png b/resources/images/jqueryui/green/ui-bg_flat_55_ffffff_40x100.png
new file mode 100644
index 0000000..18cfcd6
Binary files /dev/null and b/resources/images/jqueryui/green/ui-bg_flat_55_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/green/ui-bg_flat_75_ffffff_40x100.png b/resources/images/jqueryui/green/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 0000000..3a5db85
Binary files /dev/null and b/resources/images/jqueryui/green/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/green/ui-bg_glass_65_ffffff_1x400.png b/resources/images/jqueryui/green/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 0000000..48782e8
Binary files /dev/null and b/resources/images/jqueryui/green/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/resources/images/jqueryui/green/ui-bg_highlight-soft_100_f6f6f6_1x100.png b/resources/images/jqueryui/green/ui-bg_highlight-soft_100_f6f6f6_1x100.png
new file mode 100644
index 0000000..3388cc2
Binary files /dev/null and b/resources/images/jqueryui/green/ui-bg_highlight-soft_100_f6f6f6_1x100.png differ
diff --git a/resources/images/jqueryui/green/ui-bg_highlight-soft_25_8aca1b_1x100.png b/resources/images/jqueryui/green/ui-bg_highlight-soft_25_8aca1b_1x100.png
new file mode 100644
index 0000000..e2044bf
Binary files /dev/null and b/resources/images/jqueryui/green/ui-bg_highlight-soft_25_8aca1b_1x100.png differ
diff --git a/resources/images/jqueryui/green/ui-bg_highlight-soft_50_dddddd_1x100.png b/resources/images/jqueryui/green/ui-bg_highlight-soft_50_dddddd_1x100.png
new file mode 100644
index 0000000..95551e2
Binary files /dev/null and b/resources/images/jqueryui/green/ui-bg_highlight-soft_50_dddddd_1x100.png differ
diff --git a/resources/images/jqueryui/green/ui-icons_454545_256x240.png b/resources/images/jqueryui/green/ui-icons_454545_256x240.png
new file mode 100644
index 0000000..b6db1ac
Binary files /dev/null and b/resources/images/jqueryui/green/ui-icons_454545_256x240.png differ
diff --git a/resources/images/jqueryui/green/ui-icons_666666_256x240.png b/resources/images/jqueryui/green/ui-icons_666666_256x240.png
new file mode 100644
index 0000000..76cecfc
Binary files /dev/null and b/resources/images/jqueryui/green/ui-icons_666666_256x240.png differ
diff --git a/resources/images/jqueryui/green/ui-icons_8aca1b_256x240.png b/resources/images/jqueryui/green/ui-icons_8aca1b_256x240.png
new file mode 100644
index 0000000..d7cd16b
Binary files /dev/null and b/resources/images/jqueryui/green/ui-icons_8aca1b_256x240.png differ
diff --git a/resources/images/jqueryui/green/ui-icons_EA4F4F_256x240.png b/resources/images/jqueryui/green/ui-icons_EA4F4F_256x240.png
new file mode 100644
index 0000000..7ff0bfb
Binary files /dev/null and b/resources/images/jqueryui/green/ui-icons_EA4F4F_256x240.png differ
diff --git a/resources/images/jqueryui/green/ui-icons_ffffff_256x240.png b/resources/images/jqueryui/green/ui-icons_ffffff_256x240.png
new file mode 100644
index 0000000..4f624bb
Binary files /dev/null and b/resources/images/jqueryui/green/ui-icons_ffffff_256x240.png differ
diff --git a/resources/images/jqueryui/orange/animated-overlay.gif b/resources/images/jqueryui/orange/animated-overlay.gif
new file mode 100644
index 0000000..d441f75
Binary files /dev/null and b/resources/images/jqueryui/orange/animated-overlay.gif differ
diff --git a/resources/images/jqueryui/orange/ui-bg_flat_0_aaaaaa_40x100.png b/resources/images/jqueryui/orange/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 0000000..0165536
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/resources/images/jqueryui/orange/ui-bg_flat_0_eeeeee_40x100.png b/resources/images/jqueryui/orange/ui-bg_flat_0_eeeeee_40x100.png
new file mode 100644
index 0000000..ccf1bb8
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-bg_flat_0_eeeeee_40x100.png differ
diff --git a/resources/images/jqueryui/orange/ui-bg_flat_55_ffffff_40x100.png b/resources/images/jqueryui/orange/ui-bg_flat_55_ffffff_40x100.png
new file mode 100644
index 0000000..18cfcd6
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-bg_flat_55_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/orange/ui-bg_flat_75_ffffff_40x100.png b/resources/images/jqueryui/orange/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 0000000..3a5db85
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/orange/ui-bg_glass_65_ffffff_1x400.png b/resources/images/jqueryui/orange/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 0000000..48782e8
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/resources/images/jqueryui/orange/ui-bg_highlight-soft_100_f6f6f6_1x100.png b/resources/images/jqueryui/orange/ui-bg_highlight-soft_100_f6f6f6_1x100.png
new file mode 100644
index 0000000..3388cc2
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-bg_highlight-soft_100_f6f6f6_1x100.png differ
diff --git a/resources/images/jqueryui/orange/ui-bg_highlight-soft_25_ffa600_1x100.png b/resources/images/jqueryui/orange/ui-bg_highlight-soft_25_ffa600_1x100.png
new file mode 100644
index 0000000..55dc025
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-bg_highlight-soft_25_ffa600_1x100.png differ
diff --git a/resources/images/jqueryui/orange/ui-bg_highlight-soft_50_dddddd_1x100.png b/resources/images/jqueryui/orange/ui-bg_highlight-soft_50_dddddd_1x100.png
new file mode 100644
index 0000000..95551e2
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-bg_highlight-soft_50_dddddd_1x100.png differ
diff --git a/resources/images/jqueryui/orange/ui-icons_454545_256x240.png b/resources/images/jqueryui/orange/ui-icons_454545_256x240.png
new file mode 100644
index 0000000..b6db1ac
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-icons_454545_256x240.png differ
diff --git a/resources/images/jqueryui/orange/ui-icons_666666_256x240.png b/resources/images/jqueryui/orange/ui-icons_666666_256x240.png
new file mode 100644
index 0000000..76cecfc
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-icons_666666_256x240.png differ
diff --git a/resources/images/jqueryui/orange/ui-icons_EA4F4F_256x240.png b/resources/images/jqueryui/orange/ui-icons_EA4F4F_256x240.png
new file mode 100644
index 0000000..7ff0bfb
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-icons_EA4F4F_256x240.png differ
diff --git a/resources/images/jqueryui/orange/ui-icons_ffa600_256x240.png b/resources/images/jqueryui/orange/ui-icons_ffa600_256x240.png
new file mode 100644
index 0000000..21306a0
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-icons_ffa600_256x240.png differ
diff --git a/resources/images/jqueryui/orange/ui-icons_ffffff_256x240.png b/resources/images/jqueryui/orange/ui-icons_ffffff_256x240.png
new file mode 100644
index 0000000..4f624bb
Binary files /dev/null and b/resources/images/jqueryui/orange/ui-icons_ffffff_256x240.png differ
diff --git a/resources/images/jqueryui/purple/animated-overlay.gif b/resources/images/jqueryui/purple/animated-overlay.gif
new file mode 100644
index 0000000..d441f75
Binary files /dev/null and b/resources/images/jqueryui/purple/animated-overlay.gif differ
diff --git a/resources/images/jqueryui/purple/ui-bg_flat_0_aaaaaa_40x100.png b/resources/images/jqueryui/purple/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 0000000..0165536
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/resources/images/jqueryui/purple/ui-bg_flat_0_eeeeee_40x100.png b/resources/images/jqueryui/purple/ui-bg_flat_0_eeeeee_40x100.png
new file mode 100644
index 0000000..ccf1bb8
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-bg_flat_0_eeeeee_40x100.png differ
diff --git a/resources/images/jqueryui/purple/ui-bg_flat_55_ffffff_40x100.png b/resources/images/jqueryui/purple/ui-bg_flat_55_ffffff_40x100.png
new file mode 100644
index 0000000..18cfcd6
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-bg_flat_55_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/purple/ui-bg_flat_75_ffffff_40x100.png b/resources/images/jqueryui/purple/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 0000000..3a5db85
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/purple/ui-bg_glass_65_ffffff_1x400.png b/resources/images/jqueryui/purple/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 0000000..48782e8
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/resources/images/jqueryui/purple/ui-bg_highlight-soft_100_f6f6f6_1x100.png b/resources/images/jqueryui/purple/ui-bg_highlight-soft_100_f6f6f6_1x100.png
new file mode 100644
index 0000000..3388cc2
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-bg_highlight-soft_100_f6f6f6_1x100.png differ
diff --git a/resources/images/jqueryui/purple/ui-bg_highlight-soft_25_b15cd5_1x100.png b/resources/images/jqueryui/purple/ui-bg_highlight-soft_25_b15cd5_1x100.png
new file mode 100644
index 0000000..e8492ab
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-bg_highlight-soft_25_b15cd5_1x100.png differ
diff --git a/resources/images/jqueryui/purple/ui-bg_highlight-soft_50_dddddd_1x100.png b/resources/images/jqueryui/purple/ui-bg_highlight-soft_50_dddddd_1x100.png
new file mode 100644
index 0000000..95551e2
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-bg_highlight-soft_50_dddddd_1x100.png differ
diff --git a/resources/images/jqueryui/purple/ui-icons_454545_256x240.png b/resources/images/jqueryui/purple/ui-icons_454545_256x240.png
new file mode 100644
index 0000000..b6db1ac
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-icons_454545_256x240.png differ
diff --git a/resources/images/jqueryui/purple/ui-icons_666666_256x240.png b/resources/images/jqueryui/purple/ui-icons_666666_256x240.png
new file mode 100644
index 0000000..76cecfc
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-icons_666666_256x240.png differ
diff --git a/resources/images/jqueryui/purple/ui-icons_EA4F4F_256x240.png b/resources/images/jqueryui/purple/ui-icons_EA4F4F_256x240.png
new file mode 100644
index 0000000..7ff0bfb
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-icons_EA4F4F_256x240.png differ
diff --git a/resources/images/jqueryui/purple/ui-icons_b15cd5_256x240.png b/resources/images/jqueryui/purple/ui-icons_b15cd5_256x240.png
new file mode 100644
index 0000000..0004dcd
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-icons_b15cd5_256x240.png differ
diff --git a/resources/images/jqueryui/purple/ui-icons_ffffff_256x240.png b/resources/images/jqueryui/purple/ui-icons_ffffff_256x240.png
new file mode 100644
index 0000000..4f624bb
Binary files /dev/null and b/resources/images/jqueryui/purple/ui-icons_ffffff_256x240.png differ
diff --git a/resources/images/jqueryui/red/animated-overlay.gif b/resources/images/jqueryui/red/animated-overlay.gif
new file mode 100644
index 0000000..d441f75
Binary files /dev/null and b/resources/images/jqueryui/red/animated-overlay.gif differ
diff --git a/resources/images/jqueryui/red/ui-bg_flat_0_aaaaaa_40x100.png b/resources/images/jqueryui/red/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 0000000..0165536
Binary files /dev/null and b/resources/images/jqueryui/red/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/resources/images/jqueryui/red/ui-bg_flat_0_eeeeee_40x100.png b/resources/images/jqueryui/red/ui-bg_flat_0_eeeeee_40x100.png
new file mode 100644
index 0000000..ccf1bb8
Binary files /dev/null and b/resources/images/jqueryui/red/ui-bg_flat_0_eeeeee_40x100.png differ
diff --git a/resources/images/jqueryui/red/ui-bg_flat_55_ffffff_40x100.png b/resources/images/jqueryui/red/ui-bg_flat_55_ffffff_40x100.png
new file mode 100644
index 0000000..18cfcd6
Binary files /dev/null and b/resources/images/jqueryui/red/ui-bg_flat_55_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/red/ui-bg_flat_75_ffffff_40x100.png b/resources/images/jqueryui/red/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 0000000..3a5db85
Binary files /dev/null and b/resources/images/jqueryui/red/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/resources/images/jqueryui/red/ui-bg_glass_65_ffffff_1x400.png b/resources/images/jqueryui/red/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 0000000..48782e8
Binary files /dev/null and b/resources/images/jqueryui/red/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/resources/images/jqueryui/red/ui-bg_highlight-soft_100_f6f6f6_1x100.png b/resources/images/jqueryui/red/ui-bg_highlight-soft_100_f6f6f6_1x100.png
new file mode 100644
index 0000000..3388cc2
Binary files /dev/null and b/resources/images/jqueryui/red/ui-bg_highlight-soft_100_f6f6f6_1x100.png differ
diff --git a/resources/images/jqueryui/red/ui-bg_highlight-soft_25_EA4F4F_1x100.png b/resources/images/jqueryui/red/ui-bg_highlight-soft_25_EA4F4F_1x100.png
new file mode 100644
index 0000000..1cccc3c
Binary files /dev/null and b/resources/images/jqueryui/red/ui-bg_highlight-soft_25_EA4F4F_1x100.png differ
diff --git a/resources/images/jqueryui/red/ui-bg_highlight-soft_50_dddddd_1x100.png b/resources/images/jqueryui/red/ui-bg_highlight-soft_50_dddddd_1x100.png
new file mode 100644
index 0000000..95551e2
Binary files /dev/null and b/resources/images/jqueryui/red/ui-bg_highlight-soft_50_dddddd_1x100.png differ
diff --git a/resources/images/jqueryui/red/ui-icons_454545_256x240.png b/resources/images/jqueryui/red/ui-icons_454545_256x240.png
new file mode 100644
index 0000000..b6db1ac
Binary files /dev/null and b/resources/images/jqueryui/red/ui-icons_454545_256x240.png differ
diff --git a/resources/images/jqueryui/red/ui-icons_666666_256x240.png b/resources/images/jqueryui/red/ui-icons_666666_256x240.png
new file mode 100644
index 0000000..76cecfc
Binary files /dev/null and b/resources/images/jqueryui/red/ui-icons_666666_256x240.png differ
diff --git a/resources/images/jqueryui/red/ui-icons_EA4F4F_256x240.png b/resources/images/jqueryui/red/ui-icons_EA4F4F_256x240.png
new file mode 100644
index 0000000..7ff0bfb
Binary files /dev/null and b/resources/images/jqueryui/red/ui-icons_EA4F4F_256x240.png differ
diff --git a/resources/images/jqueryui/red/ui-icons_ffffff_256x240.png b/resources/images/jqueryui/red/ui-icons_ffffff_256x240.png
new file mode 100644
index 0000000..4f624bb
Binary files /dev/null and b/resources/images/jqueryui/red/ui-icons_ffffff_256x240.png differ
diff --git a/resources/images/lang/br.png b/resources/images/lang/br.png
new file mode 100644
index 0000000..cc6c197
Binary files /dev/null and b/resources/images/lang/br.png differ
diff --git a/resources/images/lang/de.png b/resources/images/lang/de.png
new file mode 100644
index 0000000..b965925
Binary files /dev/null and b/resources/images/lang/de.png differ
diff --git a/resources/images/lang/dk.png b/resources/images/lang/dk.png
new file mode 100644
index 0000000..a04f1b8
Binary files /dev/null and b/resources/images/lang/dk.png differ
diff --git a/resources/images/lang/en.png b/resources/images/lang/en.png
new file mode 100644
index 0000000..5787cc9
Binary files /dev/null and b/resources/images/lang/en.png differ
diff --git a/resources/images/lang/es.png b/resources/images/lang/es.png
new file mode 100644
index 0000000..639ed10
Binary files /dev/null and b/resources/images/lang/es.png differ
diff --git a/resources/images/lang/fi.png b/resources/images/lang/fi.png
new file mode 100644
index 0000000..f1d8875
Binary files /dev/null and b/resources/images/lang/fi.png differ
diff --git a/resources/images/lang/fr.png b/resources/images/lang/fr.png
new file mode 100644
index 0000000..e4bac8e
Binary files /dev/null and b/resources/images/lang/fr.png differ
diff --git a/resources/images/lang/hu.png b/resources/images/lang/hu.png
new file mode 100644
index 0000000..da408dc
Binary files /dev/null and b/resources/images/lang/hu.png differ
diff --git a/resources/images/lang/it.png b/resources/images/lang/it.png
new file mode 100644
index 0000000..bb81545
Binary files /dev/null and b/resources/images/lang/it.png differ
diff --git a/resources/images/lang/nl.png b/resources/images/lang/nl.png
new file mode 100644
index 0000000..e3c160a
Binary files /dev/null and b/resources/images/lang/nl.png differ
diff --git a/resources/images/lang/no.png b/resources/images/lang/no.png
new file mode 100644
index 0000000..3950afa
Binary files /dev/null and b/resources/images/lang/no.png differ
diff --git a/resources/images/lang/pl.png b/resources/images/lang/pl.png
new file mode 100644
index 0000000..ae12532
Binary files /dev/null and b/resources/images/lang/pl.png differ
diff --git a/resources/images/lang/pt.png b/resources/images/lang/pt.png
new file mode 100644
index 0000000..a36ba17
Binary files /dev/null and b/resources/images/lang/pt.png differ
diff --git a/resources/images/lang/ro.png b/resources/images/lang/ro.png
new file mode 100644
index 0000000..c740e42
Binary files /dev/null and b/resources/images/lang/ro.png differ
diff --git a/resources/images/lang/ru.png b/resources/images/lang/ru.png
new file mode 100644
index 0000000..b9d4bc4
Binary files /dev/null and b/resources/images/lang/ru.png differ
diff --git a/resources/images/lang/tr.png b/resources/images/lang/tr.png
new file mode 100644
index 0000000..fe6bbdb
Binary files /dev/null and b/resources/images/lang/tr.png differ
diff --git a/resources/images/logo.png b/resources/images/logo.png
new file mode 100644
index 0000000..b449ee3
Binary files /dev/null and b/resources/images/logo.png differ
diff --git a/resources/js/adminserv_event.js b/resources/js/adminserv_event.js
new file mode 100644
index 0000000..738d9db
--- /dev/null
+++ b/resources/js/adminserv_event.js
@@ -0,0 +1,1063 @@
+$(document).ready(function(){
+	
+	/**
+	* Global
+	*/
+	$('#theme, #lang').hover(function(){
+		$(this).css('height', $(this).find('ul').height()+'px');
+	}, function(){
+		$(this).css('height', $(this).find('ul li:first-child').height()+'px');
+	});
+	$('#footer-inner a').click(function(event){
+		event.preventDefault();
+		window.open( $(this).attr('href') );
+	});
+	
+	
+	/**
+	* Config
+	*/
+	if( $('body').hasClass('config') ){
+		/**
+		* Serveurs
+		*/
+		if( $('body').hasClass('section-config-servers') ){
+			// Clic sur les lignes
+			$('#serverList').on('click', 'tr', function(){
+				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
+					// Si la ligne est déjà sélectionnée, on l'enlève
+					if( $(this).hasClass('selected') ){
+						$('#serverList tr').removeClass('selected');
+						$(this).find('td.checkbox input').prop('checked', false);
+					}
+					// Sinon, on l'ajoute
+					else{
+						$('#serverList tr').removeClass('selected');
+						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
+					}
+				}
+				
+				// Mise à jour du nb de lignes sélectionnées
+				$('.cadre').updateNbSelectedLines();
+			});
+			// Supprimer un serveur
+			$('#deleteserver').click(function(){
+				if( !confirm( $(this).data('confirm-text') ) ){
+					return false;
+				}
+			});
+		}
+		else if( $('body').hasClass('section-config-addserver') ){
+			$('#addServerAdmLvlSA, #addServerAdmLvlADM, #addServerAdmLvlUSR').blur(function(){
+				if( $(this).val() == '' ){
+					$(this).val('all');
+				}
+			});
+		}
+		else if( $('body').hasClass('section-config-serversorder') ){
+			// Tri manuel
+			$('#sortableServersList').sortable({
+				placeholder: 'ui-state-highlight',
+				revert: true,
+				zIndex: 9999
+			}).disableSelection();
+			$('#reset').click(function(){
+				location.href = $('.section-config-serversorder .cadre form').attr('action');
+			});
+			$('#save').click(function(){
+				var listStr = '';
+				var list = $('#sortableServersList li .order-server-name');
+				if( list.length > 0 ){
+					$.each(list, function(i, n){
+						listStr += n.textContent+',';
+					});
+					$('#list').val(listStr.substring(0, listStr.length-1));
+				}
+			});
+		}
+		else if( $('body').hasClass('section-config-adminlevel') ){
+			// Clic sur les lignes
+			$('#levelList').on('click', 'tr', function(){
+				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
+					// Si la ligne est déjà sélectionnée, on l'enlève
+					if( $(this).hasClass('selected') ){
+						$('#levelList tr').removeClass('selected');
+						$(this).find('td.checkbox input').prop('checked', false);
+					}
+					// Sinon, on l'ajoute
+					else{
+						$('#levelList tr').removeClass('selected');
+						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
+					}
+				}
+				
+				// Mise à jour du nb de lignes sélectionnées
+				$('.cadre').updateNbSelectedLines();
+			});
+			// Supprimer un niveau admin
+			$('#deletelevel').click(function(){
+				if( !confirm( $(this).data('confirm-text') ) ){
+					return false;
+				}
+			});
+		}
+		else if( $('body').hasClass('section-config-addlevel') ){
+			// Access
+			$('#defaultAccess, #selectedAccess').sortable({
+				connectWith: '.adminlevelAccessList',
+				revert: true
+			}).disableSelection();
+			// Permission
+			$('#defaultPermission, #selectedPermission').sortable({
+				connectWith: '.adminlevelPermissionList',
+				revert: true
+			}).disableSelection();
+			
+			// Submit
+			$('#savelevel').click(function(){
+				var lists = {
+					access: {
+						list: '#selectedAccess li',
+						target: '#selectedAccessSortList'
+					},
+					permission: {
+						list: '#selectedPermission li',
+						target: '#selectedPermissionSortList'
+					}
+				};
+				$.each(lists, function(i, n){
+					var out = '';
+					var selector = $(n.list);
+					if(selector.length > 0){
+						selector.each(function(){
+							out += $(this).text()+',';
+						});
+						$(n.target).val(out.substring(0, out.length-1));
+					}
+				});
+			});
+		}
+		else if( $('body').hasClass('section-config-levelsorder') ){
+			// Tri manuel
+			$('#sortableLevelsList').sortable({
+				placeholder: 'ui-state-highlight',
+				revert: true,
+				zIndex: 9999
+			}).disableSelection();
+			$('#reset').click(function(){
+				location.href = $('.section-config-levelsorder .cadre form').attr('action');
+			});
+			$('#save').click(function(){
+				var listStr = '';
+				var list = $('#sortableLevelsList li .order-server-name');
+				if( list.length > 0 ){
+					$.each(list, function(i, n){
+						listStr += n.textContent+',';
+					});
+					$('#list').val(listStr.substring(0, listStr.length-1));
+				}
+			});
+		}
+	}
+	/**
+	* Front
+	*/
+	else if( $('body').hasClass('front') ){
+		// Adminlevel
+		getServerAdminLevel();
+		$('#as_server').change(function(){
+			getServerAdminLevel();
+			if( $('#error').css('display') == 'block' ){
+				$('#error').attr('hidden', true).fadeOut('fast');
+			}
+		});
+		$('#as_adminlevel').click(function(){
+			if( $(this).html() == '' ){
+				getServerAdminLevel();
+			}
+		});
+		
+		// Connexion
+		$(document).keypress(function(event){
+			if(event.keyCode == 13){
+				$('#connection form').submit();
+			}
+		});
+	}
+	/**
+	* Not front
+	*/
+	else{
+		/**
+		* Nouveau dossier
+		*/
+		$('#newfolder').click(function(event){
+			event.preventDefault();
+			if( $('#form-new-folder').prop('hidden') ){
+				slideDownNewFolderForm();
+			}
+			else{
+				slideUpNewFolderForm();
+			}
+		});
+		$('#newFolderName').keypress(function(event){
+			if(event.keyCode == 13){
+				if( $(this).val() != '' ){
+					$('#createFolderForm').submit();
+				}
+				else{
+					slideUpNewFolderForm();
+				}
+			}
+		});
+		$('#newFolderValid').click(function(){
+			if( $('#newFolderName').val() != '' ){
+				return true;
+			}
+			else{
+				slideUpNewFolderForm();
+				return false;
+			}
+		});
+		
+		
+		/**
+		* Option du dossier
+		*/
+		$('.path').scrollLeft(1000);
+		$('.folders .option-folder-list h3').click(function(){
+			var selector = $(this).parent().find('ul');
+			if( selector.attr('hidden') ){
+				selector.slideDown('fast').removeAttr('hidden');
+				$(this).find('span').removeClass('arrow-down').addClass('arrow-up');
+			}
+			else{
+				selector.slideUp('fast').attr('hidden', true);
+				$(this).find('span').removeClass('arrow-up').addClass('arrow-down');
+			}
+		});
+		$('#renameFolder').click(function(event){
+			event.preventDefault();
+			$('#optionFolderHiddenFieldAction').val('rename');
+			getRenameFolderForm();
+		});
+		$('#moveFolder').click(function(event){
+			event.preventDefault();
+			$('#optionFolderHiddenFieldAction').val('move');
+			getMoveFolderForm();
+		});
+		$('#deleteFolder').click(function(event){
+			event.preventDefault();
+			if( confirm( $(this).data('confirm-text') ) ){
+				$('#optionFolderHiddenFieldAction').val('delete');
+				$('#optionFolderForm').submit();
+			}
+		});
+		
+		
+		/**
+		* SpeedAdmin
+		*/
+		$('.speed-admin a').click(function(event){
+			event.preventDefault();
+			if( !$(this).hasClass('locked') ){
+				$(this).addClass('locked');
+				speedAdmin( $(this).text() );
+			}
+		});
+		
+		
+		/**
+		* SwitchServer
+		*/
+		$('#switchServerList').change(function(){
+			var page = getUrlParams('p');
+			var option = $(this).find('option:selected').val();
+			if(page){
+				location.href = '?p='+page+'&switch='+option;
+			}
+			else{
+				location.href = '?switch='+option;
+			}
+		});
+		
+		
+		/**
+		* Scroll doux
+		*/
+		$('a[href^="#"]').click(function(event){
+			event.preventDefault();
+			var target = $(this).attr('href');
+			$('html, body').animate({  
+				scrollTop: $(target).offset().top - 100
+			}, 'slow');
+		});
+		
+		
+		/**
+		* Général
+		*/
+		if( $('body').hasClass('section-index') ){
+			// Infos serveur
+			setInterval(function(){
+				getCurrentServerInfo(getMode(), getCurrentSort() );
+			}, 10000);
+			
+			// Checkbox
+			$('#checkAll').click(function(){
+				$('#playerlist').checkAll( $(this).attr('checked') );
+				
+				// Mise à jour du nb de lignes sélectionnées
+				$('.cadre.right').updateNbSelectedLines();
+			});
+			
+			// Clic sur les lignes
+			$('#playerlist').on('click', 'tr', function(){
+				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
+					// Si la ligne est déjà sélectionnée, on l'enlève
+					if( $(this).hasClass('selected') ){
+						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
+					}
+					// Sinon, on l'ajoute
+					else{
+						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
+					}
+					
+					// Mise à jour du nb de lignes sélectionnées
+					$('.cadre.right').updateNbSelectedLines();
+					$('.cadre.right').updateCheckAll( $('#checkAll') );
+				}
+			});
+			
+			// Mode détail
+			$('#detailMode').click(function(event){
+				event.preventDefault();
+				$('#playerlist').setDetailMode();
+			});
+			
+			// Tris
+			$('#playerlist table th a').click(function(event){
+				event.preventDefault();
+				$('#playerlist').addClass('loading');
+				getCurrentServerInfo(getMode(), $(this).attr('href').split('=')[1]);
+			});
+		}
+		/**
+		* Server Options
+		*/
+		else if( $('body').hasClass('section-srvopts') ){
+			// ServerName
+			$('#ServerName').keyup(function(event){
+				var key = event.keyCode;
+				if(key != 13 && key != 37 && key != 39){
+					$('#serverNameHtml').getColorHtml( $(this).val() );
+				}
+			});
+			$('#ServerName').blur(function(){
+				$('#serverNameHtml').getColorHtml( $(this).val() );
+			});
+			
+			// ServerComment
+			$('#ServerComment').keyup(function(event){
+				var key = event.keyCode;
+				if(key != 37 && key != 39){
+					$('#serverCommentHtml').getColorHtml('$i'+ $(this).val() );
+				}
+			});
+			
+			// VoteRato
+			$('#callVoteRatioDisabled').change(function(){
+				if( $(this).val() == '0' ){
+					$(this).hide();
+					$('#CallVoteRatio')
+						.fadeIn('fast').removeAttr('hidden')
+						.parent('td').find('.returnDefaultValue').fadeIn('fast').removeAttr('hidden');
+					if( $('#CallVoteRatio').val() == -1 ){
+						$('#CallVoteRatio').val('0.5');
+					}
+				}
+			});
+			// Désactiver le ratio vote
+			$('#resetCallVoteRatio').click(function(event){
+				event.preventDefault();
+				$(this).fadeOut().attr('hidden', true);
+				$('#CallVoteRatio').val('-1').hide().attr('hidden', true);
+				$('#callVoteRatioDisabled').fadeIn('fast').removeAttr('hidden').find('option').removeAttr('selected');
+				$('#callVoteRatioDisabled option:first').select();
+			});
+			
+			// ClientInputsMaxLatency
+			$('#ClientInputsMaxLatency').change(function(){
+				if( $(this).val() == 'more' ){
+					$(this).hide();
+					$('#ClientInputsMaxLatencyValue').fadeIn('fast').removeAttr('hidden').parent('td').find('.returnDefaultValue').fadeIn('fast').removeAttr('hidden');
+				}
+			});
+			// Revenir à la valeur par défaut
+			$('#resetClientInputsMaxLarency').click(function(event){
+				event.preventDefault();
+				$(this).fadeOut().attr('hidden', true);
+				$('#ClientInputsMaxLatencyValue').hide().attr('hidden', true).val('');
+				$('#ClientInputsMaxLatency').fadeIn('fast').removeAttr('hidden').find('option').removeAttr('selected');
+				$('#ClientInputsMaxLatency option:first').select();
+			});
+			
+			
+			// Gestion des options serveur
+			$('.srvopts_importexport input[name="srvoptsImportExport"]').click(function(){
+				var type = $(this).val();
+				
+				if(type == 'Import'){
+					$('#srvoptsExportName').fadeOut().attr('hidden', true);
+				}
+				else{
+					$('#srvoptsImportName').fadeOut().attr('hidden', true);
+				}
+				
+				$('#srvopts'+type+'Name').fadeIn('fast').removeAttr('hidden');
+			});
+		}
+		/**
+		* Game Infos
+		*/
+		else if( $('body').hasClass('section-gameinfos') || $('body').hasClass('section-maps-creatematchset') ){
+			// GameMode
+			getCurrentGameModeConfig();
+			$('#NextGameMode').change(function(){
+				getCurrentGameModeConfig();
+			});
+			
+			// FinishTimeout
+			$('#NextFinishTimeout').change(function(){
+				if( $(this).val() == 'more' ){
+					$(this).hide();
+					$('#NextFinishTimeoutValue').fadeIn('fast').removeAttr('hidden').val('15').parent('td').parent('tr').find('.returnDefaultValue').fadeIn('fast').parent('td').removeAttr('hidden');
+				}
+			});
+			
+			// ForceShowAllOpponents
+			$('#NextForceShowAllOpponents').change(function(){
+				if( $(this).val() == 'more' ){
+					$(this).hide();
+					$('#NextForceShowAllOpponentsValue').fadeIn('fast').removeAttr('hidden').val('2').parent('td').parent('tr').find('.returnDefaultValue').fadeIn('fast').parent('td').removeAttr('hidden');
+				}
+			});
+			
+			// Revenir à la valeur par défaut
+			$('.returnDefaultValue').click(function(event){
+				event.preventDefault();
+				$(this).fadeOut().attr('hidden', true);
+				$(this).parent('td').parent('tr').find('td.next input').hide().attr('hidden', true).val('');
+				$(this).parent('td').parent('tr').find('td.next select').fadeIn('fast').find('option').removeAttr('selected').find('option:first').select().removeAttr('hidden');
+			});
+			
+			// Infos équipes
+			$('#colorPickerTeam1').css('backgroundColor', $('#teamInfo1ColorHex').val());
+			$('#colorPickerTeam1').ColorPicker({
+				color: $('#teamInfo1ColorHex').val(),
+				onShow: function (colpkr) {
+					$(colpkr).slideDown('fast');
+					return false;
+				},
+				onHide: function (colpkr) {
+					$(colpkr).slideUp('fast');
+					return false;
+				},
+				onChange: function (hsb, hex, rgb) {
+					$('#colorPickerTeam1').css('backgroundColor', '#'+hex);
+					$('#teamInfo1ColorHex').val('#'+hex);
+					var val = $('#colorPickerTeam1 .colorpicker_hue div').css('top');
+					$('#teamInfo1Color').val(round(1 - val.substring(0, val.length-2)/150, 3));
+				}
+			});
+			$('#colorPickerTeam2').css('backgroundColor', $('#teamInfo2ColorHex').val());
+			$('#colorPickerTeam2').ColorPicker({
+				color: $('#teamInfo2ColorHex').val(),
+				onShow: function (colpkr) {
+					$(colpkr).slideDown('fast');
+					return false;
+				},
+				onHide: function (colpkr) {
+					$(colpkr).slideUp('fast');
+					return false;
+				},
+				onChange: function (hsb, hex, rgb) {
+					$('#colorPickerTeam2').css('backgroundColor', '#'+hex);
+					$('#teamInfo2ColorHex').val('#'+hex);
+					var val = $('#colorPickerTeam2 .colorpicker_hue div').css('top');
+					$('#teamInfo2Color').val(round(1 - val.substring(0, val.length-2)/150, 3));
+				}
+			});
+			
+			// Script settings
+			$('#getScriptSettings').click(function(event){
+				event.preventDefault();
+				getScriptSettings();
+			});
+			
+			// Affichage sec -> min
+			$('#NextTimeAttackLimit, #NextLapsTimeLimit, #hotSeatTimeLimit').click(function(){
+				$(this).parent('td').parent('tr').find('td.preview').html('['+secToMin( $(this).val() )+' min]');
+			});
+			$('#NextTimeAttackLimit, #NextLapsTimeLimit, #hotSeatTimeLimit').change(function(){
+				$(this).parent('td').parent('tr').find('td.preview').html('['+secToMin( $(this).val() )+' min]');
+			});
+			$('#NextTimeAttackLimit, #NextLapsTimeLimit, #hotSeatTimeLimit').keyup(function(){
+				$(this).parent('td').parent('tr').find('td.preview').html('['+secToMin( $(this).val() )+' min]');
+			});
+			$('#NextTimeAttackLimit, #NextLapsTimeLimit, #hotSeatTimeLimit').blur(function(){
+				$(this).parent('td').parent('tr').find('td.preview').html('');
+			});
+			
+			
+			/**
+			* Create MatchSettings
+			*/
+			if( $('body').hasClass('section-maps-creatematchset') ){
+				// Nom du matchSetting
+				$('#matchSettingName').keyup(function(event){
+					var key = event.keyCode;
+					if(key != 13 && key != 37 && key != 39){
+						matchset_getFileExists( $(this).val() );
+					}
+				});
+				
+				// Importer tout le dossier
+				$('#mapImport').click(function(){
+					$('.creatematchset .maps').addClass('loading');
+					matchset_mapImport();
+				});
+				
+				// Faire une sélection
+				$('#mapImportSelection').click(function(){
+					$('.creatematchset .maps').addClass('loading');
+					matchset_mapImportSelection();
+				});
+				
+				// Checkbox
+				$('#checkAllMapImport').click(function(){
+					var dialog = $('#mapImportSelectionDialog');
+					dialog.checkAll( $(this).attr('checked') );
+					if( dialog.find('tr.current').hasClass('selected') ){
+						dialog.find('tr.current').removeClass('selected');
+					}
+				});
+				
+				// Clic sur les lignes
+				$('#mapImportSelectionDialog').on('click', 'tr', function(){
+					// Si la ligne est déjà sélectionnée, on l'enlève
+					if( $(this).hasClass('selected') ){
+						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
+					}
+					// Sinon, on l'ajoute
+					else{
+						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
+					}
+					// Mise à jour du CheckAll
+					$('#mapImportSelectionDialog').updateCheckAll( $('#checkAllMapImport') );
+				});
+				
+				// Voir la sélection du matchsettings
+				$('#mapSelection').click(function(){
+					$('.creatematchset .maps').addClass('loading');
+					matchset_mapSelection();
+				});
+				
+				// Enlever une map de la sélection
+				$('#mapSelectionDialog').on('click', 'tr a', function(event){
+					event.preventDefault();
+					matchset_mapSelection( parseInt($(this).parent('td').parent('tr')[0].sectionRowIndex) );
+				});
+				
+				// Nom du MatchSettings
+				$('#matchSettingName').click(function(){
+					$(this).select();
+				});
+				$('#matchSettingName').blur(function(){
+					if( $(this).val() == '' ){
+						$(this).val('match_settings');
+					}
+				});
+				
+				// Submit
+				$('#savematchsetting').click(function(){
+					if( $('#nbMapSelected').text() == '0' ){
+						scrollTop();
+						error( $(this).data('nomap'), true);
+						return false;
+					}
+					else{
+						return true;
+					}
+				});
+			}
+		}
+		/**
+		* Chat
+		*/
+		else if( $('body').hasClass('section-chat') ){
+			var hideServerLines = 0;
+			
+			// Clique sur "Masquer les lignes du serveur"
+			$('.title-detail a').click(function(event){
+				event.preventDefault();
+				// Valeur
+				hideServerLines = $(this).data('val');
+				if(hideServerLines == 0){
+					hideServerLines = 1;
+				}
+				else{
+					hideServerLines = 0;
+				}
+				getChatServerLines(hideServerLines);
+				$(this).data('val', hideServerLines);
+				
+				// Texte
+				var text = $(this).text();
+				$(this).text( $(this).data('txt') ).data('txt', text);
+			});
+			
+			// Affichage toutes les 3s
+			setInterval(function(){
+				getChatServerLines(hideServerLines);
+			}, 3000);
+			
+			// Ajout d'un message
+			$('#chatNickname, #chatMessage').click(function(){
+				var text = $(this).val();
+				var defaultText = $(this).data('default-value');
+				
+				if(text == defaultText){
+					$(this).val('');
+				}
+			});
+			$('#chatNickname, #chatMessage').blur(function(){
+				var text = $(this).val();
+				var defaultText = $(this).data('default-value');
+				
+				if(text == ''){
+					$(this).val(defaultText);
+				}
+			});
+			$('#chatSend').click(function(){
+				var msg = $('#chatMessage').val();
+				if( msg != $('#chatMessage').data('default-value') && msg != '' ){
+					addChatServerLine();
+				}
+			});
+			$('#chatMessage').keypress(function(event){
+				var msg = $(this).val();
+				if( msg != $(this).data('default-value') && msg != '' ){
+					if( event.keyCode == 13 ){
+						addChatServerLine();
+					}
+				}
+			});
+		}
+		/**
+		* Maps-list
+		*/
+		else if( $('body').hasClass('section-maps-list') ){
+			var mapList = $('#maplist');
+			// Mise à jour de la liste
+			setInterval(function(){
+				getMapList(getMode());
+			}, 10000);
+			
+			// Checkbox
+			$('#checkAll').click(function(){
+				mapList.checkAll( $(this).prop('checked') );
+				if( mapList.find('tr.current').hasClass('selected') ){
+					mapList.find('tr.current').removeClass('selected');
+				}
+				
+				// Mise à jour du nb de lignes sélectionnées
+				$('.maps .list').updateNbSelectedLines();
+			});
+			
+			// Clic sur les lignes
+			mapList.on('click', 'tr', function(){
+				if( !$(this).hasClass('current') && !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
+					// Si la ligne est déjà sélectionnée, on l'enlève
+					if( $(this).hasClass('selected') ){
+						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
+					}
+					// Sinon, on l'ajoute
+					else{
+						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
+					}
+					
+					// Mise à jour du nb de lignes sélectionnées
+					$('.maps .list').updateNbSelectedLines();
+					$('.maps .list').updateCheckAll( $('#checkAll') );
+				}
+			});
+			
+			// Mode détail
+			$('#detailMode').click(function(event){
+				event.preventDefault();
+				mapList.setDetailMode();
+			});
+		}
+		/**
+		* Maps-upload
+		*/
+		else if( $('body').hasClass('section-maps-upload') ){
+			//Upload
+			var uploader = initializeUploader();
+			
+			// Mode de transfert
+			$('.transferMode li').click(function(){
+				$('.transferMode li').removeClass('selected');
+				$('.options-checkbox li')
+					.removeClass('disabled')
+					.find('input').prop('disabled', false);
+				$('#GotoListMaps').prop('checked', true);
+				
+				$(this)
+					.addClass('selected')
+					.find('input').prop('checked', true);
+				
+				if( $(this).find('input').val() == 'local' ){
+					$('#SaveCurrentMatchSettings')
+						.prop('disabled', true)
+						.parent().addClass('disabled');
+					$('#GotoListMaps').prop('checked', false);
+				}
+				uploader.setParams( getUploaderUserParams() );
+			});
+			
+			// Options
+			$('.options-checkbox input, .options-checkbox label').click(function(){
+				uploader.setParams( getUploaderUserParams() );
+			});
+		}
+		/**
+		* Maps-local
+		*/
+		else if( $('body').hasClass('section-maps-local') ){
+			// Checkbox
+			$('#checkAll').click(function(){
+				$('#maplist').checkAll( $(this).prop('checked') );
+				
+				// Mise à jour du nb de lignes sélectionnées
+				$('.maps .local').updateNbSelectedLines();
+			});
+			
+			// Clic sur les lignes
+			$('#maplist').on('click', 'tr', function(){
+				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
+					// Si la ligne est déjà sélectionnée, on l'enlève
+					if( $(this).hasClass('selected') ){
+						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
+					}
+					// Sinon, on l'ajoute
+					else{
+						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
+					}
+					
+					// Mise à jour du nb de lignes sélectionnées
+					$('.maps .local').updateNbSelectedLines();
+					$('.maps .local').updateCheckAll( $('#checkAll') );
+					
+					// Vérifie s'il reste des formulaires ouvert et les ferme quand il y 0 lignes sélectionnées
+					if( $('#maplist tr.selected').length == 0 ){
+						if( $('.selected-files-label').hasClass('optHover') ){
+							slideUpRenameForm();
+							slideUpMoveForm();
+						}
+					}
+				}
+			});
+			
+			// Renommer
+			$('#renameMap').click(function(){
+				if( !$('#maplist tr.selected').hasClass('onserver') ){
+					if( $(this).hasClass('active') ){
+						slideUpRenameForm();
+					}
+					else{
+						if( $('#moveMap').hasClass('active') ){
+							slideUpMoveForm();
+						}
+						slideDownRenameForm();
+					}
+				}
+				else{
+					var mapTextError = $('.local .options').data('mapisused').split(',');
+					var mapName = $('#maplist tr.selected td span').html();
+					error(mapTextError[0]+' '+mapName+' '+mapTextError[1]);
+					scrollTop();
+				}
+			});
+			$('#form-rename-map').on('click', '#renameMapCancel', function(){
+				slideUpRenameForm();
+			});
+			
+			// Déplacer
+			$('#moveMap').click(function(){
+				if( !$('#maplist tr.selected').hasClass('onserver') ){
+					if( $(this).hasClass('active') ){
+						slideUpMoveForm();
+					}
+					else{
+						if( $('#renameMap').hasClass('active') ){
+							slideUpRenameForm();
+						}
+						slideDownMoveForm();
+					}
+				}
+				else{
+					var mapTextError = $('.local .options').data('mapisused').split(',');
+					var mapName = $('#maplist tr.selected td span').html();
+					error(mapTextError[0]+' '+mapName+' '+mapTextError[1]);
+					scrollTop();
+				}
+			});
+			$('#form-move-map').on('click', '#moveMapCancel', function(){
+				slideUpMoveForm();
+			});
+			
+			// Supprimer
+			$('#deleteMap').click(function(){
+				if( !$('#maplist tr.selected').hasClass('onserver') ){
+					return confirm( $(this).data('confirm') );
+				}
+				else{
+					var mapTextError = $('.local .options').data('mapisused').split(',');
+					var mapName = $('#maplist tr.selected td span').html();
+					error(mapTextError[0]+' '+mapName+' '+mapTextError[1]);
+					scrollTop();
+					return false;
+				}
+			});
+		}
+		/**
+		* Maps-matchset
+		*/
+		else if( $('body').hasClass('section-maps-matchset') ){
+			// Checkbox
+			$('input#checkAll').click(function(){
+				$('#matchsetlist').checkAll( $(this).prop('checked') );
+				
+				// Mise à jour du nb de lignes sélectionnées
+				$('.maps .matchset').updateNbSelectedLines();
+			});
+			
+			// Clic sur les lignes
+			$('#matchsetlist').on('click', 'tr', function(){
+				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
+					// Si la ligne est déjà sélectionnée, on l'enlève
+					if( $(this).hasClass('selected') ){
+						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
+					}
+					// Sinon, on l'ajoute
+					else{
+						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
+					}
+					
+					// Mise à jour du nb de lignes sélectionnées
+					$('.maps .matchset').updateNbSelectedLines();
+					$('.maps .matchset').updateCheckAll( $('input#checkAll') );
+					
+					// Édition si une seule ligne sélectionné
+					if( $('.selected-files-count').text().replace('(', '').replace(')', '') > 1 ){
+						$('#editMatchset').attr('hidden', true);
+					}
+					else{
+						if( $('#editMatchset').attr('hidden') ){
+							$('#editMatchset').removeAttr('hidden');
+						}
+					}
+				}
+			});
+		}
+		/**
+		* Maps-order
+		*/
+		else if( $('body').hasClass('section-maps-order') ){
+			// Tri automatique
+			$('.autoSortMode li').click(function(){
+				$('#sortableMapList').addClass('loading');
+				$(this).children('input').prop('checked', true);
+				$('.autoSortMode li').removeClass('selected').find('span.ui-icon').removeClass('active');
+				$(this).addClass('ui-state-default selected').find('.icon .ui-icon-arrowthick-1-n').addClass('active');
+				
+				// Tri
+				setMapsOrderSort($(this).children('input').val(), 'asc');
+			});
+			$('.autoSortMode li span.ui-icon').click(function(){
+				$('#sortableMapList').addClass('loading');
+				$('.autoSortMode li').removeClass('selected').find('span.ui-icon').removeClass('active');
+				$(this).parents('li').addClass('selected').children('input').prop('checked', true);
+				$(this).addClass('active');
+				
+				if( $(this).hasClass('ui-icon-arrowthick-1-n') ){
+					var order = 'asc';
+				}
+				else{
+					var order = 'desc';
+				}
+				
+				// Tri
+				setMapsOrderSort($(this).parent('.icon').parent('li').children('input').val(), order);
+				
+				return false;
+			});
+			
+			// Tri manuel
+			$('#sortableMapList').sortable({
+				placeholder: 'ui-state-highlight',
+				revert: true,
+				zIndex: 9999
+			});
+			$('#reset').click(function(){
+				location.href = $('.section-maps-order .cadre.order form').attr('action');
+			});
+			$('#save').click(function(){
+				var listStr = '';
+				var list = $('#sortableMapList li .order-map-name');
+				if( list.length > 0 ){
+					$.each(list, function(i, n){
+						listStr += n.title+',';
+					});
+					$('#list').val(listStr.substring(0, listStr.length-1));
+				}
+			});
+		}
+		/**
+		* Guest-Ban
+		*/
+		else if( $('body').hasClass('section-guestban') ){
+			// CleanList
+			$('a.cleanList').click(function(){
+				var out = false;
+				var lines = $(this).parents('.title-detail').parent('div').find('tbody tr:not(.no-line)');
+				
+				if(lines.length > 1){
+					out = true;
+				}
+				else{
+					error( $('a.cleanList').data('empty'), true);
+				}
+				
+				return out;
+			});
+			
+			// Checkbox
+			$('#checkAllBanlist').click(function(){
+				$('#banlist').checkAll( $(this).prop('checked') );
+				$('.cadre.left').updateNbSelectedLines();
+			});
+			$('#checkAllBlacklist').click(function(){
+				$('#blacklist').checkAll( $(this).prop('checked') );
+				$('.cadre.left').updateNbSelectedLines();
+			});
+			$('#checkAllGuestlist').click(function(){
+				$('#guestlist').checkAll( $(this).prop('checked') );
+				$('.cadre.left').updateNbSelectedLines();
+			});
+			$('#checkAllIgnorelist').click(function(){
+				$('#ignorelist').checkAll( $(this).prop('checked') );
+				$('.cadre.left').updateNbSelectedLines();
+			});
+			$('#playlists #checkAllPlaylists').click(function(){
+				$('#playlists').checkAll( $(this).prop('checked') );
+				$('#playlists').updateNbSelectedLines();
+			});
+			
+			// Clic sur les lignes
+			$('#banlist, #blacklist, #guestlist, #ignorelist').on('click', 'tr', function(){
+				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
+					// Si la ligne est déjà sélectionnée, on l'enlève
+					if( $(this).hasClass('selected') ){
+						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
+					}
+					// Sinon, on l'ajoute
+					else{
+						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
+					}
+					
+					// Mise à jour du nb de lignes sélectionnées
+					$('.cadre.left').updateNbSelectedLines();
+					$('.cadre.left').updateCheckAll( $(this).parent('tbody').parent('table').parent('div').find('input[type=checkbox]') );
+				}
+			});
+			$('#playlists').on('click', 'tr', function(){
+				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
+					// Si la ligne est déjà sélectionnée, on l'enlève
+					if( $(this).hasClass('selected') ){
+						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
+					}
+					// Sinon, on l'ajoute
+					else{
+						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
+					}
+					
+					// Mise à jour du nb de lignes sélectionnées
+					$('#playlists').updateNbSelectedLines();
+					$('#playlists').updateCheckAll( $('#playlists #checkAllPlaylists') );
+				}
+			});
+			
+			// Ajouter
+			$('#addPlayerList').change(function(){
+				if( $(this).val() == 'more' ){
+					$(this).hide().attr('hidden', true);
+					$('#addPlayerLogin').fadeIn('fast').removeAttr('hidden');
+				}
+			});
+			$('#addPlayerLogin').click(function(){
+				if( $(this).val() == $(this).data('default-value') ){
+					$(this).val('');
+				}
+			});
+			$('#addPlayerLogin').blur(function(){
+				if( $(this).val() == '' ){
+					$(this).val( $(this).data('default-value') );
+				}
+			});
+			
+			// Créer une playlist
+			$('#clickNewPlaylist').click(function(event){
+				event.preventDefault();
+				var selector = $('#form-new-playlist');
+				if( selector.attr('hidden') ){
+					selector.animate({
+						height: '25px',
+						marginTop: '6px',
+						marginBottom: '6px'
+					}, 'fast').removeAttr('hidden');
+					$(this).text( $(this).data('cancel') );
+				}
+				else{
+					selector.animate({
+						height: '0',
+						marginTop: '0',
+						marginBottom: '0'
+					}, 'fast', function(){
+						$(this).attr('hidden', true);
+						$('#clickNewPlaylist').text( $('#clickNewPlaylist').data('newplaylist') );
+					});
+				}
+			});
+			$('#createPlaylistName').click(function(){
+				if( $(this).val() == $(this).data('playlistname') ){
+					$(this).val('');
+				}
+			});
+			$('#createPlaylistName').blur(function(){
+				var val = $(this).val();
+				if( val == '' ){
+					$(this).val( $(this).data('playlistname') );
+				}
+				else{
+					var extTXT = val.indexOf('.playlist.txt');
+					if(extTXT === -1){
+						$(this).val(val+'.playlist.txt');
+					}
+				}
+			});
+		}
+	}
+});
\ No newline at end of file
diff --git a/resources/js/adminserv_funct.js b/resources/js/adminserv_funct.js
new file mode 100644
index 0000000..e06060c
--- /dev/null
+++ b/resources/js/adminserv_funct.js
@@ -0,0 +1,1108 @@
+/**
+* Fonctions générales
+*/
+function getResourcesPath(){
+	return $.trim( $('#path_resources').text() );
+}
+function getPath(){
+	return $.trim( $('.path').text() );
+}
+function getMode(){
+	return $.trim( $('#detailMode').data('statusmode') );
+}
+function getCurrentSort(){
+	return $('#currentSort').val();
+}
+function setCurrentSort(sort){
+	return $('#currentSort').val(sort);
+}
+function scrollTop(){
+	$('html, body').animate({  
+		scrollTop: 0
+	}, 'slow');
+}
+function scrollBottom(){
+	$('html, body').animate({  
+		scrollTop: $(document).height() - $(window).height()
+	}, 'slow');
+}
+function getUrlParams(key){
+	var params = window.location.search.substring(1);
+	if(!key){
+		return params;
+	}
+	else{
+		var index = params.indexOf(key);
+		if(index !== -1){
+			return params.substring(index).split('&')[0].substring(2);
+		}
+	}
+}
+
+
+/**
+* Affiche la valeur seconde -> minute
+*
+* @param int sec -> La valeur en seconde
+*/
+function secToMin(sec){
+	if(sec == '' || sec == undefined || isNaN(sec) ){
+		sec = 0;
+	}
+	return round( (parseInt(sec) / 60), 1);
+}
+
+
+/**
+* Math.round avec précision
+*
+* @param int value     -> Valeur à arrondir
+* @param int precision -> Nombre de caractère après la virgule
+*/
+function round(value, precision){
+	power = Math.pow(10, precision);
+	return (Math.ceil(value * power)) / power;
+}
+
+
+/**
+* Affichage du texte d'erreur
+*/
+function error(text, hide){
+	var selector = $('#error');
+	selector.fadeIn('fast').html(text);
+	if( selector.attr('hidden') ){
+		selector.removeAttr('hidden');
+	}
+	
+	if(hide){
+		setTimeout(function(){
+			selector.attr('hidden', true).fadeOut('fast');
+		}, 4000);
+	}
+}
+
+
+/**
+* Affichage du texte d'erreur
+*/
+function info(text, hide){
+	var selector = $('#info');
+	selector.fadeIn('fast').html(text);
+	if( selector.attr('hidden') ){
+		selector.removeAttr('hidden');
+	}
+	
+	if(hide){
+		setTimeout(function(){
+			selector.attr('hidden', true).fadeOut('fast');
+		}, 4000);
+	}
+}
+
+
+/**
+* Administration rapide (restart, next, endround)
+*
+* @param string cmd -> Le nom de la méthode à utiliser
+*/
+function speedAdmin(cmd){
+	$.post(getResourcesPath()+'ajax/speed_admin.php', {cmd: cmd}, function(response){
+		if(response != 'true'){
+			error('Error: '+response);
+		}
+		setTimeout(function(){
+			var sort = getCurrentSort();
+			if( $('body').hasClass('section-index') ){
+				getCurrentServerInfo('', sort);
+			}
+			else if( $('body').hasClass('section-maps-list') ){
+				getMapList('', sort);
+			}
+			$('.speed-admin a.locked').removeClass('locked');
+		}, 2000);
+	});
+}
+
+
+/**
+* Récupère la liste des niveaux admin suivant le serveur sélectionné
+*/
+function getServerAdminLevel(){
+	var serverName = $('#as_server').val();
+	var adminLevelList = '';
+	
+	$.getJSON(getResourcesPath()+'ajax/get_server_adminlevel.php', {srv: serverName}, function(response){
+		if(response.levels != null){
+			$.each(response.levels, function(i, n){
+				if(response.last != null && response.last == n){ var selected = ' selected="selected"'; }
+				else{ var selected = ''; }
+				adminLevelList += '<option value="'+n+'"'+selected+'>'+n+'</option>';
+			});
+			
+			$('#as_adminlevel').html(adminLevelList);
+		}
+		else{
+			$('#as_adminlevel').empty();
+			error( $('#as_adminlevel').data('error') );
+		}
+	});
+}
+
+
+/**
+* Récupère les informations du serveur actuel (map, serveur, stats, joueurs)
+*/
+function getCurrentServerInfo(mode, sort){
+	var path_ressources = getResourcesPath();
+	if(!mode){
+		mode = getMode();
+	}
+	if(sort){
+		setCurrentSort(sort);
+	}
+	var isTeamGameMode = $('#isTeamGameMode').val();
+	
+	$.getJSON(getResourcesPath()+'ajax/get_current_serverinfo.php', {mode: mode, sort: sort}, function(data){
+		if(data != null){
+			// Map
+			if(data.map != null){
+				$('#map_name').html(data.map.name);
+				$('#map_author').html(data.map.author);
+				$('#map_enviro').html(data.map.enviro+'<img src="'+path_ressources+'images/env/'+data.map.enviro.toLowerCase()+'.png" alt="" />');
+				$('#map_uid').html(data.map.uid);
+				if(data.srv.gameModeScriptName){
+					var gameModeName = data.srv.gameModeScriptName+' <span class="scriptName">('+data.srv.gameModeName+')</span>';
+				}else{
+					var gameModeName = data.srv.gameModeName;
+				}
+				$('#map_gamemode').html(gameModeName).attr('class', '').addClass('value '+data.srv.gameModeName.toLowerCase() );
+				if(data.map.thumb){
+					$('#map_thumbnail').html('<img src="data:image/jpeg;base64,'+data.map.thumb+'" alt="'+$('#map_thumbnail').data('text-thumbnail')+'" />');
+				}
+				if(data.map.scores){
+					$('#ScoreTeamBlue').val(data.map.scores.blue);
+					$('#ScoreTeamRed').val(data.map.scores.red);
+				}
+			}
+			
+			// Server
+			if(data.srv != null){
+				$('#server_name').html(data.srv.name);
+				$('#server_status').html(data.srv.status);
+			}
+			
+			// Stats
+			if(data.net != null){
+				$('#network_uptime').html(data.net.uptime);
+				$('#network_nbrconnection').html(data.net.nbrconnection);
+				$('#network_meanconnectiontime').html(data.net.meanconnectiontime);
+				$('#network_meannbrplayer').html(data.net.meannbrplayer);
+				$('#network_recvnetrate').html(data.net.recvnetrate);
+				$('#network_sendnetrate').html(data.net.sendnetrate);
+				$('#network_totalreceivingsize').html(data.net.totalreceivingsize);
+				$('#network_totalsendingsize').html(data.net.totalsendingsize);
+			}
+			
+			// Players
+			if(data.ply != null && !$('#playerlist').isChecked() ){
+				var out = '';
+				
+				// Création du tableau
+				out += '<tr class="table-separation"><td colspan="'; if(isTeamGameMode){ out += '6'; }else{ out += '5'; } out += '"></td></tr>';
+				if( typeof(data.ply) == 'object' ){
+					$.each(data.ply, function(i, player){
+						out += '<tr class="'; if(i%2){ out += 'even'; }else{ out += 'odd'; } out += '">';
+							if(isTeamGameMode && mode == 'detail'){
+								out += '<td class="detailModeTd imgleft"><span class="team_'+player.TeamId+'" title="'+player.TeamName+'">&nbsp;</span>'+player.TeamName+'</td>';
+							}
+							out += '<td class="imgleft"><img src="'+path_ressources+'images/16/solo.png" alt="" />'+player.NickName+'</td>';
+							if( !isTeamGameMode && mode == "detail" ){
+								out += '<td class="imgleft"><img src="'+path_ressources+'images/16/leagueladder.png" alt="" />'+player.LadderRanking+'</td>';
+							}
+							out += '<td>'+player.Login+'</td>'
+							+'<td>'+player.PlayerStatus+'</td>'
+							+'<td class="checkbox"><input type="checkbox" name="player[]" value="'+player.Login+'" /></td>'
+						+'</tr>';
+					});
+					
+					if( $('#checkAll').attr('disabled') ){
+						$('#checkAll').prop('disabled', false);
+					}
+				}
+				else{
+					if( !$('#checkAll').attr('disabled') ){
+						$('#checkAll').prop('disabled', true);
+					}
+					out += '<tr class="no-line"><td class="center" colspan="'; if(isTeamGameMode){ out += '6'; }else{ out += '5'; } out += '">'+data.ply+'</td></tr>';
+				}
+				
+				// HTML
+				$('#playerlist table tbody').html(out);
+				$('.cadre.right .options .nb-line').html(data.nbp);
+				if( $('#playerlist').hasClass('loading') ){
+					$('#playerlist').removeClass('loading');
+				}
+			}
+		}
+	});
+}
+
+
+/**
+* Transforme une chaine de caractère de couleur en HTML
+*
+* @param string str
+*/
+(function($){
+	$.fn.getColorHtml = function(str){
+		var selector = $(this);
+		
+		$.getJSON(getResourcesPath()+'ajax/get_colorstr.php', {t: str}, function(data){
+			if(data != null){
+				selector.html(data.str);
+			}
+		});
+	};
+})(jQuery);
+
+
+/**
+* Récupère la configuration du gameMode sélectionné
+*/
+function getCurrentGameModeConfig(){
+	var gameMode = $('#NextGameMode option:selected').text();
+	var selector = $('#gameMode-'+gameMode.toLowerCase() );
+	
+	// Fermeture de tous les modes par défaut
+	if( $('body').hasClass('section-maps-creatematchset') ){
+		var section = '.section-maps-creatematchset';
+	}else{
+		var section = '.section-gameinfos';
+	}
+	$.each( $(section+' .content.gameinfos fieldset'), function(i, n){
+		if( !$(this).hasClass('gameinfos_general') && !$(this).hasClass('gameinfos_teaminfos') ){
+			if( $(this).attr('hidden') ){
+				$(this).hide();
+			}
+			else{
+				$(this).hide();
+				$(this).attr('hidden', true);
+			}
+		}
+	});
+	
+	// Affichage du mode de jeu sélectionné
+	if( selector.attr('hidden') ){
+		selector.slideDown('fast').removeAttr('hidden');
+	}
+}
+
+
+/**
+* Récupère les paramètres du script courant
+*/
+function getScriptSettings(){
+	$.post(getResourcesPath()+'ajax/script_settings.php', {method: 'get'}, function(data){
+		if(data != null){
+			// Script info
+			$('#dialogScriptInfoName').html(data.Name+' ('+data.Version+')');
+			$('#dialogScriptInfoCompatibleMapTypes').html(data.CompatibleMapTypes);
+			if(data.Description != ''){
+				$('.dialogScriptInfoDesc').attr('hidden', false);
+				$('#dialogScriptInfoDesc').html(data.Description);
+			}
+			
+			// Paramètres
+			paramsList = '';
+			if( typeof(data.ParamDescs) == 'object' ){
+				$.each(data.ParamDescs, function(i, param){
+					var paramValueField = '';
+					if(param.Type == 'boolean'){
+						var isChecked = '';
+						if(param.Default == 'True'){
+							isChecked = ' checked="checked"';
+						}
+						paramValueField = '<input class="text" data-type="'+param.Type+'" type="checkbox" name="'+param.Name+'" id="'+param.Name+'" value="'+param.Default+'"'+isChecked+' />';
+					}
+					else{
+						paramValueField = '<input class="text" data-type="'+param.Type+'" type="text" name="'+param.Name+'" id="'+param.Name+'" value="'+param.Default+'" />';
+					}
+					
+					paramsList += '<tr>'
+						+ '<td class="first">'+param.Name+'</td>'
+						+ '<td class="middle">'+paramValueField+'</td>'
+						+ '<td class="last">'+param.Desc+'</td>'
+					+ '</tr>';
+				});
+				
+				$('#dialogScriptSettings table tbody').html(paramsList);
+			}
+			
+			// Dialog
+			$('#getScriptSettingsDialog').dialog({
+				title: $('#getScriptSettingsDialog').data('title'),
+				modal: true,
+				minWidth: 800,
+				minHeight: 400,
+				buttons: [
+					{
+						text: $('#getScriptSettingsDialog').data('cancel'),
+						click: function(){
+							$(this).dialog('close');
+						}
+					},
+					{
+						text: $('#getScriptSettingsDialog').data('save'),
+						click: function(){
+							setScriptSettings();
+						}
+					}
+				]
+			});
+		}
+	}, 'json');
+}
+
+
+/**
+* Enregistre les paramètres du script courant
+*/
+function setScriptSettings(){
+	var params = [];
+	
+	$('#dialogScriptSettings table tbody tr').each(function(){
+		var key = $(this).find('.first').text();
+		var type = $(this).find('.middle input').data('type');
+		
+		if(type == 'boolean'){
+			if( $(this).find('.middle input').attr('checked') == 'checked' ){
+				var val = 1;
+			}
+			else{
+				var val = 0;
+			}
+		}
+		else{
+			var val = $(this).find('.middle input').val();
+		}
+		
+		params.push({
+			name: key,
+			value: val,
+			type: type,
+		});
+	});
+	
+	$.post(getResourcesPath()+'ajax/script_settings.php', {method: 'set', params: params}, function(response){
+		if(response != 'true'){
+			error(response);
+			scrollTop();
+		}
+		else{
+			$('#getScriptSettingsDialog').dialog('close');
+			info($('#getScriptSettings').data('infotext'), true);
+		}
+	});
+}
+
+
+/**
+* Récupère les lignes du chat du serveur
+*
+* @param bool hideServerLines -> Afficher ou non les lignes provenant d'un gestionnaire de serveur
+* @return string html
+*/
+function getChatServerLines(hideServerLines){
+	$.getJSON(getResourcesPath()+'ajax/get_chatserverlines.php', {s: hideServerLines}, function(data){
+		$('#chat').html(data);
+	});
+}
+
+
+/**
+* Ajoute une ligne (pseudo + message) dans le chat du serveur
+*/
+function addChatServerLine(){
+	var nickname = $('#chatNickname').val();
+	if( nickname == $('#chatNickname').data('default-value') ){
+		nickname = '';
+	}
+	var color = $('#chatColor').val();
+	var message = $('#chatMessage').val();
+	var destination = $('#chatDestination').val();
+	var hideServerLines = $('#checkServerLines').data('val');
+	
+	$.post(getResourcesPath()+'ajax/add_chatserverline.php', {nic: nickname, clr: color, msg: message, dst: destination}, function(response){
+		if(response != null){
+			getChatServerLines(hideServerLines);
+			$('#chatMessage').val('');
+		}
+	});
+}
+
+
+/**
+* Initialisation de l'uploader Ajax
+*/
+function initializeUploader(){
+	var formSelector = $('#formUpload');
+	var statusFiles = [];
+	var uploader = new qq.FileUploader({
+		element: formSelector[0],
+		action: getResourcesPath()+'ajax/upload.php',
+		maxConnections: 2,
+		params: getUploaderUserParams(),
+		template:
+		'<div class="qq-uploader">'
+			+ '<div class="qq-upload-drop-area"><span>'+ formSelector.data('dropfiles') +'</span></div>'
+			+ '<div class="qq-upload-button">'+ formSelector.data('uploadfile') +'</div>'
+			+ '<ul class="qq-upload-list"></ul>'
+		+ '</div>',
+		fileTemplate:
+		'<li>'
+			+ '<span class="qq-upload-file"></span>'
+			+ '<span class="qq-upload-spinner"><span class="qq-progress-bar"></span></span>'
+			+ '<span class="qq-upload-size"></span>'
+			+ '<a class="qq-upload-cancel" href="./">'+ formSelector.data('cancel') +'</a>'
+			+ '<span class="qq-upload-failed-text">'+ formSelector.data('failed') +'</span>'
+		+ '</li>',
+		onProgress: function(id, fileName, loaded, total){
+			window.onbeforeunload = function(){
+				return formSelector.data('uploadnotfinished');
+			}
+			$.each( $('.qq-upload-list li'), function(key, value){
+				var uploadSizeSelector = $(this).find('.qq-upload-size');
+				var text = uploadSizeSelector.text();
+				var newtext = text.replace(/from/gi, formSelector.data('from') );
+				newtext = newtext.replace(/kb/gi, formSelector.data('kb') );
+				newtext = newtext.replace(/mb/gi, formSelector.data('mb') );
+				var lastpos = text.indexOf('%');
+				var pourcent = text.substring(0, lastpos);
+				
+				uploadSizeSelector.text(newtext);
+				$(this).find('.qq-progress-bar').css('width', pourcent+'px');
+			});
+		},
+		onComplete: function(id, fileName, responseJSON){
+			window.onbeforeunload = function(){}
+			
+			if(uploader._options.params.gtlm){
+				if(responseJSON.success){
+					var status = true;
+				}
+				else{
+					var status = false;
+				}
+				statusFiles.push(status);
+				
+				if(uploader.getInProgress() == 0){
+					var allowRedirect = true;
+					for(var i = 0; i < statusFiles.length; i++){
+						if(statusFiles[i] === false){
+							allowRedirect = false;
+							break;
+						}
+					}
+					
+					if(allowRedirect){
+						location.href = '?p='+formSelector.data('mapspagename');
+					}
+				}
+			}
+		},
+		onCancel: function(id, fileName){
+			window.onbeforeunload = function(){}
+		},
+		messages: {
+			typeError: formSelector.data('type-error'),
+			sizeError: formSelector.data('size-error'),
+			minSizeError: formSelector.data('minsize-error'),
+			emptyError: formSelector.data('empty-error'),
+			onLeave: formSelector.data('onleave')
+		},
+		showMessage: function(message){
+			error(message);
+		}
+	});
+	
+	return uploader;
+}
+
+
+/**
+* Récupère les paramètres utilisateur de l'uploader
+*/
+function getUploaderUserParams(){
+	return {
+		path: getPath(),
+		type: $('.transferMode li.selected input').val(),
+		mset: ( $('#SaveCurrentMatchSettings').attr('checked') ) ? true : false,
+		gtlm: ( $('#GotoListMaps').attr('checked') ) ? true : false
+	};
+}
+
+
+/**
+* Récupère la liste des maps du serveur
+*/
+function getMapList(mode, sort){
+	var path_ressources = getResourcesPath();
+	if(!mode){
+		mode = getMode();
+	}
+	if(sort){
+		setCurrentSort(sort);
+	}
+	
+	$.getJSON(getResourcesPath()+'ajax/get_maplist.php', {mode: mode, sort: sort}, function(data){
+		if(data != null){
+			if(data.lst != null && !$('#maplist').isChecked() ){
+				var out = '';
+				
+				// Création du tableau
+				out += '<tr class="table-separation"><td colspan="6"></td></tr>';
+				if( typeof(data.lst) == 'object' ){
+					$.each(data.lst, function(i, map){
+						out += '<tr'; if(data.cid == i){ out += ' id="currentMap"'; } out += ' class="'; if(i%2){ out += 'even'; }else{ out += 'odd'; } if(data.cid == i){ out += ' current'; } out += '">'
+							+'<td class="imgleft"><img src="'+path_ressources+'images/16/map.png" alt="" />'
+								+'<span title="'+map.FileName+'">'+map.Name+'</span>'
+								if(mode == 'detail'){
+									out += '<span class="detailModeTd">'+map.UId+'</span>';
+								}
+							out += '</td>'
+							+'<td class="imgcenter"><img src="'+path_ressources+'images/env/'+map.Environment.toLowerCase()+'.png" alt="" />'+map.Environment+'</td>'
+							+'<td>'+map.Author+'</td>';
+							if(mode == 'detail'){
+								out += '<td>'+map.GoldTime+'</td>'
+								+'<td>'+map.CopperPrice+'</td>';
+							}
+							out += '<td class="checkbox">'; if(data.cid != i){ out += '<input type="checkbox" name="map[]" value="'+map.FileName+'" />'; } out += '</td>'
+						+'</tr>';
+					});
+					
+					if( $('#checkAll').attr('disabled') ){
+						$('#checkAll').prop('disabled', false);
+					}
+				}
+				else{
+					if( !$('#checkAll').attr('disabled') ){
+						$('#checkAll').prop('disabled', true);
+					}
+					out += '<tr class="no-line"><td class="center" colspan="6">'+data.lst+'</td></tr>';
+				}
+				
+				// HTML
+				$('#maplist table tbody').html(out);
+				$('.cadre.right .options .nb-line').html(data.nbm.count+' '+data.nbm.title);
+				if( $('#maplist').hasClass('loading') ){
+					$('#maplist').removeClass('loading');
+				}
+			}
+		}
+	});
+}
+
+
+/**
+* Récupère la liste des fichiers map pour les renommer
+*/
+(function($){
+	$.fn.getMapRenameList = function(){
+		var out = '';
+		var formSelector = $('#form-rename-map');
+		var list = $(this);
+		if( list.length > 0 ){
+			out += '<ul>';
+			list.each(function(){
+				var mapName = $(this).val().replace(getUrlParams('d'), '');
+				if(mapName.length > 36){
+					var title = ' title="'+mapName+'"';
+				}else{
+					var title = '';
+				}
+				out += '<li>'
+					+ '<span class="rename-map-name"'+title+'>'+mapName+'</span>'
+					+ '<span class="rename-map-arrow">&nbsp;</span>'
+					+ '<input class="text width3" type="text" id="renameMapList" name="renameMapList[]" value="'+mapName+'" />'
+				+ '</li>';
+			});
+			out += '</ul>';
+		}
+		
+		// HTML
+		out += '<div class="form-input-submit">'
+			+ '<input class="button dark" type="button" id="renameMapCancel" name="renameMapCancel" value="'+formSelector.data('cancel')+'" />'+"\n"
+			+ '<input class="button dark" type="submit" id="renameMapValid" name="renameAutoValid" value="'+formSelector.data('autorename')+'" />'
+			+ '<input class="button dark" type="submit" id="renameMapValid" name="renameMapValid" value="'+formSelector.data('rename')+'" />'
+		+ '</div>';
+		formSelector.html(out);
+	};
+})(jQuery);
+
+
+/**
+* Récupère l'arboréscence des dossiers pour déplacer
+*/
+function getMoveFolderList(nbFiles){
+	$.getJSON(getResourcesPath()+'ajax/get_directory_list.php', function(data){
+		if(data != null){
+			var out = '';
+			var formSelector = $('#form-move-map');
+			if( nbFiles > 1 ){
+				var nbName = nbFiles + ' maps';
+			}else{
+				var nbName = '1 map';
+			}
+			out += '<label for="moveDirectoryList">'+formSelector.data('move')+' '+nbName+' '+formSelector.data('inthefolder')+'</label>'
+			+ '<select name="moveDirectoryList" id="moveDirectoryList">'
+				+ '<option value=".">'+formSelector.data('root')+'</option>';
+				$.each(data, function(i, n){
+					out += '<option value="'+n.path+'">'+n.level+n.name+'</option>';
+				});
+			out += '</select>'
+			+ '<div class="form-input-submit">'
+				+ '<input class="button dark" type="button" id="moveMapCancel" name="moveMapCancel" value="'+formSelector.data('cancel')+'" />'+"\n"
+				+ '<input class="button dark" type="submit" id="moveMapValid" name="moveMapValid" value="'+formSelector.data('move')+'" />'
+			+ '</div>';
+			
+			// HTML
+			formSelector.html(out);
+		}
+	});
+}
+
+/**
+* Fonctions d'affichage des formulaires
+*/
+function slideDownRenameForm(){
+	$('#form-rename-map').slideDown('fast');
+	$('#renameMap').addClass('active');
+	$('.options').addClass('form').find('.selected-files-label').addClass('optHover');
+	$('#maplist table tbody tr.selected td.checkbox input').getMapRenameList();
+}
+function slideUpRenameForm(){
+	$('#form-rename-map').slideUp('fast');
+	$('#renameMap').removeClass('active');
+	$('.options').removeClass('form').find('.selected-files-label').removeClass('optHover');
+}
+function slideDownMoveForm(){
+	$('#form-move-map').slideDown('fast');
+	$('#moveMap').addClass('active');
+	$('.options').addClass('form').find('.selected-files-label').addClass('optHover');
+	if( $('#form-move-map').text() == '' ){
+		getMoveFolderList( $('#maplist table tbody tr.selected td.checkbox input').length );
+	}
+}
+function slideUpMoveForm(){
+	$('#form-move-map').slideUp('fast');
+	$('#moveMap').removeClass('active');
+	$('.options').removeClass('form').find('.selected-files-label').removeClass('optHover');
+}
+function slideDownNewFolderForm(){
+	$('#form-new-folder').animate({
+		height: '25px',
+		marginTop: '6px',
+		marginBottom: '6px'
+	}, 'fast').removeAttr('hidden');
+	$('#newfolder').text( $('#newfolder').data('cancel') );
+	$('#newFolderName').select();
+}
+function slideUpNewFolderForm(){
+	$('#form-new-folder').animate({
+		height: '0',
+		marginTop: '0',
+		marginBottom: '0'
+	}, 'fast', function(){
+		$('#form-new-folder').attr('hidden', true);
+		$('#newfolder').text( $('#newfolder').data('new') );
+	});
+}
+
+
+/**
+* Fait un tri sur la liste des maps pour la page "maps-order"
+*/
+function setMapsOrderSort(sort, order){
+	var resourcesPath = getResourcesPath();
+	var list = $('#jsonlist').val();
+	
+	$.post(getResourcesPath()+'ajax/mapsorder_sort.php', {srt: sort, ord: order, lst: list}, function(data){
+		if(data != null){
+			var out = '';
+			if( typeof(data.lst) == 'object' ){
+				$.each(data.lst, function(id, map){
+					out += '<li class="ui-state-default">'
+						+ '<div class="ui-icon ui-icon-arrowthick-2-n-s"></div>'
+						+ '<div class="order-map-name" title="'+map.FileName+'">'+map.Name+'</div>'
+						+ '<div class="order-map-env"><img src="'+resourcesPath+'images/env/'+map.Environment.toLowerCase()+'.png" alt="" />'+map.Environment+'</div>'
+						+ '<div class="order-map-author"><img src="'+resourcesPath+'images/16/mapauthor.png" alt="" />'+map.Author+'</div>'
+					+ '</li>';
+				});
+			}
+			
+			// HTML
+			$('#sortableMapList').html(out);
+			if( $('#sortableMapList').hasClass('loading') ){
+				$('#sortableMapList').removeClass('loading');
+			}
+		}
+	}, 'json');
+}
+
+
+/**
+* Met en place l'affichage en mode détail
+*/
+(function($){
+	$.fn.setDetailMode = function(){
+		var sort = getCurrentSort();
+		var type = $(this).attr('id');
+		
+		if( $('#detailMode').text() == $('#detailMode').data('textdetail') ){
+			if(type == 'maplist'){
+				getMapList('detail', sort);
+			}
+			else if(type == 'playerlist'){
+				getCurrentServerInfo('detail', sort);
+			}
+			$('#detailMode').text( $('#detailMode').data('textsimple') ).data('statusmode', 'detail');
+			$(this).addClass('loading').find('table th.detailModeTh').attr('hidden', false);
+		}
+		else{
+			if(type == 'maplist'){
+				getMapList('simple', sort);
+			}
+			else if(type == 'playerlist'){
+				getCurrentServerInfo('simple', sort);
+			}
+			$('#detailMode').text( $('#detailMode').data('textdetail') ).data('statusmode', 'simple');
+			$(this).addClass('loading').find('table th.detailModeTh').attr('hidden', true);
+		}
+	};
+})(jQuery);
+
+
+/**
+* Coche toutes les checkbox d'un selecteur
+*
+* @param bool isChecked -> Si la checkbox "checkAll" est cochée
+*/
+(function($){
+	$.fn.checkAll = function(isChecked){
+		var lineSelector = $(this).find('tbody tr[class!="table-separation"]');
+		var checkboxSelector = $(this).find('tbody td.checkbox input[type="checkbox"]');
+		if(isChecked){
+			checkboxSelector.prop('checked', true);
+			lineSelector.addClass('selected');
+		}
+		else{
+			checkboxSelector.prop('checked', false);
+			lineSelector.removeClass('selected');
+		}
+	};
+})(jQuery);
+
+/**
+* Met à jour la checkbox "checkAll" si toutes les lignes sont cochées ou non
+*
+* @param string checkAllSelector -> Selecteur de l'input "checkAll"
+*/
+(function($){
+	$.fn.updateCheckAll = function(checkAllSelector){
+		var nbSelected = $(this).find('tbody tr.selected').length;
+		var nbAll = $(this).find('tbody tr[class!="table-separation"]').length;
+		if( $('body').hasClass('section-maps-list') ){
+			nbAll--;
+		}
+		
+		if(nbSelected == nbAll){
+			checkAllSelector.prop('checked', true);
+		}
+		else if(nbSelected == 0){
+			if( checkAllSelector.prop('checked') ){
+				checkAllSelector.prop('checked', false);
+			}
+		}
+	};
+})(jQuery);
+
+
+/**
+* Met à jour le nombre de fichiers sélectionnés
+*/
+(function($){
+	$.fn.updateNbSelectedLines = function(){
+		var nb = $(this).find('tbody tr.selected').length;
+		
+		if(nb > 0){
+			$(this).find('.selected-files-label').removeClass('locked');
+		}
+		else{
+			$(this).find('.selected-files-label').addClass('locked');
+		}
+		$(this).find('.selected-files-count').text('('+nb+')');
+	};
+})(jQuery);
+
+
+/**
+* Détermine si il y a au moins une ligne sélectionnée
+*/
+(function($){
+	$.fn.isChecked = function(){
+		var nb = $(this).find('tbody tr.selected').length;
+		
+		if(nb > 0){
+			return true;
+		}
+		else{
+			return false;
+		}
+	};
+})(jQuery);
+
+
+
+/**
+* MATCHSETTINGS
+*/
+
+/**
+* Vérifie si le nom du MatchSettings n'existe pas déjà
+*
+* @param string filename -> Le nom du fichier
+*/
+function matchset_getFileExists(filename){
+	$.getJSON(getResourcesPath()+'ajax/get_matchset_fileexists.php', {path: getPath(), name: filename}, function(response){
+		if(response){
+			$('#matchSettingNameExists').attr('hidden', false).hide().fadeIn('fast');
+		}
+		else{
+			$('#matchSettingNameExists').attr('hidden', true).fadeOut('fast');
+		}
+	});
+}
+
+/**
+* Récupère la liste des maps en local pour la création d'un matchSettings
+*/
+function matchset_mapImport(){
+	var path = $('#mapsDirectoryList').val();
+	var directory = getUrlParams('d');
+	
+	$.getJSON(getResourcesPath()+'ajax/get_matchset_mapimport.php', {path: path, d: directory}, function(data){
+		if(data != null){
+			matchset_setNbMapSelection(data.nbm.count);
+			$('.creatematchset .maps').removeClass('loading');
+		}
+	});
+}
+function matchset_mapImportSelection(){
+	var path = $('#mapsDirectoryList').val();
+	var directory = getUrlParams('d');
+	var resourcesPath = getResourcesPath();
+	
+	$.getJSON(resourcesPath+'ajax/get_matchset_mapimport.php', {path: path, d: directory, op: 'getSelection'}, function(data){
+		if(data != null){
+			var out = '';
+			
+			// Création du tableau
+			out += '<tr class="table-separation"><td colspan="4"></td></tr>';
+			if( typeof(data.lst) == 'object' ){
+				$.each(data.lst, function(i, map){
+					out += '<tr class="'; if(i%2){ out += 'even'; }else{ out += 'odd'; } out += '">'
+						+'<td class="imgleft"><img src="'+resourcesPath+'images/16/map.png" alt="" />'
+							+'<span title="'+map.FileName+'">'+map.Name+'</span>'
+						out += '</td>'
+						+'<td class="imgcenter"><img src="'+resourcesPath+'images/env/'+map.Environment.toLowerCase()+'.png" alt="" />'+map.Environment+'</td>';
+						if(map.Type){
+							out += '<td><span title="'+map.Type.FullName+'">'+map.Type.Name+'</span></td>';
+						}
+						else{
+							out += '<td>-</td>';
+						}
+						out += '<td>'+map.Author+'</td>';
+						out += '<td class="checkbox"><input type="checkbox" name="map[]" value="'+map.FileName+'" /></td>'
+					+'</tr>';
+				});
+				
+				if( $('#checkAllMapImport').attr('disabled') ){
+					$('#checkAllMapImport').prop('disabled', false);
+				}
+			}
+			else{
+				if( !$('#checkAllMapImport').attr('disabled') ){
+					$('#checkAllMapImport').prop('disabled', true);
+				}
+				out += '<tr class="no-line"><td class="center" colspan="4">'+data.lst+'</td></tr>';
+			}
+			
+			// HTML
+			$('#mapImportSelectionDialog').removeAttr('hidden').find('table tbody').html(out);
+			$('.creatematchset .maps').removeClass('loading');
+			$('#mapImportSelectionDialog').dialog({
+				title: $('#mapImportSelectionDialog').data('title'),
+				modal: true,
+				minWidth: 800,
+				minHeight: 400,
+				buttons: [{
+					text: $('#mapImportSelectionDialog').data('select'),
+					click: function(){
+						var listSelection = $('#mapImportSelectionDialog tbody tr.selected');
+						var listSelectionId = [];
+						if( listSelection.length > 0 ){
+							$.each(listSelection, function(i, n){
+								if( n.className.indexOf('selected') !== -1 ){
+									listSelectionId.push( parseInt(n.sectionRowIndex - 1) );
+								}
+							});
+						}
+						$.getJSON(resourcesPath+'ajax/get_matchset_mapimport.php', {path: path, op: 'setSelection', select: listSelectionId}, function(data){
+							if(data != null){
+								matchset_setNbMapSelection(data.nbm.count);
+								$('#mapImportSelectionDialog').dialog('close');
+							}
+						});
+					}
+				}]
+			});
+		}
+	});
+}
+
+
+/**
+* Met à jour le nombre de maps sélectionnées
+*
+* @param int nb
+*/
+function matchset_setNbMapSelection(nb){
+	$('#nbMapSelected').text(nb);
+}
+/**
+* Récupère et affiche la sélection du MatchSettings
+*/
+function matchset_mapSelection(removeId){
+	var path_ressources = getResourcesPath();
+	if(removeId){
+		var params = {remove: parseInt(removeId - 1)};
+	}else{
+		var params = '';
+	}
+	$.getJSON(getResourcesPath()+'ajax/get_matchset_mapselection.php', params, function(data){
+		if(data != null){
+			var out = '';
+			
+			// Création du tableau
+			out += '<tr class="table-separation"><td colspan="4"></td></tr>';
+			if( typeof(data.lst) == 'object' ){
+				$.each(data.lst, function(i, map){
+					out += '<tr class="'; if(i%2){ out += 'even'; }else{ out += 'odd'; } out += '">'
+						+ '<td class="imgleft"><img src="'+path_ressources+'images/16/map.png" alt="" />'
+							+ '<span title="'+map.FileName+'">'+map.Name+'</span>'
+						+ '</td>'
+						+ '<td class="imgcenter"><img src="'+path_ressources+'images/env/'+map.Environment.toLowerCase()+'.png" alt="" />'+map.Environment+'</td>';
+						if(map.Type){
+							out += '<td><span title="'+map.Type.FullName+'">'+map.Type.Name+'</span></td>';
+						}
+						else{
+							out += '<td>-</td>';
+						}
+						out += '<td>'+map.Author+'</td>'
+						+ '<td class="checkbox imgcenter"><a href="." title="'+$("#mapSelectionDialog").data("remove")+'"><img src="'+path_ressources+'images/16/delete.png" alt="" /></a></td>'
+					+ '</tr>';
+				});
+			}
+			else{
+				out += '<tr class="no-line"><td class="center" colspan="4">'+data.lst+'</td></tr>';
+			}
+			
+			// HTML
+			matchset_setNbMapSelection(data.nbm.count);
+			$('#mapSelectionDialog').removeAttr('hidden').find('table tbody').html(out);
+			$('.creatematchset .maps').removeClass('loading');
+			$('#mapSelectionDialog').dialog({
+				title: $('#mapSelectionDialog').data('title'),
+				modal: true,
+				minWidth: 800,
+				minHeight: 400,
+				buttons: [{
+					text: $('#mapSelectionDialog').data('close'),
+					click: function(){
+						$(this).dialog('close');
+					}
+				}]
+			});
+		}
+	});
+}
+
+
+/* Folders */
+function getRenameFolderForm(){
+	$('#renameFolderForm').removeAttr('hidden');
+	$('#renameFolderForm').dialog({
+		title: $('#renameFolderForm').data('title'),
+		modal: true,
+		resizable: false,
+		minWidth: 406,
+		buttons: [
+			{
+				text: $('#renameFolderForm').data('cancel'),
+				click: function(){
+					$(this).dialog('close');
+				}
+			},
+			{
+				text: $('#renameFolderForm').data('rename'),
+				click: function(){
+					$('#optionFolderHiddenFieldValue').val( $('#renameFolderNewName').val() );
+					$('#optionFolderForm').submit();
+				}
+			},
+			
+		]
+	});
+}
+function getMoveFolderForm(){
+	$('#moveFolderForm').removeAttr('hidden');
+	$.getJSON(getResourcesPath()+'ajax/get_directory_list.php', function(data){
+		if(data != null){
+			var out = '';
+			var formSelector = $('#moveFolderForm');
+			out += '<label for="moveFormDirectoryList">'+formSelector.data('movethefolder')+'</label>'
+			+ '<select name="moveFormDirectoryList" id="moveFormDirectoryList">'
+				+ '<option value=".">'+formSelector.data('root')+'</option>';
+				$.each(data, function(i, n){
+					out += '<option value="'+n.path+'">'+n.level+n.name+'</option>';
+				});
+			out += '</select>';
+			
+			// HTML
+			formSelector.html(out);
+		}
+	});
+	$('#moveFolderForm').dialog({
+		title: $('#moveFolderForm').data('title'),
+		modal: true,
+		resizable: false,
+		minWidth: 406,
+		buttons: [
+			{
+				text: $('#moveFolderForm').data('cancel'),
+				click: function(){
+					$(this).dialog('close');
+				}
+			},
+			{
+				text: $('#moveFolderForm').data('move'),
+				click: function(){
+					$('#optionFolderHiddenFieldValue').val( $('#moveFormDirectoryList').val() );
+					$('#optionFolderForm').submit();
+				}
+			},
+			
+		]
+	});
+}
\ No newline at end of file
diff --git a/resources/js/colorpicker.js b/resources/js/colorpicker.js
new file mode 100644
index 0000000..34e71c7
--- /dev/null
+++ b/resources/js/colorpicker.js
@@ -0,0 +1,9 @@
+/**
+ *
+ * Color picker
+ * Author: Stefan Petre www.eyecon.ro
+ *
+ * Dual licensed under the MIT and GPL licenses
+ *
+ */
+(function(a){var b=function(){var b={},c,d=65,e,f='<div class="colorpicker"><div class="colorpicker_color"><div><div></div></div></div><div class="colorpicker_hue"><div></div></div><div class="colorpicker_new_color"></div><div class="colorpicker_current_color"></div><div class="colorpicker_hex"><input type="text" maxlength="6" size="6" /></div><div class="colorpicker_rgb_r colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_rgb_g colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_rgb_b colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_h colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_s colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_b colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_submit"></div></div>',g={eventName:"click",onShow:function(){},onBeforeShow:function(){},onHide:function(){},onChange:function(){},onSubmit:function(){},color:"ff0000",livePreview:true,flat:false},h=function(b,c){var d=P(b);a(c).data("colorpicker").fields.eq(1).val(d.r).end().eq(2).val(d.g).end().eq(3).val(d.b).end()},i=function(b,c){a(c).data("colorpicker").fields.eq(4).val(b.h).end().eq(5).val(b.s).end().eq(6).val(b.b).end()},j=function(b,c){a(c).data("colorpicker").fields.eq(0).val(R(b)).end()},k=function(b,c){a(c).data("colorpicker").selector.css("backgroundColor","#"+R({h:b.h,s:100,b:100}));a(c).data("colorpicker").selectorIndic.css({left:parseInt(150*b.s/100,10),top:parseInt(150*(100-b.b)/100,10)})},l=function(b,c){a(c).data("colorpicker").hue.css("top",parseInt(150-150*b.h/360,10))},m=function(b,c){a(c).data("colorpicker").currentColor.css("backgroundColor","#"+R(b))},n=function(b,c){a(c).data("colorpicker").newColor.css("backgroundColor","#"+R(b))},o=function(b){var c=b.charCode||b.keyCode||-1;if(c>d&&c<=90||c==32){return false}var e=a(this).parent().parent();if(e.data("colorpicker").livePreview===true){p.apply(this)}},p=function(b){var c=a(this).parent().parent(),d;if(this.parentNode.className.indexOf("_hex")>0){c.data("colorpicker").color=d=N(L(this.value))}else if(this.parentNode.className.indexOf("_hsb")>0){c.data("colorpicker").color=d=J({h:parseInt(c.data("colorpicker").fields.eq(4).val(),10),s:parseInt(c.data("colorpicker").fields.eq(5).val(),10),b:parseInt(c.data("colorpicker").fields.eq(6).val(),10)})}else{c.data("colorpicker").color=d=O(K({r:parseInt(c.data("colorpicker").fields.eq(1).val(),10),g:parseInt(c.data("colorpicker").fields.eq(2).val(),10),b:parseInt(c.data("colorpicker").fields.eq(3).val(),10)}))}if(b){h(d,c.get(0));j(d,c.get(0));i(d,c.get(0))}k(d,c.get(0));l(d,c.get(0));n(d,c.get(0));c.data("colorpicker").onChange.apply(c,[d,R(d),P(d)])},q=function(b){var c=a(this).parent().parent();c.data("colorpicker").fields.parent().removeClass("colorpicker_focus")},r=function(){d=this.parentNode.className.indexOf("_hex")>0?70:65;a(this).parent().parent().data("colorpicker").fields.parent().removeClass("colorpicker_focus");a(this).parent().addClass("colorpicker_focus")},s=function(b){var c=a(this).parent().find("input").focus();var d={el:a(this).parent().addClass("colorpicker_slider"),max:this.parentNode.className.indexOf("_hsb_h")>0?360:this.parentNode.className.indexOf("_hsb")>0?100:255,y:b.pageY,field:c,val:parseInt(c.val(),10),preview:a(this).parent().parent().data("colorpicker").livePreview};a(document).bind("mouseup",d,u);a(document).bind("mousemove",d,t)},t=function(a){a.data.field.val(Math.max(0,Math.min(a.data.max,parseInt(a.data.val+a.pageY-a.data.y,10))));if(a.data.preview){p.apply(a.data.field.get(0),[true])}return false},u=function(b){p.apply(b.data.field.get(0),[true]);b.data.el.removeClass("colorpicker_slider").find("input").focus();a(document).unbind("mouseup",u);a(document).unbind("mousemove",t);return false},v=function(b){b.preventDefault();var c={cal:a(this).parent(),y:a(this).offset().top};c.preview=c.cal.data("colorpicker").livePreview;a(document).bind("mouseup touchend",c,x);a(document).bind("mousemove touchmove",c,w)},w=function(a){var b=a;if(typeof event!=="undefined"&&event.touches){b=event.touches[0]}p.apply(a.data.cal.data("colorpicker").fields.eq(4).val(parseInt(360*(150-Math.max(0,Math.min(150,b.pageY-a.data.y)))/150,10)).get(0),[a.data.preview]);return false},x=function(b){h(b.data.cal.data("colorpicker").color,b.data.cal.get(0));j(b.data.cal.data("colorpicker").color,b.data.cal.get(0));a(document).unbind("mouseup touchend",x);a(document).unbind("mousemove touchmove",w);return false},y=function(b){b.preventDefault();var c={cal:a(this).parent(),pos:a(this).offset()};c.preview=c.cal.data("colorpicker").livePreview;a(document).bind("mouseup touchend",c,A);a(document).bind("mousemove touchmove",c,z)},z=function(a){var b=a;if(typeof event!=="undefined"&&event.touches){b=event.touches[0]}p.apply(a.data.cal.data("colorpicker").fields.eq(6).val(parseInt(100*(150-Math.max(0,Math.min(150,b.pageY-a.data.pos.top)))/150,10)).end().eq(5).val(parseInt(100*Math.max(0,Math.min(150,b.pageX-a.data.pos.left))/150,10)).get(0),[a.data.preview]);return false},A=function(b){h(b.data.cal.data("colorpicker").color,b.data.cal.get(0));j(b.data.cal.data("colorpicker").color,b.data.cal.get(0));a(document).unbind("mouseup touchend",A);a(document).unbind("mousemove touchmove",z);return false},B=function(b){a(this).addClass("colorpicker_focus")},C=function(b){a(this).removeClass("colorpicker_focus")},D=function(b){var c=a(this).parent();var d=c.data("colorpicker").color;c.data("colorpicker").origColor=d;m(d,c.get(0));c.data("colorpicker").onSubmit(d,R(d),P(d),c.data("colorpicker").el)},E=function(b){var c=a("body"),d=c.data("colorpickerId"),e=a(this).data("colorpickerId");if(d&&d===e){a(document).trigger("mousedown");c.data("colorpickerId",null)}else{F.call(this,b);c.data("colorpickerId",e)}},F=function(b){var c=a("#"+a(this).data("colorpickerId"));c.data("colorpicker").onBeforeShow.apply(this,[c.get(0)]);var d=a(this).offset();var e=I();var f=d.top+this.offsetHeight;var g=d.left;if(f+176>e.t+e.h){f-=this.offsetHeight+176}if(g+356>e.l+e.w){g=Math.max(0,g-356)}if(c.data("colorpicker").onShow.apply(this,[c.get(0)])!=false){c.show()}a(document).bind("mousedown",{cal:c},G);return false},G=function(b){if(!H(b.data.cal.get(0),b.target,b.data.cal.get(0))){if(b.data.cal.data("colorpicker").onHide.apply(this,[b.data.cal.get(0)])!=false){b.data.cal.hide()}a(document).unbind("mousedown",G)}},H=function(a,b,c){if(a==b){return true}if(a.contains){return a.contains(b)}if(a.compareDocumentPosition){return!!(a.compareDocumentPosition(b)&16)}var d=b.parentNode;while(d&&d!=c){if(d==a)return true;d=d.parentNode}return false},I=function(){var a=document.compatMode=="CSS1Compat";return{l:window.pageXOffset||(a?document.documentElement.scrollLeft:document.body.scrollLeft),t:window.pageYOffset||(a?document.documentElement.scrollTop:document.body.scrollTop),w:window.innerWidth||(a?document.documentElement.clientWidth:document.body.clientWidth),h:window.innerHeight||(a?document.documentElement.clientHeight:document.body.clientHeight)}},J=function(a){return{h:Math.round(Math.min(360,Math.max(0,a.h))),s:Math.round(Math.min(100,Math.max(0,a.s))),b:Math.round(Math.min(100,Math.max(0,a.b)))}},K=function(a){return{r:Math.min(255,Math.max(0,a.r)),g:Math.min(255,Math.max(0,a.g)),b:Math.min(255,Math.max(0,a.b))}},L=function(a){var b=6-a.length;if(b>0){var c=[];for(var d=0;d<b;d++){c.push("0")}c.push(a);a=c.join("")}return a},M=function(a){var a=parseInt(a.indexOf("#")>-1?a.substring(1):a,16);return{r:a>>16,g:(a&65280)>>8,b:a&255}},N=function(a){return O(M(a))},O=function(a){var b={h:0,s:0,b:0};var c=Math.min(a.r,a.g,a.b);var d=Math.max(a.r,a.g,a.b);var e=d-c;b.b=d;if(d!=0){}b.s=d!=0?255*e/d:0;if(b.s!=0){if(a.r==d){b.h=(a.g-a.b)/e}else if(a.g==d){b.h=2+(a.b-a.r)/e}else{b.h=4+(a.r-a.g)/e}}else{b.h=-1}b.h*=60;if(b.h<0){b.h+=360}b.s*=100/255;b.b*=100/255;b.h=Math.round(b.h);b.s=Math.round(b.s);b.b=Math.round(b.b);return b},P=function(a){var b={};var c=Math.round(a.h);var d=Math.round(a.s*255/100);var e=Math.round(a.b*255/100);if(d==0){b.r=b.g=b.b=e}else{var f=e;var g=(255-d)*e/255;var h=(f-g)*(c%60)/60;if(c==360)c=0;if(c<60){b.r=f;b.b=g;b.g=g+h}else if(c<120){b.g=f;b.b=g;b.r=f-h}else if(c<180){b.g=f;b.r=g;b.b=g+h}else if(c<240){b.b=f;b.r=g;b.g=f-h}else if(c<300){b.b=f;b.g=g;b.r=g+h}else if(c<360){b.r=f;b.g=g;b.b=f-h}else{b.r=0;b.g=0;b.b=0}}return{r:Math.round(b.r),g:Math.round(b.g),b:Math.round(b.b)}},Q=function(b){var c=[b.r.toString(16),b.g.toString(16),b.b.toString(16)];a.each(c,function(a,b){if(b.length==1){c[a]="0"+b}});return c.join("")},R=function(a){return Q(P(a))},S=function(){var b=a(this).parent();var c=b.data("colorpicker").origColor;b.data("colorpicker").color=c;h(c,b.get(0));j(c,b.get(0));i(c,b.get(0));k(c,b.get(0));l(c,b.get(0));n(c,b.get(0))};return{init:function(b){b=a.extend({},g,b||{});if(typeof b.color=="string"){b.color=N(b.color)}else if(b.color.r!=undefined&&b.color.g!=undefined&&b.color.b!=undefined){b.color=O(b.color)}else if(b.color.h!=undefined&&b.color.s!=undefined&&b.color.b!=undefined){b.color=J(b.color)}else{return this}return this.each(function(){if(!a(this).data("colorpickerId")){var c=a.extend({},b);c.origColor=b.color;var d="collorpicker_"+parseInt(Math.random()*1e3);a(this).data("colorpickerId",d);var e=a(f).attr("id",d);if(c.flat){e.appendTo(this).show()}else{e.appendTo(this)}c.fields=e.find("input").bind("keyup",o).bind("change",p).bind("blur",q).bind("focus",r);e.find("span").bind("mousedown touchstart",s).end().find(">div.colorpicker_current_color").bind("click",S);c.selector=e.find("div.colorpicker_color").bind("touchstart mousedown",y);c.selectorIndic=c.selector.find("div div");c.el=this;c.hue=e.find("div.colorpicker_hue div");e.find("div.colorpicker_hue").bind("mousedown touchstart",v);c.newColor=e.find("div.colorpicker_new_color");c.currentColor=e.find("div.colorpicker_current_color");e.data("colorpicker",c);e.find("div.colorpicker_submit").bind("mouseenter touchstart",B).bind("mouseleave touchend",C).bind("click",D);h(c.color,e.get(0));i(c.color,e.get(0));j(c.color,e.get(0));l(c.color,e.get(0));k(c.color,e.get(0));m(c.color,e.get(0));n(c.color,e.get(0));if(c.flat){e.css({position:"relative",display:"block"})}else{a(this).bind(c.eventName,E)}}})},showPicker:function(){return this.each(function(){if(a(this).data("colorpickerId")){F.apply(this)}})},hidePicker:function(){return this.each(function(){if(a(this).data("colorpickerId")){a("#"+a(this).data("colorpickerId")).hide()}})},setColor:function(b){if(typeof b=="string"){b=N(b)}else if(b.r!=undefined&&b.g!=undefined&&b.b!=undefined){b=O(b)}else if(b.h!=undefined&&b.s!=undefined&&b.b!=undefined){b=J(b)}else{return this}return this.each(function(){if(a(this).data("colorpickerId")){var c=a("#"+a(this).data("colorpickerId"));c.data("colorpicker").color=b;c.data("colorpicker").origColor=b;h(b,c.get(0));i(b,c.get(0));j(b,c.get(0));l(b,c.get(0));k(b,c.get(0));m(b,c.get(0));n(b,c.get(0))}})}}}();a.fn.extend({ColorPicker:b.init,ColorPickerHide:b.hidePicker,ColorPickerShow:b.showPicker,ColorPickerSetColor:b.setColor})})(jQuery)
\ No newline at end of file
diff --git a/resources/js/displayserv.js b/resources/js/displayserv.js
new file mode 100644
index 0000000..5f37bf1
--- /dev/null
+++ b/resources/js/displayserv.js
@@ -0,0 +1,193 @@
+(function($){
+	$.fn.displayServ = function(options){
+		var selector = $(this);
+		
+		// Options
+		var settings = {
+			config: 'config/servers.cfg.php',
+			resources: 'resources/',
+			timeout: 3,
+			refresh: 30,
+			color: '',
+			links: {
+				join: true,
+				spectate: true,
+				addfavourite: false
+			}
+		}
+		$.extend(settings, options);
+		settings.refresh = parseInt(settings.refresh * 1000);
+		if(settings.refresh < 10000){
+			settings.refresh = 10000;
+		}
+		if(settings.color){
+			settings.color = ' style="color: '+settings.color+';"';
+		}
+		
+		// Refresh
+		selector.initialize(settings);
+		setInterval(function(){
+			selector.initialize(settings);
+		}, settings.refresh);
+	};
+})(jQuery);
+
+(function($){
+	$.fn.initialize = function(settings){
+		var selector = $(this);
+		
+		// 1ère étape - Initialiser DisplayServ en créant le html
+		$.getJSON(settings.resources+'ajax/ds_initialize.php', {cfg: settings.config}, function(data){
+			if(data != null){
+				var out = '<ul class="ds-servers-list loading">';
+					if(data.servers){
+						for(var i = 0; i < data.servers; i++){
+							out += '<li id="ds-server-'+i+'" class="ds-server">'
+								+ '<table>'
+									+ '<tr class="ds-header">'
+										+ '<th class="first"'+settings.color+'>'+data.label.server+' n°'+(i+1)+'</th>'
+										+ '<th class="middle"></th>'
+										+ '<th class="last"'+settings.color+'>'+data.label.players+'</th>'
+									+ '</tr>'
+									+ '<tr class="ds-space"><td colspan="3"></td></tr>'
+									+ '<tr class="ds-content">'
+										+ '<td class="ds-part-left">'
+											+ '<ul>'
+												+ '<li>'+data.label.name+'</li>'
+												+ '<li>'+data.label.login+'</li>'
+												+ '<li>'+data.label.connect+'</li>'
+												+ '<li>'+data.label.status+'</li>'
+												+ '<li>'+data.label.gamemode+'</li>'
+												+ '<li>'+data.label.currentmap+'</li>'
+												+ '<li>'+data.label.players+'</li>'
+											+ '</ul>'
+										+ '</td>'
+										+ '<td class="ds-part-middle">'
+											+ '<ul>'
+												+ '<li class="ds-server-name"></li>'
+												+ '<li class="ds-server-login"></li>'
+												+ '<li class="ds-server-connect"></li>'
+												+ '<li class="ds-server-protocol"></li>'
+												+ '<li class="ds-server-status"></li>'
+												+ '<li class="ds-server-gamemode"></li>'
+												+ '<li class="ds-server-currentmap"></li>'
+												+ '<li class="ds-server-players-count"></li>'
+											+ '</ul>'
+										+ '</td>'
+										+ '<td class="ds-part-right">'
+											+ '<div class="ds-servers-players-list"></div>'
+										+ '</td>'
+									+ '</tr>'
+								+ '</table>'
+								+ '<div class="ds-server-join-wrap">'
+										+ '<ul>';
+											if(settings.links.addfavourite){
+												out += '<li class="ds-server-favourite"><a href=".">'+data.label.addfavourite+'</a></li>';
+											}
+											if(settings.links.spectate){
+												out += '<li class="ds-server-spectate"><a href=".">'+data.label.accessserverspectate+'</a></li>';
+											}
+											if(settings.links.join){
+												out += '<li class="ds-server-join"><a href=".">'+data.label.accessserverplayer+'</a></li>';
+											}
+										out += '</ul>'
+								+ '</div>'
+							+ '</li>';
+						}
+					}
+				out += '</ul>';
+				
+				// Affichage
+				selector.find('.ds-servers-list').remove();
+				selector.html(out);
+				
+				// Calcul de la taille max
+				var maxsize = selector.find('.ds-servers-list').width();
+				if(maxsize < 380){
+					selector.find('.ds-servers-list').addClass("max-width-380");
+					if(settings.links.addfavourite){
+						selector.find('.ds-servers-list .ds-server-favourite').remove();
+					}
+					if(settings.links.spectate){
+						selector.find('.ds-servers-list .ds-server-spectate').remove();
+					}
+				}
+				else if(maxsize < 580){
+					selector.find('.ds-servers-list').addClass('max-width-580');
+					if(settings.links.addfavourite){
+						selector.find('.ds-servers-list .ds-server-favourite').remove();
+					}
+				}
+				
+				// 2ème étape - Récupérer les données serveur
+				$.getJSON(settings.resources+'ajax/ds_getservers.php', {cfg: settings.config, rsc: settings.resources}, function(data){
+					if(data != null){
+						if(data.servers){
+							for(var i = 0; i < data.servers.length; i++){
+								var serverId = $('#ds-server-'+i);
+								
+								// Server infos
+								if(data.servers[i].error){
+									serverId.find('.ds-server-name').html(data.servers[i].error);
+									serverId.find('.ds-server-join-wrap').remove();
+								}
+								else{
+									serverId.find('.ds-server-name').html(data.servers[i].name);
+									serverId.find('.ds-server-login').html(data.servers[i].serverlogin);
+									serverId.find('.ds-server-connect').html(data.servers[i].version.name);
+									serverId.find('.ds-server-connect').addClass(data.servers[i].version.name.toLowerCase());
+									serverId.find('.ds-server-status').html(data.servers[i].status);
+									serverId.find('.ds-server-gamemode').html(data.servers[i].gamemode);
+									serverId.find('.ds-server-gamemode').addClass(data.servers[i].gamemode.toLowerCase());
+									var envImg = '';
+									if(data.servers[i].map.env.filename != null){
+										var envImg = ' <img src="'+data.servers[i].map.env.filename+'" alt="('+data.servers[i].map.env.name+')" title="'+data.servers[i].map.env.name+'" />';
+									}
+									serverId.find('.ds-server-currentmap').html(data.servers[i].map.name + envImg);
+									serverId.find('.ds-server-players-count').html(data.players[i].count.current+' / '+data.players[i].count.max);
+									
+									// Join
+									var title = '';
+									if(data.servers[i].version.title){
+										title += '@'+data.servers[i].version.title;
+									}
+									if(settings.links.join){
+										serverId.find('.ds-server-join a').attr('href', data.servers[i].version.protocol+'://#join='+data.servers[i].serverlogin+title);
+									}
+									if(settings.links.spectate){
+										serverId.find('.ds-server-spectate a').attr('href', data.servers[i].version.protocol+'://#spectate='+data.servers[i].serverlogin+title);
+									}
+									if(settings.links.addfavourite){
+										serverId.find('.ds-server-favourite a').attr('href', data.servers[i].version.protocol+'://#addfavourite='+data.servers[i].serverlogin+title);
+									}
+									
+									// Players
+									var playerListTable = '<table>';
+										if(data.players[i].count.current > 0){
+											$.each(data.players[i].list, function(idPlayer, dataPlayer){
+												var teamSpan = '';
+												if(data.servers[i].gamemode == 'Team'){
+													teamSpan = '<span class="team_'+dataPlayer.teamId+'" title="'+dataPlayer.teamName+'">&nbsp;</span>';
+												}
+												playerListTable += '<tr>'
+													+ '<td>'+teamSpan+dataPlayer.name+'</td>'
+													+ '<td>'+dataPlayer.status+'</td>'
+												+ '</tr>';
+											});
+										}
+										else{
+											playerListTable += '<td class="no-player" colspan="2">'+data.players[i].list+'</td>';
+										}
+									playerListTable += '</table>';
+									serverId.find('.ds-servers-players-list').html(playerListTable);
+								}
+							}
+						}
+						
+						selector.find('.ds-servers-list').removeClass('loading');
+					}
+				});
+			}
+		});
+	};
+})(jQuery);
\ No newline at end of file
diff --git a/resources/js/fileuploader.js b/resources/js/fileuploader.js
new file mode 100644
index 0000000..a7ccde3
--- /dev/null
+++ b/resources/js/fileuploader.js
@@ -0,0 +1,16 @@
+/**
+ * http://github.com/Valums-File-Uploader/file-uploader
+ *
+ * Multiple file upload component with progress-bar, drag-and-drop.
+ *
+ * Have ideas for improving this JS for the general community?
+ * Submit your changes at: https://github.com/Valums-File-Uploader/file-uploader
+ * Readme at https://github.com/valums/file-uploader/blob/2.0/readme.md
+ *
+ * VERSION 2.1-SNAPSHOT
+ * Original version: 1.0 © 2010 Andrew Valums ( andrew(at)valums.com )
+ * Current Maintainer (2.0+): © 2012, Ray Nicholus ( fineuploader(at)garstasio.com )
+ *
+ * Licensed under MIT license, GNU GPL 2 or later, GNU LGPL 2 or later, see license.txt.
+ */
+var qq=qq||{};qq.extend=function(a,b){for(var c in b){a[c]=b[c]}};qq.indexOf=function(a,b,c){if(a.indexOf)return a.indexOf(b,c);c=c||0;var d=a.length;if(c<0)c+=d;for(;c<d;c++){if(c in a&&a[c]===b){return c}}return-1};qq.getUniqueId=function(){var a=0;return function(){return a++}}();qq.ie=function(){return navigator.userAgent.indexOf("MSIE")!=-1};qq.safari=function(){return navigator.vendor!=undefined&&navigator.vendor.indexOf("Apple")!=-1};qq.chrome=function(){return navigator.vendor!=undefined&&navigator.vendor.indexOf("Google")!=-1};qq.firefox=function(){return navigator.userAgent.indexOf("Mozilla")!=-1&&navigator.vendor!=undefined&&navigator.vendor==""};qq.windows=function(){return navigator.platform=="Win32"};qq.attach=function(a,b,c){if(a.addEventListener){a.addEventListener(b,c,false)}else if(a.attachEvent){a.attachEvent("on"+b,c)}return function(){qq.detach(a,b,c)}};qq.detach=function(a,b,c){if(a.removeEventListener){a.removeEventListener(b,c,false)}else if(a.attachEvent){a.detachEvent("on"+b,c)}};qq.preventDefault=function(a){if(a.preventDefault){a.preventDefault()}else{a.returnValue=false}};qq.insertBefore=function(a,b){b.parentNode.insertBefore(a,b)};qq.remove=function(a){a.parentNode.removeChild(a)};qq.contains=function(a,b){if(a==b)return true;if(a.contains){return a.contains(b)}else{return!!(b.compareDocumentPosition(a)&8)}};qq.toElement=function(){var a=document.createElement("div");return function(b){a.innerHTML=b;var c=a.firstChild;a.removeChild(c);return c}}();qq.css=function(a,b){if(b.opacity!=null){if(typeof a.style.opacity!="string"&&typeof a.filters!="undefined"){b.filter="alpha(opacity="+Math.round(100*b.opacity)+")"}}qq.extend(a.style,b)};qq.hasClass=function(a,b){var c=new RegExp("(^| )"+b+"( |$)");return c.test(a.className)};qq.addClass=function(a,b){if(!qq.hasClass(a,b)){a.className+=" "+b}};qq.removeClass=function(a,b){var c=new RegExp("(^| )"+b+"( |$)");a.className=a.className.replace(c," ").replace(/^\s+|\s+$/g,"")};qq.setText=function(a,b){a.innerText=b;a.textContent=b};qq.children=function(a){var b=[],c=a.firstChild;while(c){if(c.nodeType==1){b.push(c)}c=c.nextSibling}return b};qq.getByClass=function(a,b){if(a.querySelectorAll){return a.querySelectorAll("."+b)}var c=[];var d=a.getElementsByTagName("*");var e=d.length;for(var f=0;f<e;f++){if(qq.hasClass(d[f],b)){c.push(d[f])}}return c};qq.obj2url=function(a,b,c){var d=[],e="&",f=function(a,c){var e=b?/\[\]$/.test(b)?b:b+"["+c+"]":c;if(e!="undefined"&&c!="undefined"){d.push(typeof a==="object"?qq.obj2url(a,e,true):Object.prototype.toString.call(a)==="[object Function]"?encodeURIComponent(e)+"="+encodeURIComponent(a()):encodeURIComponent(e)+"="+encodeURIComponent(a))}};if(!c&&b){e=/\?/.test(b)?/\?$/.test(b)?"":"&":"?";d.push(b);d.push(qq.obj2url(a))}else if(Object.prototype.toString.call(a)==="[object Array]"&&typeof a!="undefined"){for(var g=0,h=a.length;g<h;++g){f(a[g],g)}}else if(typeof a!="undefined"&&a!==null&&typeof a==="object"){for(var g in a){f(a[g],g)}}else{d.push(encodeURIComponent(b)+"="+encodeURIComponent(a))}return d.join(e).replace(/^&/,"").replace(/%20/g,"+")};var qq=qq||{};qq.FileUploaderBasic=function(a){var b=this;this._options={debug:false,action:"/server/upload",params:{},customHeaders:{},button:null,multiple:true,maxConnections:3,disableCancelForFormUploads:false,autoUpload:true,allowedExtensions:[],acceptFiles:null,sizeLimit:0,minSizeLimit:0,onSubmit:function(a,b){},onComplete:function(a,b,c){},onCancel:function(a,b){},onUpload:function(a,b,c){},onProgress:function(a,b,c,d){},onError:function(a,b,c){},messages:{typeError:"{file} has an invalid extension. Only {extensions} {isAre} allowed.",sizeError:"{file} is too large, maximum file size is {sizeLimit}.",minSizeError:"{file} is too small, minimum file size is {minSizeLimit}.",emptyError:"{file} is empty, please select files again without it.",noFilesError:"No files to upload.",onLeave:"The files are being uploaded, if you leave now the upload will be cancelled."},showMessage:function(a){alert(a)},inputName:"qqfile"};qq.extend(this._options,a);qq.extend(this,qq.DisposeSupport);this._filesInProgress=0;this._storedFileIds=[];this._handler=this._createUploadHandler();if(this._options.button){this._button=this._createUploadButton(this._options.button)}this._preventLeaveInProgress()};qq.FileUploaderBasic.prototype={setParams:function(a){this._options.params=a},getInProgress:function(){return this._filesInProgress},uploadStoredFiles:function(){for(var a=0;a<this._storedFileIds.length;a++){this._filesInProgress++;this._handler.upload(this._storedFileIds[a],this._options.params)}},clearStoredFiles:function(){this._storedFileIds=[]},_createUploadButton:function(a){var b=this;var c=new qq.UploadButton({element:a,multiple:this._options.multiple&&qq.UploadHandlerXhr.isSupported(),acceptFiles:this._options.acceptFiles,onChange:function(a){b._onInputChange(a)}});this.addDisposer(function(){c.dispose()});return c},_createUploadHandler:function(){var a=this,b;if(qq.UploadHandlerXhr.isSupported()){b="UploadHandlerXhr"}else{b="UploadHandlerForm"}var c=new qq[b]({debug:this._options.debug,action:this._options.action,encoding:this._options.encoding,maxConnections:this._options.maxConnections,customHeaders:this._options.customHeaders,inputName:this._options.inputName,demoMode:this._options.demoMode,onProgress:function(b,c,d,e){a._onProgress(b,c,d,e);a._options.onProgress(b,c,d,e)},onComplete:function(b,c,d){a._onComplete(b,c,d);a._options.onComplete(b,c,d)},onCancel:function(b,c){var d=qq.indexOf(a._storedFileIds,b);if(d>=0){a._storedFileIds.splice(d,1)}a._onCancel(b,c);a._options.onCancel(b,c)},onError:a._options.onError,onUpload:function(b,c,d){a._onUpload(b,c,d);a._options.onUpload(b,c,d)}});return c},_preventLeaveInProgress:function(){var a=this;this._attach(window,"beforeunload",function(b){if(!a._filesInProgress){return}var b=b||window.event;b.returnValue=a._options.messages.onLeave;return a._options.messages.onLeave})},_onSubmit:function(a,b){if(this._options.autoUpload){this._filesInProgress++}},_onProgress:function(a,b,c,d){},_onComplete:function(a,b,c){var d=qq.indexOf(this._storedFileIds,a);if(d>=0){this._storedFileIds.splice(d,1)}this._filesInProgress--;if(c.error){this._options.showMessage(c.error)}},_onCancel:function(a,b){if(this._options.autoUpload){this._filesInProgress--}},_onUpload:function(a,b,c){},_onInputChange:function(a){if(this._handler instanceof qq.UploadHandlerXhr){this._uploadFileList(a.files)}else{if(this._validateFile(a)){this._uploadFile(a)}}this._button.reset()},_uploadFileList:function(a){if(a.length>0){for(var b=0;b<a.length;b++){if(!this._validateFile(a[b])){return}}for(var b=0;b<a.length;b++){this._uploadFile(a[b])}}else{this._error("noFilesError","")}},_uploadFile:function(a){var b=this._handler.add(a);var c=this._handler.getName(b);if(this._options.onSubmit(b,c)!==false){this._onSubmit(b,c);if(this._options.autoUpload){this._handler.upload(b,this._options.params)}else{this._storeFileForLater(b)}}},_storeFileForLater:function(a){this._storedFileIds.push(a)},_validateFile:function(a){var b,c;if(a.value){b=a.value.replace(/.*(\/|\\)/,"")}else{b=a.fileName!==null&&a.fileName!==undefined?a.fileName:a.name;c=a.fileSize!==null&&a.fileSize!==undefined?a.fileSize:a.size}if(!this._isAllowedExtension(b)){this._error("typeError",b);return false}else if(c===0){this._error("emptyError",b);return false}else if(c&&this._options.sizeLimit&&c>this._options.sizeLimit){this._error("sizeError",b);return false}else if(c&&c<this._options.minSizeLimit){this._error("minSizeError",b);return false}return true},_error:function(a,b){function d(a,b){c=c.replace(a,b)}var c=this._options.messages[a];var e=this._options.allowedExtensions.join(", ");d("{file}",this._formatFileName(b));d("{extensions}",e);d("{sizeLimit}",this._formatSize(this._options.sizeLimit));d("{minSizeLimit}",this._formatSize(this._options.minSizeLimit));d("{isAre}",e.indexOf(",")!=-1?"are":"is");this._options.showMessage(c)},_formatFileName:function(a){if(a.length>33){a=a.slice(0,19)+"..."+a.slice(-13)}return a},_isAllowedExtension:function(a){var b=-1!==a.indexOf(".")?a.replace(/.*[.]/,"").toLowerCase():"";var c=this._options.allowedExtensions;if(!c.length){return true}for(var d=0;d<c.length;d++){if(c[d].toLowerCase()==b){return true}}return false},_formatSize:function(a){var b=-1;do{a=a/1024;b++}while(a>99);return Math.max(a,.1).toFixed(1)+["kB","MB","GB","TB","PB","EB"][b]}};qq.FileUploader=function(a){qq.FileUploaderBasic.apply(this,arguments);qq.extend(this._options,{element:null,listElement:null,dragText:"Drop files here to upload",extraDropzones:[],uploadButtonText:"Upload a file",cancelButtonText:"Cancel",failUploadText:"Upload failed",template:'<div class="qq-uploader">'+'<div class="qq-upload-drop-area"><span>{dragText}</span></div>'+'<div class="qq-upload-button">{uploadButtonText}</div>'+(!this._options.listElement?'<ul class="qq-upload-list"></ul>':"")+"</div>",fileTemplate:"<li>"+'<span class="qq-progress-bar"></span>'+'<span class="qq-upload-spinner"></span>'+'<span class="qq-upload-finished"></span>'+'<span class="qq-upload-file"></span>'+'<span class="qq-upload-size"></span>'+'<a class="qq-upload-cancel" href="#">{cancelButtonText}</a>'+'<span class="qq-upload-failed-text">{failUploadtext}</span>'+"</li>",classes:{button:"qq-upload-button",drop:"qq-upload-drop-area",dropActive:"qq-upload-drop-area-active",dropDisabled:"qq-upload-drop-area-disabled",list:"qq-upload-list",progressBar:"qq-progress-bar",file:"qq-upload-file",spinner:"qq-upload-spinner",finished:"qq-upload-finished",size:"qq-upload-size",cancel:"qq-upload-cancel",success:"qq-upload-success",fail:"qq-upload-fail",successIcon:null,failIcon:null},extraMessages:{formatProgress:"{percent}% of {total_size}",tooManyFilesError:"You may only drop one file"}});qq.extend(this._options,a);qq.extend(this._options.messages,this._options.extraMessages);this._options.template=this._options.template.replace(/\{dragText\}/g,this._options.dragText);this._options.template=this._options.template.replace(/\{uploadButtonText\}/g,this._options.uploadButtonText);this._options.fileTemplate=this._options.fileTemplate.replace(/\{cancelButtonText\}/g,this._options.cancelButtonText);this._options.fileTemplate=this._options.fileTemplate.replace(/\{failUploadtext\}/g,this._options.failUploadText);this._element=this._options.element;this._element.innerHTML=this._options.template;this._listElement=this._options.listElement||this._find(this._element,"list");this._classes=this._options.classes;this._button=this._createUploadButton(this._find(this._element,"button"));this._bindCancelEvent();this._setupDragDrop()};qq.extend(qq.FileUploader.prototype,qq.FileUploaderBasic.prototype);qq.extend(qq.FileUploader.prototype,{clearStoredFiles:function(){qq.FileUploaderBasic.prototype.clearStoredFiles.apply(this,arguments);this._listElement.innerHTML=""},addExtraDropzone:function(a){this._setupExtraDropzone(a)},removeExtraDropzone:function(a){var b=this._options.extraDropzones;for(var c in b)if(b[c]===a)return this._options.extraDropzones.splice(c,1)},_leaving_document_out:function(a){return(qq.chrome()||qq.safari()&&qq.windows())&&a.clientX==0&&a.clientY==0||qq.firefox()&&!a.relatedTarget},_storeFileForLater:function(a){qq.FileUploaderBasic.prototype._storeFileForLater.apply(this,arguments);var b=this._getItemByFileId(a);this._find(b,"spinner").style.display="none"},_find:function(a,b){var c=qq.getByClass(a,this._options.classes[b])[0];if(!c){throw new Error("element not found "+b)}return c},_setupExtraDropzone:function(a){this._options.extraDropzones.push(a);this._setupDropzone(a)},_setupDropzone:function(a){var b=this;var c=new qq.UploadDropZone({element:a,onEnter:function(c){qq.addClass(a,b._classes.dropActive);c.stopPropagation()},onLeave:function(a){},onLeaveNotDescendants:function(c){qq.removeClass(a,b._classes.dropActive)},onDrop:function(c){a.style.display="none";qq.removeClass(a,b._classes.dropActive);if(c.dataTransfer.files.length>1&&!b._options.multiple){b._error("tooManyFilesError","")}else{b._uploadFileList(c.dataTransfer.files)}}});this.addDisposer(function(){c.dispose()});a.style.display="none"},_setupDragDrop:function(){var a=this._find(this._element,"drop");var b=this;this._options.extraDropzones.push(a);var c=this._options.extraDropzones;var d;for(d=0;d<c.length;d++){this._setupDropzone(c[d])}if(!qq.ie()){this._attach(document,"dragenter",function(e){if(qq.hasClass(a,b._classes.dropDisabled))return;a.style.display="block";for(d=0;d<c.length;d++){c[d].style.display="block"}})}this._attach(document,"dragleave",function(a){var b=document.elementFromPoint(a.clientX,a.clientY);if(qq.FileUploader.prototype._leaving_document_out(a)){for(d=0;d<c.length;d++){c[d].style.display="none"}}});qq.attach(document,"drop",function(a){for(d=0;d<c.length;d++){c[d].style.display="none"}a.preventDefault()})},_onSubmit:function(a,b){qq.FileUploaderBasic.prototype._onSubmit.apply(this,arguments);this._addToList(a,b)},_onProgress:function(a,b,c,d){qq.FileUploaderBasic.prototype._onProgress.apply(this,arguments);var e=this._getItemByFileId(a);if(c===d){var f=this._find(e,"cancel");f.style.display="none"}var g=this._find(e,"size");g.style.display="inline";var h;var i=Math.round(c/d*100);if(c!=d){h=this._formatProgress(c,d)}else{h=this._formatSize(d)}this._find(e,"progressBar").style.width=i+"%";qq.setText(g,h)},_onComplete:function(a,b,c){qq.FileUploaderBasic.prototype._onComplete.apply(this,arguments);var d=this._getItemByFileId(a);if(!this._options.disableCancelForFormUploads||qq.UploadHandlerXhr.isSupported()){qq.remove(this._find(d,"cancel"))}qq.remove(this._find(d,"spinner"));if(c.success){qq.addClass(d,this._classes.success);if(this._classes.successIcon){this._find(d,"finished").style.display="inline-block";qq.addClass(d,this._classes.successIcon)}}else{var e=c.reason?c.reason:"Unknown error";qq.addClass(d,this._classes.fail);if(this._classes.failIcon){this._find(d,"finished").style.display="inline-block";qq.addClass(d,this._classes.failIcon)}d.title=e}},_onUpload:function(a,b,c){qq.FileUploaderBasic.prototype._onUpload.apply(this,arguments);var d=this._getItemByFileId(a);var e=this._find(d,"spinner");if(e.style.display=="none"){e.style.display="inline-block"}},_addToList:function(a,b){var c=qq.toElement(this._options.fileTemplate);if(this._options.disableCancelForFormUploads&&!qq.UploadHandlerXhr.isSupported()){var d=this._find(c,"cancel");qq.remove(d)}c.qqFileId=a;var e=this._find(c,"file");qq.setText(e,this._formatFileName(b));this._find(c,"size").style.display="none";if(!this._options.multiple)this._clearList();this._listElement.appendChild(c)},_clearList:function(){this._listElement.innerHTML="";this.clearStoredFiles()},_getItemByFileId:function(a){var b=this._listElement.firstChild;while(b){if(b.qqFileId==a)return b;b=b.nextSibling}},_bindCancelEvent:function(){var a=this,b=this._listElement;this._attach(b,"click",function(b){b=b||window.event;var c=b.target||b.srcElement;if(qq.hasClass(c,a._classes.cancel)){qq.preventDefault(b);var d=c.parentNode;a._handler.cancel(d.qqFileId);qq.remove(d)}})},_formatProgress:function(a,b){function d(a,b){c=c.replace(a,b)}var c=this._options.messages.formatProgress;d("{percent}",Math.round(a/b*100));d("{total_size}",this._formatSize(b));return c}});qq.UploadDropZone=function(a){this._options={element:null,onEnter:function(a){},onLeave:function(a){},onLeaveNotDescendants:function(a){},onDrop:function(a){}};qq.extend(this._options,a);qq.extend(this,qq.DisposeSupport);this._element=this._options.element;this._disableDropOutside();this._attachEvents()};qq.UploadDropZone.prototype={_dragover_should_be_canceled:function(){return qq.safari()||qq.firefox()&&qq.windows()},_disableDropOutside:function(a){if(!qq.UploadDropZone.dropOutsideDisabled){if(this._dragover_should_be_canceled){qq.attach(document,"dragover",function(a){a.preventDefault()})}else{qq.attach(document,"dragover",function(a){if(a.dataTransfer){a.dataTransfer.dropEffect="none";a.preventDefault()}})}qq.UploadDropZone.dropOutsideDisabled=true}},_attachEvents:function(){var a=this;a._attach(a._element,"dragover",function(b){if(!a._isValidFileDrag(b))return;var c=qq.ie()?null:b.dataTransfer.effectAllowed;if(c=="move"||c=="linkMove"){b.dataTransfer.dropEffect="move"}else{b.dataTransfer.dropEffect="copy"}b.stopPropagation();b.preventDefault()});a._attach(a._element,"dragenter",function(b){if(!a._isValidFileDrag(b))return;a._options.onEnter(b)});a._attach(a._element,"dragleave",function(b){if(!a._isValidFileDrag(b))return;a._options.onLeave(b);var c=document.elementFromPoint(b.clientX,b.clientY);if(qq.contains(this,c))return;a._options.onLeaveNotDescendants(b)});a._attach(a._element,"drop",function(b){if(!a._isValidFileDrag(b))return;b.preventDefault();a._options.onDrop(b)})},_isValidFileDrag:function(a){if(qq.ie())return false;var b=a.dataTransfer,c=qq.safari();return b&&b.effectAllowed!="none"&&(b.files||!c&&b.types.contains&&b.types.contains("Files"))}};qq.UploadButton=function(a){this._options={element:null,multiple:false,acceptFiles:null,name:"file",onChange:function(a){},hoverClass:"qq-upload-button-hover",focusClass:"qq-upload-button-focus"};qq.extend(this._options,a);qq.extend(this,qq.DisposeSupport);this._element=this._options.element;qq.css(this._element,{position:"relative",overflow:"hidden",direction:"ltr"});this._input=this._createInput()};qq.UploadButton.prototype={getInput:function(){return this._input},reset:function(){if(this._input.parentNode){qq.remove(this._input)}qq.removeClass(this._element,this._options.focusClass);this._input=this._createInput()},_createInput:function(){var a=document.createElement("input");if(this._options.multiple){a.setAttribute("multiple","multiple")}if(this._options.acceptFiles)a.setAttribute("accept",this._options.acceptFiles);a.setAttribute("type","file");a.setAttribute("name",this._options.name);qq.css(a,{position:"absolute",right:0,top:0,fontFamily:"Arial",fontSize:"118px",margin:0,padding:0,cursor:"pointer",opacity:0});this._element.appendChild(a);var b=this;this._attach(a,"change",function(){b._options.onChange(a)});this._attach(a,"mouseover",function(){qq.addClass(b._element,b._options.hoverClass)});this._attach(a,"mouseout",function(){qq.removeClass(b._element,b._options.hoverClass)});this._attach(a,"focus",function(){qq.addClass(b._element,b._options.focusClass)});this._attach(a,"blur",function(){qq.removeClass(b._element,b._options.focusClass)});if(window.attachEvent){a.setAttribute("tabIndex","-1")}return a}};qq.UploadHandlerAbstract=function(a){this._options={debug:false,action:"/upload.php",maxConnections:999,onProgress:function(a,b,c,d){},onComplete:function(a,b,c){},onCancel:function(a,b){},onUpload:function(a,b,c){}};qq.extend(this._options,a);this._queue=[];this._params=[]};qq.UploadHandlerAbstract.prototype={log:function(a){if(this._options.debug&&window.console)console.log("[uploader] "+a)},add:function(a){},upload:function(a,b){var c=this._queue.push(a);var d={};qq.extend(d,b);this._params[a]=d;if(c<=this._options.maxConnections){this._upload(a,this._params[a])}},cancel:function(a){this._cancel(a);this._dequeue(a)},cancelAll:function(){for(var a=0;a<this._queue.length;a++){this._cancel(this._queue[a])}this._queue=[]},getName:function(a){},getSize:function(a){},getQueue:function(){return this._queue},_upload:function(a){},_cancel:function(a){},_dequeue:function(a){var b=qq.indexOf(this._queue,a);this._queue.splice(b,1);var c=this._options.maxConnections;if(this._queue.length>=c&&b<c){var d=this._queue[c-1];this._upload(d,this._params[d])}}};qq.UploadHandlerForm=function(a){qq.UploadHandlerAbstract.apply(this,arguments);this._inputs={};this._detach_load_events={}};qq.extend(qq.UploadHandlerForm.prototype,qq.UploadHandlerAbstract.prototype);qq.extend(qq.UploadHandlerForm.prototype,{add:function(a){a.setAttribute("name",this._options.inputName);var b="qq-upload-handler-iframe"+qq.getUniqueId();this._inputs[b]=a;if(a.parentNode){qq.remove(a)}return b},getName:function(a){return this._inputs[a].value.replace(/.*(\/|\\)/,"")},_cancel:function(a){this._options.onCancel(a,this.getName(a));delete this._inputs[a];delete this._detach_load_events[a];var b=document.getElementById(a);if(b){b.setAttribute("src","javascript:false;");qq.remove(b)}},_upload:function(a,b){this._options.onUpload(a,this.getName(a),false);var c=this._inputs[a];if(!c){throw new Error("file with passed id was not added, or already uploaded or cancelled")}var d=this.getName(a);b[this._options.inputName]=d;var e=this._createIframe(a);var f=this._createForm(e,b);f.appendChild(c);var g=this;this._attachLoadEvent(e,function(){g.log("iframe loaded");var b=g._getIframeContentJSON(e);g._options.onComplete(a,d,b);g._dequeue(a);delete g._inputs[a];setTimeout(function(){g._detach_load_events[a]();delete g._detach_load_events[a];qq.remove(e)},1)});f.submit();qq.remove(f);return a},_attachLoadEvent:function(a,b){this._detach_load_events[a.id]=qq.attach(a,"load",function(){if(!a.parentNode){return}try{if(a.contentDocument&&a.contentDocument.body&&a.contentDocument.body.innerHTML=="false"){return}}catch(c){}b()})},_getIframeContentJSON:function(iframe){try{var doc=iframe.contentDocument?iframe.contentDocument:iframe.contentWindow.document,response;var innerHTML=doc.body.innerHTML;this.log("converting iframe's innerHTML to JSON");this.log("innerHTML = "+innerHTML);if(innerHTML.slice(0,5).toLowerCase()=="<pre>"&&innerHTML.slice(-6).toLowerCase()=="</pre>"){innerHTML=doc.body.firstChild.firstChild.nodeValue}response=eval("("+innerHTML+")")}catch(err){response={success:false}}return response},_createIframe:function(a){var b=qq.toElement('<iframe src="javascript:false;" name="'+a+'" />');b.setAttribute("id",a);b.style.display="none";document.body.appendChild(b);return b},_createForm:function(a,b){var c=this._options.demoMode?"GET":"POST";var d=qq.toElement('<form method="'+c+'" enctype="multipart/form-data"></form>');var e=qq.obj2url(b,this._options.action);d.setAttribute("action",e);d.setAttribute("target",a.name);d.style.display="none";document.body.appendChild(d);return d}});qq.UploadHandlerXhr=function(a){qq.UploadHandlerAbstract.apply(this,arguments);this._files=[];this._xhrs=[];this._loaded=[]};qq.UploadHandlerXhr.isSupported=function(){var a=document.createElement("input");a.type="file";return"multiple"in a&&typeof File!="undefined"&&typeof FormData!="undefined"&&typeof (new XMLHttpRequest).upload!="undefined"};qq.extend(qq.UploadHandlerXhr.prototype,qq.UploadHandlerAbstract.prototype);qq.extend(qq.UploadHandlerXhr.prototype,{add:function(a){if(!(a instanceof File)){throw new Error("Passed obj in not a File (in qq.UploadHandlerXhr)")}return this._files.push(a)-1},getName:function(a){var b=this._files[a];return b.fileName!==null&&b.fileName!==undefined?b.fileName:b.name},getSize:function(a){var b=this._files[a];return b.fileSize!=null?b.fileSize:b.size},getLoaded:function(a){return this._loaded[a]||0},_upload:function(a,b){this._options.onUpload(a,this.getName(a),true);var c=this._files[a],d=this.getName(a),e=this.getSize(a);this._loaded[a]=0;var f=this._xhrs[a]=new XMLHttpRequest;var g=this;f.upload.onprogress=function(b){if(b.lengthComputable){g._loaded[a]=b.loaded;g._options.onProgress(a,d,b.loaded,b.total)}};f.onreadystatechange=function(){if(f.readyState==4){g._onComplete(a,f)}};b=b||{};b[this._options.inputName]=d;var h=qq.obj2url(b,this._options.action);var i=this._options.demoMode?"GET":"POST";f.open(i,h,true);f.setRequestHeader("X-Requested-With","XMLHttpRequest");f.setRequestHeader("X-File-Name",encodeURIComponent(d));if(this._options.encoding=="multipart"){var j=new FormData;j.append(this._options.inputName,c);c=j}else{f.setRequestHeader("Content-Type","application/octet-stream");f.setRequestHeader("X-Mime-Type",c.type)}for(key in this._options.customHeaders){f.setRequestHeader(key,this._options.customHeaders[key])}f.send(c)},_onComplete:function(id,xhr){"use strict";if(!this._files[id]){return}var name=this.getName(id);var size=this.getSize(id);var response;this._options.onProgress(id,name,size,size);this.log("xhr - server response received");this.log("responseText = "+xhr.responseText);try{if(typeof JSON.parse==="function"){response=JSON.parse(xhr.responseText)}else{response=eval("("+xhr.responseText+")")}}catch(err){response={}}if(xhr.status!==200){this._options.onError(id,name,xhr)}this._options.onComplete(id,name,response);this._xhrs[id]=null;this._dequeue(id)},_cancel:function(a){this._options.onCancel(a,this.getName(a));this._files[a]=null;if(this._xhrs[a]){this._xhrs[a].abort();this._xhrs[a]=null}}});qq.DisposeSupport={_disposers:[],dispose:function(){var a;while(a=this._disposers.shift()){a()}},addDisposer:function(a){this._disposers.push(a)},_attach:function(){this.addDisposer(qq.attach.apply(this,arguments))}}
\ No newline at end of file
diff --git a/resources/js/jquery-ui.js b/resources/js/jquery-ui.js
new file mode 100644
index 0000000..82bbb67
--- /dev/null
+++ b/resources/js/jquery-ui.js
@@ -0,0 +1,12 @@
+/*! jQuery UI - v1.10.3 - 2013-05-03
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
+* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
+(function(t,e){function i(e,i){var n,o,a,r=e.nodeName.toLowerCase();return"area"===r?(n=e.parentNode,o=n.name,e.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap=#"+o+"]")[0],!!a&&s(a)):!1):(/input|select|textarea|button|object/.test(r)?!e.disabled:"a"===r?e.href||i:i)&&s(e)}function s(e){return t.expr.filters.visible(e)&&!t(e).parents().addBack().filter(function(){return"hidden"===t.css(this,"visibility")}).length}var n=0,o=/^ui-id-\d+$/;t.ui=t.ui||{},t.extend(t.ui,{version:"1.10.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),t.fn.extend({focus:function(e){return function(i,s){return"number"==typeof i?this.each(function(){var e=this;setTimeout(function(){t(e).focus(),s&&s.call(e)},i)}):e.apply(this,arguments)}}(t.fn.focus),scrollParent:function(){var e;return e=t.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(t.css(this,"position"))&&/(auto|scroll)/.test(t.css(this,"overflow")+t.css(this,"overflow-y")+t.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(t.css(this,"overflow")+t.css(this,"overflow-y")+t.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!e.length?t(document):e},zIndex:function(i){if(i!==e)return this.css("zIndex",i);if(this.length)for(var s,n,o=t(this[0]);o.length&&o[0]!==document;){if(s=o.css("position"),("absolute"===s||"relative"===s||"fixed"===s)&&(n=parseInt(o.css("zIndex"),10),!isNaN(n)&&0!==n))return n;o=o.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){o.test(this.id)&&t(this).removeAttr("id")})}}),t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])},focusable:function(e){return i(e,!isNaN(t.attr(e,"tabindex")))},tabbable:function(e){var s=t.attr(e,"tabindex"),n=isNaN(s);return(n||s>=0)&&i(e,!n)}}),t("<a>").outerWidth(1).jquery||t.each(["Width","Height"],function(i,s){function n(e,i,s,n){return t.each(o,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),n&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var o="Width"===s?["Left","Right"]:["Top","Bottom"],a=s.toLowerCase(),r={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+s]=function(i){return i===e?r["inner"+s].call(this):this.each(function(){t(this).css(a,n(this,i)+"px")})},t.fn["outer"+s]=function(e,i){return"number"!=typeof e?r["outer"+s].call(this,e):this.each(function(){t(this).css(a,n(this,e,!0,i)+"px")})}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(t.fn.removeData=function(e){return function(i){return arguments.length?e.call(this,t.camelCase(i)):e.call(this)}}(t.fn.removeData)),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),t.support.selectstart="onselectstart"in document.createElement("div"),t.fn.extend({disableSelection:function(){return this.bind((t.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(t){t.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),t.extend(t.ui,{plugin:{add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i){var s,n=t.plugins[e];if(n&&t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType)for(s=0;n.length>s;s++)t.options[n[s][0]]&&n[s][1].apply(t.element,i)}},hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)}})})(jQuery),function(t,e){var i=0,s=Array.prototype.slice,n=t.cleanData;t.cleanData=function(e){for(var i,s=0;null!=(i=e[s]);s++)try{t(i).triggerHandler("remove")}catch(o){}n(e)},t.widget=function(i,s,n){var o,a,r,h,l={},c=i.split(".")[0];i=i.split(".")[1],o=c+"-"+i,n||(n=s,s=t.Widget),t.expr[":"][o.toLowerCase()]=function(e){return!!t.data(e,o)},t[c]=t[c]||{},a=t[c][i],r=t[c][i]=function(t,i){return this._createWidget?(arguments.length&&this._createWidget(t,i),e):new r(t,i)},t.extend(r,a,{version:n.version,_proto:t.extend({},n),_childConstructors:[]}),h=new s,h.options=t.widget.extend({},h.options),t.each(n,function(i,n){return t.isFunction(n)?(l[i]=function(){var t=function(){return s.prototype[i].apply(this,arguments)},e=function(t){return s.prototype[i].apply(this,t)};return function(){var i,s=this._super,o=this._superApply;return this._super=t,this._superApply=e,i=n.apply(this,arguments),this._super=s,this._superApply=o,i}}(),e):(l[i]=n,e)}),r.prototype=t.widget.extend(h,{widgetEventPrefix:a?h.widgetEventPrefix:i},l,{constructor:r,namespace:c,widgetName:i,widgetFullName:o}),a?(t.each(a._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,r,i._proto)}),delete a._childConstructors):s._childConstructors.push(r),t.widget.bridge(i,r)},t.widget.extend=function(i){for(var n,o,a=s.call(arguments,1),r=0,h=a.length;h>r;r++)for(n in a[r])o=a[r][n],a[r].hasOwnProperty(n)&&o!==e&&(i[n]=t.isPlainObject(o)?t.isPlainObject(i[n])?t.widget.extend({},i[n],o):t.widget.extend({},o):o);return i},t.widget.bridge=function(i,n){var o=n.prototype.widgetFullName||i;t.fn[i]=function(a){var r="string"==typeof a,h=s.call(arguments,1),l=this;return a=!r&&h.length?t.widget.extend.apply(null,[a].concat(h)):a,r?this.each(function(){var s,n=t.data(this,o);return n?t.isFunction(n[a])&&"_"!==a.charAt(0)?(s=n[a].apply(n,h),s!==n&&s!==e?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):e):t.error("no such method '"+a+"' for "+i+" widget instance"):t.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+a+"'")}):this.each(function(){var e=t.data(this,o);e?e.option(a||{})._init():t.data(this,o,new n(a,this))}),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this.bindings=t(),this.hoverable=t(),this.focusable=t(),s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:t.noop,_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(t.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:t.noop,widget:function(){return this.element},option:function(i,s){var n,o,a,r=i;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof i)if(r={},n=i.split("."),i=n.shift(),n.length){for(o=r[i]=t.widget.extend({},this.options[i]),a=0;n.length-1>a;a++)o[n[a]]=o[n[a]]||{},o=o[n[a]];if(i=n.pop(),s===e)return o[i]===e?null:o[i];o[i]=s}else{if(s===e)return this.options[i]===e?null:this.options[i];r[i]=s}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return this.options[t]=e,"disabled"===t&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!e).attr("aria-disabled",e),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var o,a=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=o=t(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,o=this.widget()),t.each(n,function(n,r){function h(){return i||a.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof r?a[r]:r).apply(a,arguments):e}"string"!=typeof r&&(h.guid=r.guid=r.guid||h.guid||t.guid++);var l=n.match(/^(\w+)\s*(.*)$/),c=l[1]+a.eventNamespace,u=l[2];u?o.delegate(u,c,h):s.bind(c,h)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(e).undelegate(e)},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){t(e.currentTarget).addClass("ui-state-hover")},mouseleave:function(e){t(e.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){t(e.currentTarget).addClass("ui-state-focus")},focusout:function(e){t(e.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}})}(jQuery),function(t){var e=!1;t(document).mouseup(function(){e=!1}),t.widget("ui.mouse",{version:"1.10.3",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.bind("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).bind("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!e){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,o="string"==typeof this.options.cancel&&i.target.nodeName?t(i.target).closest(this.options.cancel).length:!1;return n&&!o&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===t.data(i.target,this.widgetName+".preventClickEvent")&&t.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return s._mouseMove(t)},this._mouseUpDelegate=function(t){return s._mouseUp(t)},t(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),e=!0,!0)):!0}},_mouseMove:function(e){return t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button?this._mouseUp(e):this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){return t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),!1},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})}(jQuery),function(t){t.widget("ui.draggable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(t(i.iframeFix===!0?"iframe":i.iframeFix).each(function(){t("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(t(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offsetParent=this.helper.offsetParent(),this.offsetParentCssPosition=this.offsetParent.css("position"),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.offset.scroll=!1,t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_mouseDrag:function(e,i){if("fixed"===this.offsetParentCssPosition&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"original"!==this.options.helper||t.contains(this.element[0].ownerDocument,this.element[0])?("invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1):!1},_mouseUp:function(e){return t("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.element.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;return n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):"document"===n.containment?(this.containment=[0,0,t(document).width()-this.helperProportions.width-this.margins.left,(t(document).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):n.containment.constructor===Array?(this.containment=n.containment,undefined):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e="hidden"!==i.css("overflow"),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i),undefined):(this.containment=null,undefined)},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent;return this.offset.scroll||(this.offset.scroll={top:n.scrollTop(),left:n.scrollLeft()}),{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top)*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)*s}},_generatePosition:function(e){var i,s,n,o,a=this.options,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=e.pageX,l=e.pageY;return this.offset.scroll||(this.offset.scroll={top:r.scrollTop(),left:r.scrollLeft()}),this.originalPosition&&(this.containment&&(this.relative_container?(s=this.relative_container.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),e.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),e.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,h=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s]),"drag"===e&&(this.positionAbs=this._convertPositionTo("absolute")),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i){var s=t(this).data("ui-draggable"),n=s.options,o=t.extend({},i,{item:s.element});s.sortables=[],t(n.connectToSortable).each(function(){var i=t.data(this,"ui-sortable");i&&!i.options.disabled&&(s.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",e,o))})},stop:function(e,i){var s=t(this).data("ui-draggable"),n=t.extend({},i,{item:s.element});t.each(s.sortables,function(){this.instance.isOver?(this.instance.isOver=0,s.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(e),this.instance.options.helper=this.instance.options._helper,"original"===s.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",e,n))})},drag:function(e,i){var s=t(this).data("ui-draggable"),n=this;t.each(s.sortables,function(){var o=!1,a=this;this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(o=!0,t.each(s.sortables,function(){return this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this!==a&&this.instance._intersectsWith(this.instance.containerCache)&&t.contains(a.instance.element[0],this.instance.element[0])&&(o=!1),o})),o?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=t(n).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},e.target=this.instance.currentItem[0],this.instance._mouseCapture(e,!0),this.instance._mouseStart(e,!0,!0),this.instance.offset.click.top=s.offset.click.top,this.instance.offset.click.left=s.offset.click.left,this.instance.offset.parent.left-=s.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=s.offset.parent.top-this.instance.offset.parent.top,s._trigger("toSortable",e),s.dropped=this.instance.element,s.currentItem=s.element,this.instance.fromOutside=s),this.instance.currentItem&&this.instance._mouseDrag(e)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",e,this.instance._uiHash(this.instance)),this.instance._mouseStop(e,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),s._trigger("fromSortable",e),s.dropped=!1)})}}),t.ui.plugin.add("draggable","cursor",{start:function(){var e=t("body"),i=t(this).data("ui-draggable").options;e.css("cursor")&&(i._cursor=e.css("cursor")),e.css("cursor",i.cursor)},stop:function(){var e=t(this).data("ui-draggable").options;e._cursor&&t("body").css("cursor",e._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("opacity")&&(n._opacity=s.css("opacity")),s.css("opacity",n.opacity)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._opacity&&t(i.helper).css("opacity",s._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(){var e=t(this).data("ui-draggable");e.scrollParent[0]!==document&&"HTML"!==e.scrollParent[0].tagName&&(e.overflowOffset=e.scrollParent.offset())},drag:function(e){var i=t(this).data("ui-draggable"),s=i.options,n=!1;i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-e.pageY<s.scrollSensitivity?i.scrollParent[0].scrollTop=n=i.scrollParent[0].scrollTop+s.scrollSpeed:e.pageY-i.overflowOffset.top<s.scrollSensitivity&&(i.scrollParent[0].scrollTop=n=i.scrollParent[0].scrollTop-s.scrollSpeed)),s.axis&&"y"===s.axis||(i.overflowOffset.left+i.scrollParent[0].offsetWidth-e.pageX<s.scrollSensitivity?i.scrollParent[0].scrollLeft=n=i.scrollParent[0].scrollLeft+s.scrollSpeed:e.pageX-i.overflowOffset.left<s.scrollSensitivity&&(i.scrollParent[0].scrollLeft=n=i.scrollParent[0].scrollLeft-s.scrollSpeed))):(s.axis&&"x"===s.axis||(e.pageY-t(document).scrollTop()<s.scrollSensitivity?n=t(document).scrollTop(t(document).scrollTop()-s.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<s.scrollSensitivity&&(n=t(document).scrollTop(t(document).scrollTop()+s.scrollSpeed))),s.axis&&"y"===s.axis||(e.pageX-t(document).scrollLeft()<s.scrollSensitivity?n=t(document).scrollLeft(t(document).scrollLeft()-s.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<s.scrollSensitivity&&(n=t(document).scrollLeft(t(document).scrollLeft()+s.scrollSpeed)))),n!==!1&&t.ui.ddmanager&&!s.dropBehaviour&&t.ui.ddmanager.prepareOffsets(i,e)}}),t.ui.plugin.add("draggable","snap",{start:function(){var e=t(this).data("ui-draggable"),i=e.options;e.snapElements=[],t(i.snap.constructor!==String?i.snap.items||":data(ui-draggable)":i.snap).each(function(){var i=t(this),s=i.offset();this!==e.element[0]&&e.snapElements.push({item:this,width:i.outerWidth(),height:i.outerHeight(),top:s.top,left:s.left})})},drag:function(e,i){var s,n,o,a,r,h,l,c,u,d,p=t(this).data("ui-draggable"),f=p.options,g=f.snapTolerance,m=i.offset.left,v=m+p.helperProportions.width,_=i.offset.top,b=_+p.helperProportions.height;for(u=p.snapElements.length-1;u>=0;u--)r=p.snapElements[u].left,h=r+p.snapElements[u].width,l=p.snapElements[u].top,c=l+p.snapElements[u].height,r-g>v||m>h+g||l-g>b||_>c+g||!t.contains(p.snapElements[u].item.ownerDocument,p.snapElements[u].item)?(p.snapElements[u].snapping&&p.options.snap.release&&p.options.snap.release.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=!1):("inner"!==f.snapMode&&(s=g>=Math.abs(l-b),n=g>=Math.abs(c-_),o=g>=Math.abs(r-v),a=g>=Math.abs(h-m),s&&(i.position.top=p._convertPositionTo("relative",{top:l-p.helperProportions.height,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c,left:0}).top-p.margins.top),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r-p.helperProportions.width}).left-p.margins.left),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h}).left-p.margins.left)),d=s||n||o||a,"outer"!==f.snapMode&&(s=g>=Math.abs(l-_),n=g>=Math.abs(c-b),o=g>=Math.abs(r-m),a=g>=Math.abs(h-v),s&&(i.position.top=p._convertPositionTo("relative",{top:l,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c-p.helperProportions.height,left:0}).top-p.margins.top),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r}).left-p.margins.left),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h-p.helperProportions.width}).left-p.margins.left)),!p.snapElements[u].snapping&&(s||n||o||a||d)&&p.options.snap.snap&&p.options.snap.snap.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=s||n||o||a||d)}}),t.ui.plugin.add("draggable","stack",{start:function(){var e,i=this.data("ui-draggable").options,s=t.makeArray(t(i.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});s.length&&(e=parseInt(t(s[0]).css("zIndex"),10)||0,t(s).each(function(i){t(this).css("zIndex",e+i)}),this.css("zIndex",e+s.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("zIndex")&&(n._zIndex=s.css("zIndex")),s.css("zIndex",n.zIndex)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._zIndex&&t(i.helper).css("zIndex",s._zIndex)}})}(jQuery),function(t){function e(t,e,i){return t>e&&e+i>t}t.widget("ui.droppable",{version:"1.10.3",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e=this.options,i=e.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(i)?i:function(t){return t.is(i)
+},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},t.ui.ddmanager.droppables[e.scope]=t.ui.ddmanager.droppables[e.scope]||[],t.ui.ddmanager.droppables[e.scope].push(this),e.addClasses&&this.element.addClass("ui-droppable")},_destroy:function(){for(var e=0,i=t.ui.ddmanager.droppables[this.options.scope];i.length>e;e++)i[e]===this&&i.splice(e,1);this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(e,i){"accept"===e&&(this.accept=t.isFunction(i)?i:function(t){return t.is(i)}),t.Widget.prototype._setOption.apply(this,arguments)},_activate:function(e){var i=t.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var e=t.data(this,"ui-droppable");return e.options.greedy&&!e.options.disabled&&e.options.scope===s.options.scope&&e.accept.call(e.element[0],s.currentItem||s.element)&&t.ui.intersect(s,t.extend(e,{offset:e.element.offset()}),e.options.tolerance)?(n=!0,!1):undefined}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",e,this.ui(s)),this.element):!1):!1},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}}}),t.ui.intersect=function(t,i,s){if(!i.offset)return!1;var n,o,a=(t.positionAbs||t.position.absolute).left,r=a+t.helperProportions.width,h=(t.positionAbs||t.position.absolute).top,l=h+t.helperProportions.height,c=i.offset.left,u=c+i.proportions.width,d=i.offset.top,p=d+i.proportions.height;switch(s){case"fit":return a>=c&&u>=r&&h>=d&&p>=l;case"intersect":return a+t.helperProportions.width/2>c&&u>r-t.helperProportions.width/2&&h+t.helperProportions.height/2>d&&p>l-t.helperProportions.height/2;case"pointer":return n=(t.positionAbs||t.position.absolute).left+(t.clickOffset||t.offset.click).left,o=(t.positionAbs||t.position.absolute).top+(t.clickOffset||t.offset.click).top,e(o,d,i.proportions.height)&&e(n,c,i.proportions.width);case"touch":return(h>=d&&p>=h||l>=d&&p>=l||d>h&&l>p)&&(a>=c&&u>=a||r>=c&&u>=r||c>a&&r>u);default:return!1}},t.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,i){var s,n,o=t.ui.ddmanager.droppables[e.options.scope]||[],a=i?i.type:null,r=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;o.length>s;s++)if(!(o[s].options.disabled||e&&!o[s].accept.call(o[s].element[0],e.currentItem||e.element))){for(n=0;r.length>n;n++)if(r[n]===o[s].element[0]){o[s].proportions.height=0;continue t}o[s].visible="none"!==o[s].element.css("display"),o[s].visible&&("mousedown"===a&&o[s]._activate.call(o[s],i),o[s].offset=o[s].element.offset(),o[s].proportions={width:o[s].element[0].offsetWidth,height:o[s].element[0].offsetHeight})}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&t.ui.intersect(e,this,this.options.tolerance)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").bind("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,o,a=t.ui.intersect(e,this,this.options.tolerance),r=!a&&this.isover?"isout":a&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,o=this.element.parents(":data(ui-droppable)").filter(function(){return t.data(this,"ui-droppable").options.scope===n}),o.length&&(s=t.data(o[0],"ui-droppable"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").unbind("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}}}(jQuery),function(t){function e(t){return parseInt(t,10)||0}function i(t){return!isNaN(parseInt(t,10))}t.widget("ui.resizable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var e,i,s,n,o,a=this,r=this.options;if(this.element.addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),e=this.handles.split(","),this.handles={},i=0;e.length>i;i++)s=t.trim(e[i]),o="ui-resizable-"+s,n=t("<div class='ui-resizable-handle "+o+"'></div>"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=t(this.handles[i],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),t(this.handles[i]).length},this._renderAxis(this.element),this._handles=t(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){a.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),a.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),t(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(t(this).removeClass("ui-resizable-autohide"),a._handles.show())}).mouseleave(function(){r.disabled||a.resizing||(t(this).addClass("ui-resizable-autohide"),a._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(i){var s,n,o,a=this.options,r=this.element.position(),h=this.element;return this.resizing=!0,/absolute/.test(h.css("position"))?h.css({position:"absolute",top:h.css("top"),left:h.css("left")}):h.is(".ui-draggable")&&h.css({position:"absolute",top:r.top,left:r.left}),this._renderProxy(),s=e(this.helper.css("left")),n=e(this.helper.css("top")),a.containment&&(s+=t(a.containment).scrollLeft()||0,n+=t(a.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:s,top:n},this.size=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalSize=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalPosition={left:s,top:n},this.sizeDiff={width:h.outerWidth()-h.width(),height:h.outerHeight()-h.height()},this.originalMousePosition={left:i.pageX,top:i.pageY},this.aspectRatio="number"==typeof a.aspectRatio?a.aspectRatio:this.originalSize.width/this.originalSize.height||1,o=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===o?this.axis+"-resize":o),h.addClass("ui-resizable-resizing"),this._propagate("start",i),!0},_mouseDrag:function(e){var i,s=this.helper,n={},o=this.originalMousePosition,a=this.axis,r=this.position.top,h=this.position.left,l=this.size.width,c=this.size.height,u=e.pageX-o.left||0,d=e.pageY-o.top||0,p=this._change[a];return p?(i=p.apply(this,[e,u,d]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),this.position.top!==r&&(n.top=this.position.top+"px"),this.position.left!==h&&(n.left=this.position.left+"px"),this.size.width!==l&&(n.width=this.size.width+"px"),this.size.height!==c&&(n.height=this.size.height+"px"),s.css(n),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(n)||this._trigger("resize",e,this.ui()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&t.ui.hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null,h=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(t){var e,s,n,o,a,r=this.options;a={minWidth:i(r.minWidth)?r.minWidth:0,maxWidth:i(r.maxWidth)?r.maxWidth:1/0,minHeight:i(r.minHeight)?r.minHeight:0,maxHeight:i(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||t)&&(e=a.minHeight*this.aspectRatio,n=a.minWidth/this.aspectRatio,s=a.maxHeight*this.aspectRatio,o=a.maxWidth/this.aspectRatio,e>a.minWidth&&(a.minWidth=e),n>a.minHeight&&(a.minHeight=n),a.maxWidth>s&&(a.maxWidth=s),a.maxHeight>o&&(a.maxHeight=o)),this._vBoundaries=a},_updateCache:function(t){this.offset=this.helper.offset(),i(t.left)&&(this.position.left=t.left),i(t.top)&&(this.position.top=t.top),i(t.height)&&(this.size.height=t.height),i(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,s=this.size,n=this.axis;return i(t.height)?t.width=t.height*this.aspectRatio:i(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===n&&(t.left=e.left+(s.width-t.width),t.top=null),"nw"===n&&(t.top=e.top+(s.height-t.height),t.left=e.left+(s.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,s=this.axis,n=i(t.width)&&e.maxWidth&&e.maxWidth<t.width,o=i(t.height)&&e.maxHeight&&e.maxHeight<t.height,a=i(t.width)&&e.minWidth&&e.minWidth>t.width,r=i(t.height)&&e.minHeight&&e.minHeight>t.height,h=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,c=/sw|nw|w/.test(s),u=/nw|ne|n/.test(s);return a&&(t.width=e.minWidth),r&&(t.height=e.minHeight),n&&(t.width=e.maxWidth),o&&(t.height=e.maxHeight),a&&c&&(t.left=h-e.minWidth),n&&c&&(t.left=h-e.maxWidth),r&&u&&(t.top=l-e.minHeight),o&&u&&(t.top=l-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var t,e,i,s,n,o=this.helper||this.element;for(t=0;this._proportionallyResizeElements.length>t;t++){if(n=this._proportionallyResizeElements[t],!this.borderDif)for(this.borderDif=[],i=[n.css("borderTopWidth"),n.css("borderRightWidth"),n.css("borderBottomWidth"),n.css("borderLeftWidth")],s=[n.css("paddingTop"),n.css("paddingRight"),n.css("paddingBottom"),n.css("paddingLeft")],e=0;i.length>e;e++)this.borderDif[e]=(parseInt(i[e],10)||0)+(parseInt(s[e],10)||0);n.css({height:o.height()-this.borderDif[0]-this.borderDif[2]||0,width:o.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).data("ui-resizable"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&t.ui.hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,c=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var i,s,n,o,a,r,h,l=t(this).data("ui-resizable"),c=l.options,u=l.element,d=c.containment,p=d instanceof t?d.get(0):/parent/.test(d)?u.parent().get(0):d;p&&(l.containerElement=t(p),/document/.test(d)||d===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(i=t(p),s=[],t(["Top","Right","Left","Bottom"]).each(function(t,n){s[t]=e(i.css("padding"+n))}),l.containerOffset=i.offset(),l.containerPosition=i.position(),l.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},n=l.containerOffset,o=l.containerSize.height,a=l.containerSize.width,r=t.ui.hasScroll(p,"left")?p.scrollWidth:a,h=t.ui.hasScroll(p)?p.scrollHeight:o,l.parentData={element:p,left:n.left,top:n.top,width:r,height:h}))},resize:function(e){var i,s,n,o,a=t(this).data("ui-resizable"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio),a.position.top=a._helper?h.top:0),a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top,i=Math.abs((a._helper?a.offset.left-u.left:a.offset.left-u.left)+a.sizeDiff.width),s=Math.abs((a._helper?a.offset.top-u.top:a.offset.top-h.top)+a.sizeDiff.height),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o&&(i-=a.parentData.left),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio))},stop:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=function(e){t(e).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseInt(e.width(),10),height:parseInt(e.height(),10),left:parseInt(e.css("left"),10),top:parseInt(e.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):t.each(i.alsoResize,function(t){s(t)})},resize:function(e,i){var s=t(this).data("ui-resizable"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0},h=function(e,s){t(e).each(function(){var e=t(this),n=t(this).data("ui-resizable-alsoresize"),o={},a=s&&s.length?s:e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(a,function(t,e){var i=(n[e]||0)+(r[e]||0);i&&i>=0&&(o[e]=i||null)}),e.css(o)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):t.each(n.alsoResize,function(t,e){h(t,e)})},stop:function(){t(this).removeData("resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).data("ui-resizable");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).data("ui-resizable");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,a=e.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=r[0]||1,l=r[1]||1,c=Math.round((s.width-n.width)/h)*h,u=Math.round((s.height-n.height)/l)*l,d=n.width+c,p=n.height+u,f=i.maxWidth&&d>i.maxWidth,g=i.maxHeight&&p>i.maxHeight,m=i.minWidth&&i.minWidth>d,v=i.minHeight&&i.minHeight>p;i.grid=r,m&&(d+=h),v&&(p+=l),f&&(d-=h),g&&(p-=l),/^(se|s|e)$/.test(a)?(e.size.width=d,e.size.height=p):/^(ne)$/.test(a)?(e.size.width=d,e.size.height=p,e.position.top=o.top-u):/^(sw)$/.test(a)?(e.size.width=d,e.size.height=p,e.position.left=o.left-c):(e.size.width=d,e.size.height=p,e.position.top=o.top-u,e.position.left=o.left-c)}})}(jQuery),function(t){t.widget("ui.selectable",t.ui.mouse,{version:"1.10.3",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e,i=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e=t(i.options.filter,i.element[0]),e.addClass("ui-selectee"),e.each(function(){var e=t(this),i=e.offset();t.data(this,"selectable-item",{element:this,$element:e,left:i.left,top:i.top,right:i.left+e.outerWidth(),bottom:i.top+e.outerHeight(),startselected:!1,selected:e.hasClass("ui-selected"),selecting:e.hasClass("ui-selecting"),unselecting:e.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=e.addClass("ui-selectee"),this._mouseInit(),this.helper=t("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,n=t.data(this,"selectable-item");return n?(s=!e.metaKey&&!e.ctrlKey||!n.$element.hasClass("ui-selected"),n.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",e,{selecting:n.element}):i._trigger("unselecting",e,{unselecting:n.element}),!1):undefined}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,o=this.opos[0],a=this.opos[1],r=e.pageX,h=e.pageY;return o>r&&(i=r,r=o,o=i),a>h&&(i=h,h=a,a=i),this.helper.css({left:o,top:a,width:r-o,height:h-a}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1;i&&i.element!==s.element[0]&&("touch"===n.tolerance?l=!(i.left>r||o>i.right||i.top>h||a>i.bottom):"fit"===n.tolerance&&(l=i.left>o&&r>i.right&&i.top>a&&h>i.bottom),l?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}})}(jQuery),function(t){function e(t,e,i){return t>e&&e+i>t}function i(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))}t.widget("ui.sortable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var t=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===t.axis||i(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_setOption:function(e,i){"disabled"===e?(this.options[e]=i,this.widget().toggleClass("ui-sortable-disabled",!!i)):t.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):undefined}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("<style>*{ cursor: "+a.cursor+" !important; }</style>").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<a.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+a.scrollSpeed:e.pageY-this.overflowOffset.top<a.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-a.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<a.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+a.scrollSpeed:e.pageX-this.overflowOffset.left<a.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-a.scrollSpeed)):(e.pageY-t(document).scrollTop()<a.scrollSensitivity?r=t(document).scrollTop(t(document).scrollTop()-a.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<a.scrollSensitivity&&(r=t(document).scrollTop(t(document).scrollTop()+a.scrollSpeed)),e.pageX-t(document).scrollLeft()<a.scrollSensitivity?r=t(document).scrollLeft(t(document).scrollLeft()-a.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<a.scrollSensitivity&&(r=t(document).scrollLeft(t(document).scrollLeft()+a.scrollSpeed))),r!==!1&&t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;
+this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var i="x"===this.options.axis||e(this.positionAbs.top+this.offset.click.top,t.top,t.height),s="y"===this.options.axis||e(this.positionAbs.left+this.offset.click.left,t.left,t.width),n=i&&s,o=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return n?this.floating?a&&"right"===a||"down"===o?2:1:o&&("down"===o?2:1):!1},_intersectsWithSides:function(t){var i=e(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),s=e(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),n=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return this.floating&&o?"right"===o&&s||"left"===o&&!s:n&&("down"===n&&i||"up"===n&&!i)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){var i,s,n,o,a=[],r=[],h=this._connectWith();if(h&&e)for(i=h.length-1;i>=0;i--)for(n=t(h[i]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&r.push([t.isFunction(o.options.items)?o.options.items.call(o.element):t(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);for(r.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),i=r.length-1;i>=0;i--)r[i][0].each(function(){a.push(this)});return t(a)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]).addClass(i||e.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?e.currentItem.children().each(function(){t("<td>&#160;</td>",e.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(n)}):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_contactContainers:function(s){var n,o,a,r,h,l,c,u,d,p,f=null,g=null;for(n=this.containers.length-1;n>=0;n--)if(!t.contains(this.currentItem[0],this.containers[n].element[0]))if(this._intersectsWith(this.containers[n].containerCache)){if(f&&t.contains(this.containers[n].element[0],f.element[0]))continue;f=this.containers[n],g=n}else this.containers[n].containerCache.over&&(this.containers[n]._trigger("out",s,this._uiHash(this)),this.containers[n].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[g].containerCache.over||(this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1);else{for(a=1e4,r=null,p=f.floating||i(this.currentItem),h=p?"left":"top",l=p?"width":"height",c=this.positionAbs[h]+this.offset.click[h],o=this.items.length-1;o>=0;o--)t.contains(this.containers[g].element[0],this.items[o].item[0])&&this.items[o].item[0]!==this.currentItem[0]&&(!p||e(this.positionAbs.top+this.offset.click.top,this.items[o].top,this.items[o].height))&&(u=this.items[o].item.offset()[h],d=!1,Math.abs(u-c)>Math.abs(u+this.items[o][l]-c)&&(d=!0,u+=this.items[o][l]),a>Math.abs(u-c)&&(a=Math.abs(u-c),r=this.items[o],this.direction=d?"up":"down"));if(!r&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[g])return;r?this._rearrange(s,r,null,!0):this._rearrange(s,null,this.containers[g].element,!0),this._trigger("change",s,this._uiHash()),this.containers[g]._trigger("change",s,this._uiHash(this)),this.currentContainer=this.containers[g],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,t("document"===n.containment?document:window).width()-this.helperProportions.width-this.margins.left,(t("document"===n.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(o=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(a=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)("auto"===this._storedCSS[i]||"static"===this._storedCSS[i])&&(this._storedCSS[i]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;i>=0;i--)e||s.push(function(t){return function(e){t._trigger("deactivate",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(function(t){return function(e){t._trigger("out",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!e){for(this._trigger("beforeStop",t,this._uiHash()),i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}if(e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!e){for(i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}})}(jQuery),function(t,e){var i="ui-effects-";t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,o){var a,r=o.re.exec(i),h=r&&o.parse(r),l=o.space||"rgba";return h?(a=s[l](h),s[c[l].cache]=a[c[l].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("<p>")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),l.fn=t.extend(l.prototype,{parse:function(n,a,r,h){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,h],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof l?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=l(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=l(t),n=s._space(),o=c[n],a=0===this.alpha()?l("transparent"):this,r=a[o.cache]||o.to(a._rgba),h=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],l=s[o],c=u[n.type]||{};null!==l&&(null===a?h[o]=l:(c.mod&&(l-a>c.mod/2?a+=c.mod:a-l>c.mod/2&&(a-=c.mod)),h[o]=i((l-a)*e+a,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),h=Math.min(s,n,o),l=r-h,c=r+h,u=.5*c;return e=h===r?0:s===r?60*(n-o)/l+360:n===r?60*(o-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=u?l/c:l/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,h=n.to,c=n.from;l.fn[s]=function(s){if(h&&!this[a]&&(this[a]=h(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=l(c(d)),n[a]=d,n):l(d)},f(o,function(e,i){l.fn[e]||(l.fn[e]=function(n){var o,a=t.type(n),h="alpha"===e?this._hsla?"hsla":"rgba":s,l=this[h](),c=l[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=l(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(h){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=l(e.elem,i),e.end=l(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},l.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function s(e,i){var s,n,a={};for(s in i)n=i[s],e[s]!==n&&(o[s]||(t.fx.step[s]||!isNaN(parseFloat(n)))&&(a[s]=n));return a}var n=["add","remove","toggle"],o={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(jQuery.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(e,o,a,r){var h=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",l=h.children?a.find("*").addBack():a;l=l.map(function(){var e=t(this);return{el:e,start:i(this)}}),o=function(){t.each(n,function(t,i){e[i]&&a[i+"Class"](e[i])})},o(),l=l.map(function(){return this.end=i(this.el[0]),this.diff=s(this.start,this.end),this}),a.attr("class",r),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(i){return function(s,n,o,a,r){return"boolean"==typeof n||n===e?o?t.effects.animateClass.call(this,n?{add:s}:{remove:s},o,a,r):i.apply(this,arguments):t.effects.animateClass.call(this,{toggle:s},n,o,a)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function s(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function n(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}t.extend(t.effects,{version:"1.10.3",save:function(t,e){for(var s=0;e.length>s;s++)null!==e[s]&&t.data(i+e[s],t[0].style[e[s]])},restore:function(t,s){var n,o;for(o=0;s.length>o;o++)null!==s[o]&&(n=t.data(i+s[o]),n===e&&(n=""),t.css(s[o],n))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).focus(),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).focus()),e},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function e(e){function s(){t.isFunction(o)&&o.call(n[0]),t.isFunction(e)&&e()}var n=t(this),o=i.complete,r=i.mode;(n.is(":hidden")?"hide"===r:"show"===r)?(n[r](),s()):a.call(n[0],i,s)}var i=s.apply(this,arguments),n=i.mode,o=i.queue,a=t.effects.effect[i.effect];return t.fx.off||!a?n?this[n](i.duration,i.complete):this.each(function(){i.complete&&i.complete.call(this)}):o===!1?this.each(e):this.queue(o||"fx",e)},show:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="show",this.effect.call(this,i)}}(t.fn.show),hide:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="hide",this.effect.call(this,i)}}(t.fn.hide),toggle:function(t){return function(e){if(n(e)||"boolean"==typeof e)return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="toggle",this.effect.call(this,i)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s}})}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}()}(jQuery),function(t){var e=0,i={},s={};i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="hide",s.height=s.paddingTop=s.paddingBottom=s.borderTopWidth=s.borderBottomWidth="show",t.widget("ui.accordion",{version:"1.10.3",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t(),content:this.active.length?this.active.next():t()}},_createIcons:function(){var e=this.options.icons;e&&(t("<span>").addClass("ui-accordion-header-icon ui-icon "+e.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(e.header).addClass(e.activeHeader),this.headers.addClass("ui-accordion-icons"))
+},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),undefined):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),"disabled"===t&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!e),undefined)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),o.focus(),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().focus()},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var i,s=this.options,n=s.heightStyle,o=this.element.parent(),a=this.accordionId="ui-accordion-"+(this.element.attr("id")||++e);this.active=this._findActive(s.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(e){var i=t(this),s=i.attr("id"),n=i.next(),o=n.attr("id");s||(s=a+"-header-"+e,i.attr("id",s)),o||(o=a+"-panel-"+e,n.attr("id",o)),i.attr("aria-controls",o),n.attr("aria-labelledby",s)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(s.event),"fill"===n?(i=o.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.headers.each(function(){i-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===n&&(i=0,this.headers.next().each(function(){i=Math.max(i,t(this).css("height","").height())}).height(i))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n[0]===s[0],a=o&&i.collapsible,r=a?t():n.next(),h=s.next(),l={oldHeader:s,oldPanel:h,newHeader:a?t():n,newPanel:r};e.preventDefault(),o&&!i.collapsible||this._trigger("beforeActivate",e,l)===!1||(i.active=a?!1:this.headers.index(n),this.active=o?t():n,this._toggle(l),s.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),o||(n.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&n.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),n.next().addClass("ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-expanded":"false","aria-hidden":"true"}),s.prev().attr("aria-selected","false"),i.length&&s.length?s.prev().attr("tabIndex",-1):i.length&&this.headers.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(t,e,n){var o,a,r,h=this,l=0,c=t.length&&(!e.length||t.index()<e.index()),u=this.options.animate||{},d=c&&u.down||u,p=function(){h._toggleComplete(n)};return"number"==typeof d&&(r=d),"string"==typeof d&&(a=d),a=a||d.easing||u.easing,r=r||d.duration||u.duration,e.length?t.length?(o=t.show().outerHeight(),e.animate(i,{duration:r,easing:a,step:function(t,e){e.now=Math.round(t)}}),t.hide().animate(s,{duration:r,easing:a,complete:p,step:function(t,i){i.now=Math.round(t),"height"!==i.prop?l+=i.now:"content"!==h.options.heightStyle&&(i.now=Math.round(o-e.outerHeight()-l),l=0)}}),undefined):e.animate(i,r,a,p):t.animate(s,r,a,p)},_toggleComplete:function(t){var e=t.oldPanel;e.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),e.length&&(e.parent()[0].className=e.parent()[0].className),this._trigger("activate",null,t)}})}(jQuery),function(t){var e=0;t.widget("ui.autocomplete",{version:"1.10.3",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;this.isMultiLine=o?!0:a?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,undefined;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:case o.NUMPAD_ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),undefined;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),undefined):(this._searchTimeout(t),undefined)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,undefined):(clearTimeout(this.searching),this.close(t),this._change(t),undefined)}}),this._initSource(),this.menu=t("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().data("ui-menu"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];t(e.target).closest(".ui-menu-item").length||this._delay(function(){var e=this;this.document.one("mousedown",function(s){s.target===e.element[0]||s.target===i||t.contains(i,s.target)||e.close()})})},menufocus:function(e,i){if(this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type)))return this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),undefined;var s=i.item.data("ui-autocomplete-item");!1!==this._trigger("focus",e,{item:s})?e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(s.value):this.liveRegion.text(s.value)},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=t("<span>",{role:"status","aria-live":"polite"}).addClass("ui-helper-hidden-accessible").insertBefore(this.element),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e||(e=this.element.closest(".ui-front")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){this.term!==this._value()&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length<this.options.minLength?this.close(e):this._trigger("search",e)!==!1?this._search(t):undefined},_search:function(t){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:t},this._response())},_response:function(){var t=this,i=++e;return function(s){i===e&&t.__response(s),t.pending--,t.pending||t.element.removeClass("ui-autocomplete-loading")}},__response:function(t){t&&(t=this._normalize(t)),this._trigger("response",null,{content:t}),!this.options.disabled&&t&&t.length&&!this.cancelSearch?(this._suggest(t),this._trigger("open")):this._close()},close:function(t){this.cancelSearch=!0,this._close(t)},_close:function(t){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",t))},_change:function(t){this.previous!==this._value()&&this._trigger("change",t,{item:this.selectedItem})},_normalize:function(e){return e.length&&e[0].label&&e[0].value?e:t.map(e,function(e){return"string"==typeof e?{label:e,value:e}:t.extend({label:e.label||e.value,value:e.value||e.label},e)})},_suggest:function(e){var i=this.menu.element.empty();this._renderMenu(i,e),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(t.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var t=this.menu.element;t.outerWidth(Math.max(t.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(e,i){var s=this;t.each(i,function(t,i){s._renderItemData(e,i)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-autocomplete-item",e)},_renderItem:function(e,i){return t("<li>").append(t("<a>").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this._value(this.term),this.menu.blur(),undefined):(this.menu[t](e),undefined):(this.search(null,e),undefined)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(t){var e;this._superApply(arguments),this.options.disabled||this.cancelSearch||(e=t&&t.length?this.options.messages.results(t.length):this.options.messages.noResults,this.liveRegion.text(e))}})}(jQuery),function(t){var e,i,s,n,o="ui-button ui-widget ui-state-default ui-corner-all",a="ui-state-hover ui-state-active ",r="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",h=function(){var e=t(this);setTimeout(function(){e.find(":ui-button").button("refresh")},1)},l=function(e){var i=e.name,s=e.form,n=t([]);return i&&(i=i.replace(/'/g,"\\'"),n=s?t(s).find("[name='"+i+"']"):t("[name='"+i+"']",e.ownerDocument).filter(function(){return!this.form})),n};t.widget("ui.button",{version:"1.10.3",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,h),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var a=this,r=this.options,c="checkbox"===this.type||"radio"===this.type,u=c?"":"ui-state-active",d="ui-state-focus";null===r.label&&(r.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(o).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){r.disabled||this===e&&t(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){r.disabled||t(this).removeClass(u)}).bind("click"+this.eventNamespace,function(t){r.disabled&&(t.preventDefault(),t.stopImmediatePropagation())}),this.element.bind("focus"+this.eventNamespace,function(){a.buttonElement.addClass(d)}).bind("blur"+this.eventNamespace,function(){a.buttonElement.removeClass(d)}),c&&(this.element.bind("change"+this.eventNamespace,function(){n||a.refresh()}),this.buttonElement.bind("mousedown"+this.eventNamespace,function(t){r.disabled||(n=!1,i=t.pageX,s=t.pageY)}).bind("mouseup"+this.eventNamespace,function(t){r.disabled||(i!==t.pageX||s!==t.pageY)&&(n=!0)})),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return r.disabled||n?!1:undefined}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(r.disabled||n)return!1;t(this).addClass("ui-state-active"),a.buttonElement.attr("aria-pressed","true");var e=a.element[0];l(e).not(e).map(function(){return t(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return r.disabled?!1:(t(this).addClass("ui-state-active"),e=this,a.document.one("mouseup",function(){e=null}),undefined)}).bind("mouseup"+this.eventNamespace,function(){return r.disabled?!1:(t(this).removeClass("ui-state-active"),undefined)}).bind("keydown"+this.eventNamespace,function(e){return r.disabled?!1:((e.keyCode===t.ui.keyCode.SPACE||e.keyCode===t.ui.keyCode.ENTER)&&t(this).addClass("ui-state-active"),undefined)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){t(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(e){e.keyCode===t.ui.keyCode.SPACE&&t(this).click()})),this._setOption("disabled",r.disabled),this._resetButton()},_determineButtonType:function(){var t,e,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(t=this.element.parents().last(),e="label[for='"+this.element.attr("id")+"']",this.buttonElement=t.find(e),this.buttonElement.length||(t=t.length?t.siblings():this.element.siblings(),this.buttonElement=t.filter(e),this.buttonElement.length||(this.buttonElement=t.find(e))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(o+" "+a+" "+r).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(t,e){return this._super(t,e),"disabled"===t?(e?this.element.prop("disabled",!0):this.element.prop("disabled",!1),undefined):(this._resetButton(),undefined)},refresh:function(){var e=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");e!==this.options.disabled&&this._setOption("disabled",e),"radio"===this.type?l(this.element[0]).each(function(){t(this).is(":checked")?t(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):t(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),undefined;var e=this.buttonElement.removeClass(r),i=t("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(e.empty()).text(),s=this.options.icons,n=s.primary&&s.secondary,o=[];s.primary||s.secondary?(this.options.text&&o.push("ui-button-text-icon"+(n?"s":s.primary?"-primary":"-secondary")),s.primary&&e.prepend("<span class='ui-button-icon-primary ui-icon "+s.primary+"'></span>"),s.secondary&&e.append("<span class='ui-button-icon-secondary ui-icon "+s.secondary+"'></span>"),this.options.text||(o.push(n?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||e.attr("title",t.trim(i)))):o.push("ui-button-text-only"),e.addClass(o.join(" "))}}),t.widget("ui.buttonset",{version:"1.10.3",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(t,e){"disabled"===t&&this.buttons.button("option",t,e),this._super(t,e)},refresh:function(){var e="rtl"===this.element.css("direction");this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return t(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(e?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(e?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return t(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}})}(jQuery),function(t,e){function i(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.dpDiv=s(t("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function s(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.delegate(i,"mouseout",function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",function(){t.datepicker._isDisabledDatepicker(o.inline?e.parent()[0]:o.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))})}function n(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}t.extend(t.ui,{datepicker:{version:"1.10.3"}});var o,a="datepicker";t.extend(i.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(t){return n(this._defaults,t||{}),this},_attachDatepicker:function(e,i){var s,n,o;s=e.nodeName.toLowerCase(),n="div"===s||"span"===s,e.id||(this.uuid+=1,e.id="dp"+this.uuid),o=this._newInst(t(e),n),o.settings=t.extend({},i||{}),"input"===s?this._connectDatepicker(e,o):n&&this._inlineDatepicker(e,o)},_newInst:function(e,i){var n=e[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:n,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?s(t("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(e,i){var s=t(e);i.append=t([]),i.trigger=t([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),t.data(e,a,i),i.settings.disabled&&this._disableDatepicker(e))},_attachments:function(e,i){var s,n,o,a=this._get(i,"appendText"),r=this._get(i,"isRTL");i.append&&i.append.remove(),a&&(i.append=t("<span class='"+this._appendClass+"'>"+a+"</span>"),e[r?"before":"after"](i.append)),e.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&e.focus(this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),o=this._get(i,"buttonImage"),i.trigger=t(this._get(i,"buttonImageOnly")?t("<img/>").addClass(this._triggerClass).attr({src:o,alt:n,title:n}):t("<button type='button'></button>").addClass(this._triggerClass).html(o?t("<img/>").attr({src:o,alt:n,title:n}):n)),e[r?"before":"after"](i.trigger),i.trigger.click(function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,o=new Date(2009,11,20),a=this._get(t,"dateFormat");a.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},o.setMonth(e(this._get(t,a.match(/MM/)?"monthNames":"monthNamesShort"))),o.setDate(e(this._get(t,a.match(/DD/)?"dayNames":"dayNamesShort"))+20-o.getDay())),t.input.attr("size",this._formatDate(t,o).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,a,i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,o,r){var h,l,c,u,d,p=this._dialogInst;return p||(this.uuid+=1,h="dp"+this.uuid,this._dialogInput=t("<input type='text' id='"+h+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),t("body").append(this._dialogInput),p=this._dialogInst=this._newInst(this._dialogInput,!1),p.settings={},t.data(this._dialogInput[0],a,p)),n(p.settings,o||{}),i=i&&i.constructor===Date?this._formatDate(p,i):i,this._dialogInput.val(i),this._pos=r?r.length?r:[r.pageX,r.pageY]:null,this._pos||(l=document.documentElement.clientWidth,c=document.documentElement.clientHeight,u=document.documentElement.scrollLeft||document.body.scrollLeft,d=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[l/2-100+u,c/2-150+d]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),p.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],a,p),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,a);s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,a),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty())},_enableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,a);n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,o.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,a);n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,o.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,a)}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(i,s,o){var a,r,h,l,c=this._getInst(i);return 2===arguments.length&&"string"==typeof s?"defaults"===s?t.extend({},t.datepicker._defaults):c?"all"===s?t.extend({},c.settings):this._get(c,s):null:(a=s||{},"string"==typeof s&&(a={},a[s]=o),c&&(this._curInst===c&&this._hideDatepicker(),r=this._getDateDatepicker(i,!0),h=this._getMinMaxDate(c,"min"),l=this._getMinMaxDate(c,"max"),n(c.settings,a),null!==h&&a.dateFormat!==e&&a.minDate===e&&(c.settings.minDate=this._formatDate(c,h)),null!==l&&a.dateFormat!==e&&a.maxDate===e&&(c.settings.maxDate=this._formatDate(c,l)),"disabled"in a&&(a.disabled?this._disableDatepicker(i):this._enableDatepicker(i)),this._attachments(t(i),c),this._autoSize(c),this._setDate(c,r),this._updateAlternate(c),this._updateDatepicker(c)),e)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,o=t.datepicker._getInst(e.target),a=!0,r=o.dpDiv.is(".ui-datepicker-rtl");if(o._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),a=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",o.dpDiv),n[0]&&t.datepicker._selectDay(e.target,o.selectedMonth,o.selectedYear,n[0]),i=t.datepicker._get(o,"onSelect"),i?(s=t.datepicker._formatDate(o),i.apply(o.input?o.input[0]:null,[s,o])):t.datepicker._hideDatepicker(),!1;
+case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),a=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),a=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?1:-1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),a=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?-1:1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),a=e.ctrlKey||e.metaKey;break;default:a=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):a=!1;a&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(i){var s,n,o=t.datepicker._getInst(i.target);return t.datepicker._get(o,"constrainInput")?(s=t.datepicker._possibleChars(t.datepicker._get(o,"dateFormat")),n=String.fromCharCode(null==i.charCode?i.keyCode:i.charCode),i.ctrlKey||i.metaKey||" ">n||!s||s.indexOf(n)>-1):e},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var i,s,o,a,r,h,l;i=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==i&&(t.datepicker._curInst.dpDiv.stop(!0,!0),i&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),s=t.datepicker._get(i,"beforeShow"),o=s?s.apply(e,[e,i]):{},o!==!1&&(n(i.settings,o),i.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(i),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),a=!1,t(e).parents().each(function(){return a|="fixed"===t(this).css("position"),!a}),r={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(i),r=t.datepicker._checkOffset(i,r,a),i.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":a?"fixed":"absolute",display:"none",left:r.left+"px",top:r.top+"px"}),i.inline||(h=t.datepicker._get(i,"showAnim"),l=t.datepicker._get(i,"duration"),i.dpDiv.zIndex(t(e).zIndex()+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[h]?i.dpDiv.show(h,t.datepicker._get(i,"showOptions"),l):i.dpDiv[h||"show"](h?l:null),t.datepicker._shouldFocusInput(i)&&i.input.focus(),t.datepicker._curInst=i))}},_updateDatepicker:function(e){this.maxRows=4,o=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var i,s=this._getNumberOfMonths(e),n=s[1],a=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&t.datepicker._shouldFocusInput(e)&&e.input.focus(),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),o=e.dpDiv.outerHeight(),a=e.input?e.input.outerWidth():0,r=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-a:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+r?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+o>l&&l>o?Math.abs(o+r):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,o,r=this._curInst;!r||e&&r!==t.data(e,a)||this._datepickerShowing&&(i=this._get(r,"showAnim"),s=this._get(r,"duration"),n=function(){t.datepicker._tidyDialog(r)},t.effects&&(t.effects.effect[i]||t.effects[i])?r.dpDiv.hide(i,t.datepicker._get(r,"showOptions"),s,n):r.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,o=this._get(r,"onClose"),o&&o.apply(r.input?r.input[0]:null,[r.input?r.input.val():"",r]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),o=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(o,i+("M"===s?this._get(o,"showCurrentAtPos"):0),s),this._updateDatepicker(o))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),o=this._getInst(n[0]);o["selected"+("M"===s?"Month":"Year")]=o["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(o),this._adjustDate(n)},_selectDay:function(e,i,s,n){var o,a=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(a[0])||(o=this._getInst(a[0]),o.selectedDay=o.currentDay=t("a",n).html(),o.selectedMonth=o.currentMonth=i,o.selectedYear=o.currentYear=s,this._selectDate(e,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),o=this._getInst(n[0]);i=null!=i?i:this._formatDate(o),o.input&&o.input.val(i),this._updateAlternate(o),s=this._get(o,"onSelect"),s?s.apply(o.input?o.input[0]:null,[i,o]):o.input&&o.input.trigger("change"),o.inline?this._updateDatepicker(o):(this._hideDatepicker(),this._lastInput=o.input[0],"object"!=typeof o.input[0]&&o.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,o=this._get(e,"altField");o&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(o).each(function(){t(this).val(n)}))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(i,s,n){if(null==i||null==s)throw"Invalid arguments";if(s="object"==typeof s?""+s:s+"",""===s)return null;var o,a,r,h,l=0,c=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff,u="string"!=typeof c?c:(new Date).getFullYear()%100+parseInt(c,10),d=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,p=(n?n.dayNames:null)||this._defaults.dayNames,f=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,g=(n?n.monthNames:null)||this._defaults.monthNames,m=-1,v=-1,_=-1,b=-1,y=!1,w=function(t){var e=i.length>o+1&&i.charAt(o+1)===t;return e&&o++,e},k=function(t){var e=w(t),i="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n=RegExp("^\\d{1,"+i+"}"),o=s.substring(l).match(n);if(!o)throw"Missing number at position "+l;return l+=o[0].length,parseInt(o[0],10)},x=function(i,n,o){var a=-1,r=t.map(w(i)?o:n,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(r,function(t,i){var n=i[1];return s.substr(l,n.length).toLowerCase()===n.toLowerCase()?(a=i[0],l+=n.length,!1):e}),-1!==a)return a+1;throw"Unknown name at position "+l},D=function(){if(s.charAt(l)!==i.charAt(o))throw"Unexpected literal at position "+l;l++};for(o=0;i.length>o;o++)if(y)"'"!==i.charAt(o)||w("'")?D():y=!1;else switch(i.charAt(o)){case"d":_=k("d");break;case"D":x("D",d,p);break;case"o":b=k("o");break;case"m":v=k("m");break;case"M":v=x("M",f,g);break;case"y":m=k("y");break;case"@":h=new Date(k("@")),m=h.getFullYear(),v=h.getMonth()+1,_=h.getDate();break;case"!":h=new Date((k("!")-this._ticksTo1970)/1e4),m=h.getFullYear(),v=h.getMonth()+1,_=h.getDate();break;case"'":w("'")?D():y=!0;break;default:D()}if(s.length>l&&(r=s.substr(l),!/^\s+/.test(r)))throw"Extra/unparsed characters found in date: "+r;if(-1===m?m=(new Date).getFullYear():100>m&&(m+=(new Date).getFullYear()-(new Date).getFullYear()%100+(u>=m?0:-100)),b>-1)for(v=1,_=b;;){if(a=this._getDaysInMonth(m,v-1),a>=_)break;v++,_-=a}if(h=this._daylightSavingAdjust(new Date(m,v-1,_)),h.getFullYear()!==m||h.getMonth()+1!==v||h.getDate()!==_)throw"Invalid date";return h},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,o=(i?i.dayNames:null)||this._defaults.dayNames,a=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,o);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),a,r);break;case"y":u+=h("y")?e.getFullYear():(10>e.getYear()%100?"0":"")+e.getYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,i){return t.settings[i]!==e?t.settings[i]:this._defaults[i]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),o=n,a=this._getFormatConfig(t);try{o=this.parseDate(i,s,a)||n}catch(r){s=e?"":s}t.selectedDay=o.getDate(),t.drawMonth=t.selectedMonth=o.getMonth(),t.drawYear=t.selectedYear=o.getFullYear(),t.currentDay=s?o.getDate():0,t.currentMonth=s?o.getMonth():0,t.currentYear=s?o.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},o=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,o=n.getFullYear(),a=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":a+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a));break;case"y":case"Y":o+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a))}l=h.exec(i)}return new Date(o,a,r)},a=null==i||""===i?s:"string"==typeof i?o(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return a=a&&"Invalid Date"==""+a?s:a,a&&(a.setHours(0),a.setMinutes(0),a.setSeconds(0),a.setMilliseconds(0)),this._daylightSavingAdjust(a)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,o=t.selectedYear,a=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=a.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=a.getMonth(),t.drawYear=t.selectedYear=t.currentYear=a.getFullYear(),n===t.selectedMonth&&o===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){t.datepicker._adjustDate(s,-i,"M")},next:function(){t.datepicker._adjustDate(s,+i,"M")},hide:function(){t.datepicker._hideDatepicker()},today:function(){t.datepicker._gotoToday(s)},selectDay:function(){return t.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return t.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return t.datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,o,a,r,h,l,c,u,d,p,f,g,m,v,_,b,y,w,k,x,D,C,I,P,T,M,S,z,A,H,E,N,W,O,F,R,L=new Date,j=this._daylightSavingAdjust(new Date(L.getFullYear(),L.getMonth(),L.getDate())),Y=this._get(t,"isRTL"),B=this._get(t,"showButtonPanel"),V=this._get(t,"hideIfNoPrevNext"),K=this._get(t,"navigationAsDateFormat"),U=this._getNumberOfMonths(t),q=this._get(t,"showCurrentAtPos"),Q=this._get(t,"stepMonths"),X=1!==U[0]||1!==U[1],$=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),G=this._getMinMaxDate(t,"min"),J=this._getMinMaxDate(t,"max"),Z=t.drawMonth-q,te=t.drawYear;if(0>Z&&(Z+=12,te--),J)for(e=this._daylightSavingAdjust(new Date(J.getFullYear(),J.getMonth()-U[0]*U[1]+1,J.getDate())),e=G&&G>e?G:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=K?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-Q,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":V?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(t,"nextText"),n=K?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+Q,1)),this._getFormatConfig(t)):n,o=this._canAdjustMonth(t,1,te,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":V?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",a=this._get(t,"currentText"),r=this._get(t,"gotoCurrent")&&t.currentDay?$:j,a=K?this.formatDate(a,r,this._getFormatConfig(t)):a,h=t.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(t,"closeText")+"</button>",l=B?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(t,r)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+a+"</button>":"")+(Y?"":h)+"</div>":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),g=this._get(t,"monthNamesShort"),m=this._get(t,"beforeShowDay"),v=this._get(t,"showOtherMonths"),_=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;U[0]>k;k++){for(x="",this.maxRows=4,D=0;U[1]>D;D++){if(C=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),I=" ui-corner-all",P="",X){if(P+="<div class='ui-datepicker-group",U[1]>1)switch(D){case 0:P+=" ui-datepicker-group-first",I=" ui-corner-"+(Y?"right":"left");break;case U[1]-1:P+=" ui-datepicker-group-last",I=" ui-corner-"+(Y?"left":"right");break;default:P+=" ui-datepicker-group-middle",I=""}P+="'>"}for(P+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+I+"'>"+(/all|left/.test(I)&&0===k?Y?o:s:"")+(/all|right/.test(I)&&0===k?Y?s:o:"")+this._generateMonthYearHeader(t,Z,te,G,J,k>0||D>0,f,g)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",T=u?"<th class='ui-datepicker-week-col'>"+this._get(t,"weekHeader")+"</th>":"",w=0;7>w;w++)M=(w+c)%7,T+="<th"+((w+c+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+d[M]+"'>"+p[M]+"</span></th>";for(P+=T+"</tr></thead><tbody>",S=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,S)),z=(this._getFirstDayOfMonth(te,Z)-c+7)%7,A=Math.ceil((z+S)/7),H=X?this.maxRows>A?this.maxRows:A:A,this.maxRows=H,E=this._daylightSavingAdjust(new Date(te,Z,1-z)),N=0;H>N;N++){for(P+="<tr>",W=u?"<td class='ui-datepicker-week-col'>"+this._get(t,"calculateWeek")(E)+"</td>":"",w=0;7>w;w++)O=m?m.apply(t.input?t.input[0]:null,[E]):[!0,""],F=E.getMonth()!==Z,R=F&&!_||!O[0]||G&&G>E||J&&E>J,W+="<td class='"+((w+c+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(E.getTime()===C.getTime()&&Z===t.selectedMonth&&t._keyEvent||b.getTime()===E.getTime()&&b.getTime()===C.getTime()?" "+this._dayOverClass:"")+(R?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!v?"":" "+O[1]+(E.getTime()===$.getTime()?" "+this._currentClass:"")+(E.getTime()===j.getTime()?" ui-datepicker-today":""))+"'"+(F&&!v||!O[2]?"":" title='"+O[2].replace(/'/g,"&#39;")+"'")+(R?"":" data-handler='selectDay' data-event='click' data-month='"+E.getMonth()+"' data-year='"+E.getFullYear()+"'")+">"+(F&&!v?"&#xa0;":R?"<span class='ui-state-default'>"+E.getDate()+"</span>":"<a class='ui-state-default"+(E.getTime()===j.getTime()?" ui-state-highlight":"")+(E.getTime()===$.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+"' href='#'>"+E.getDate()+"</a>")+"</td>",E.setDate(E.getDate()+1),E=this._daylightSavingAdjust(E);P+=W+"</tr>"}Z++,Z>11&&(Z=0,te++),P+="</tbody></table>"+(X?"</div>"+(U[0]>0&&D===U[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),x+=P}y+=x}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var h,l,c,u,d,p,f,g,m=this._get(t,"changeMonth"),v=this._get(t,"changeYear"),_=this._get(t,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",y="";if(o||!m)y+="<span class='ui-datepicker-month'>"+a[e]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",c=0;12>c;c++)(!h||c>=s.getMonth())&&(!l||n.getMonth()>=c)&&(y+="<option value='"+c+"'"+(c===e?" selected='selected'":"")+">"+r[c]+"</option>");y+="</select>"}if(_||(b+=y+(!o&&m&&v?"":"&#xa0;")),!t.yearshtml)if(t.yearshtml="",o||!v)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);return isNaN(e)?d:e},f=p(u[0]),g=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,g=n?Math.min(g,n.getFullYear()):g,t.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";g>=f;f++)t.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";t.yearshtml+="</select>",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),_&&(b+=(!o&&m&&v?"":"&#xa0;")+y),b+="</div>"},_adjustInstDate:function(t,e,i){var s=t.drawYear+("Y"===i?e:0),n=t.drawMonth+("M"===i?e:0),o=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),a=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,o)));t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),o=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&o.setDate(this._getDaysInMonth(o.getFullYear(),o.getMonth())),this._isInRange(t,o)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),o=this._getMinMaxDate(t,"max"),a=null,r=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),a=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(a+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||e.getTime()>=n.getTime())&&(!o||e.getTime()<=o.getTime())&&(!a||e.getFullYear()>=a)&&(!r||r>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).mousedown(t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new i,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.10.3"}(jQuery),function(t){var e={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};t.widget("ui.dialog",{version:"1.10.3",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:t.noop,enable:t.noop,close:function(e){var i=this;this._isOpen&&this._trigger("beforeClose",e)!==!1&&(this._isOpen=!1,this._destroyOverlay(),this.opener.filter(":focusable").focus().length||t(this.document[0].activeElement).blur(),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,e){var i=!!this.uiDialog.nextAll(":visible").insertBefore(this.uiDialog).length;return i&&!e&&this._trigger("focus",t),i},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),undefined):(this._isOpen=!0,this.opener=t(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._trigger("open"),undefined)},_focusTabbable:function(){var t=this.element.find("[autofocus]");t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).focus()},_keepFocus:function(e){function i(){var e=this.document[0].activeElement,i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),undefined;if(e.keyCode===t.ui.keyCode.TAB){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(n.focus(1),e.preventDefault()):(s.focus(1),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=t("<button></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(e),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title||t.html("&#160;"),t.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=t("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),undefined):(t.each(i,function(i,s){var n,o;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,s.click=function(){n.apply(e.element[0],arguments)},o={icons:s.icons,text:s.showText},delete s.icons,delete s.showText,t("<button></button>",s).button(o).appendTo(e.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),undefined)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){t(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,o){s.position=[o.position.left-i.document.scrollLeft(),o.position.top-i.document.scrollTop()],t(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(o))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}
+}var i=this,s=this.options,n=s.resizable,o=this.uiDialog.css("position"),a="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:a,start:function(s,n){t(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,o){s.height=t(this).height(),s.width=t(this).width(),t(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(o))}}).css("position",o)},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(s){var n=this,o=!1,a={};t.each(s,function(t,s){n._setOption(t,s),t in e&&(o=!0),t in i&&(a[t]=s)}),o&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",a)},_setOption:function(t,e){var i,s,n=this.uiDialog;"dialogClass"===t&&n.removeClass(this.options.dialogClass).addClass(e),"disabled"!==t&&(this._super(t,e),"appendTo"===t&&this.uiDialog.appendTo(this._appendTo()),"buttons"===t&&this._createButtons(),"closeText"===t&&this.uiDialogTitlebarClose.button({label:""+e}),"draggable"===t&&(i=n.is(":data(ui-draggable)"),i&&!e&&n.draggable("destroy"),!i&&e&&this._makeDraggable()),"position"===t&&this._position(),"resizable"===t&&(s=n.is(":data(ui-resizable)"),s&&!e&&n.resizable("destroy"),s&&"string"==typeof e&&n.resizable("option","handles",e),s||e===!1||this._makeResizable()),"title"===t&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("<div>").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=this,i=this.widgetFullName;t.ui.dialog.overlayInstances||this._delay(function(){t.ui.dialog.overlayInstances&&this.document.bind("focusin.dialog",function(s){e._allowInteraction(s)||(s.preventDefault(),t(".ui-dialog:visible:last .ui-dialog-content").data(i)._focusTabbable())})}),this.overlay=t("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),t.ui.dialog.overlayInstances++}},_destroyOverlay:function(){this.options.modal&&this.overlay&&(t.ui.dialog.overlayInstances--,t.ui.dialog.overlayInstances||this.document.unbind("focusin.dialog"),this.overlay.remove(),this.overlay=null)}}),t.ui.dialog.overlayInstances=0,t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{_position:function(){var e,i=this.options.position,s=[],n=[0,0];i?(("string"==typeof i||"object"==typeof i&&"0"in i)&&(s=i.split?i.split(" "):[i[0],i[1]],1===s.length&&(s[1]=s[0]),t.each(["left","top"],function(t,e){+s[t]===s[t]&&(n[t]=s[t],s[t]=e)}),i={my:s[0]+(0>n[0]?n[0]:"+"+n[0])+" "+s[1]+(0>n[1]?n[1]:"+"+n[1]),at:s.join(" ")}),i=t.extend({},t.ui.dialog.prototype.options.position,i)):i=t.ui.dialog.prototype.options.position,e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.position(i),e||this.uiDialog.hide()}})}(jQuery),function(t){var e=/up|down|vertical/,i=/up|left|vertical|horizontal/;t.effects.effect.blind=function(s,n){var o,a,r,h=t(this),l=["position","top","bottom","left","right","height","width"],c=t.effects.setMode(h,s.mode||"hide"),u=s.direction||"up",d=e.test(u),p=d?"height":"width",f=d?"top":"left",g=i.test(u),m={},v="show"===c;h.parent().is(".ui-effects-wrapper")?t.effects.save(h.parent(),l):t.effects.save(h,l),h.show(),o=t.effects.createWrapper(h).css({overflow:"hidden"}),a=o[p](),r=parseFloat(o.css(f))||0,m[p]=v?a:0,g||(h.css(d?"bottom":"right",0).css(d?"top":"left","auto").css({position:"absolute"}),m[f]=v?r:a+r),v&&(o.css(p,0),g||o.css(f,r+a)),o.animate(m,{duration:s.duration,easing:s.easing,queue:!1,complete:function(){"hide"===c&&h.hide(),t.effects.restore(h,l),t.effects.removeWrapper(h),n()}})}}(jQuery),function(t){t.effects.effect.bounce=function(e,i){var s,n,o,a=t(this),r=["position","top","bottom","left","right","height","width"],h=t.effects.setMode(a,e.mode||"effect"),l="hide"===h,c="show"===h,u=e.direction||"up",d=e.distance,p=e.times||5,f=2*p+(c||l?1:0),g=e.duration/f,m=e.easing,v="up"===u||"down"===u?"top":"left",_="up"===u||"left"===u,b=a.queue(),y=b.length;for((c||l)&&r.push("opacity"),t.effects.save(a,r),a.show(),t.effects.createWrapper(a),d||(d=a["top"===v?"outerHeight":"outerWidth"]()/3),c&&(o={opacity:1},o[v]=0,a.css("opacity",0).css(v,_?2*-d:2*d).animate(o,g,m)),l&&(d/=Math.pow(2,p-1)),o={},o[v]=0,s=0;p>s;s++)n={},n[v]=(_?"-=":"+=")+d,a.animate(n,g,m).animate(o,g,m),d=l?2*d:d/2;l&&(n={opacity:0},n[v]=(_?"-=":"+=")+d,a.animate(n,g,m)),a.queue(function(){l&&a.hide(),t.effects.restore(a,r),t.effects.removeWrapper(a),i()}),y>1&&b.splice.apply(b,[1,0].concat(b.splice(y,f+1))),a.dequeue()}}(jQuery),function(t){t.effects.effect.clip=function(e,i){var s,n,o,a=t(this),r=["position","top","bottom","left","right","height","width"],h=t.effects.setMode(a,e.mode||"hide"),l="show"===h,c=e.direction||"vertical",u="vertical"===c,d=u?"height":"width",p=u?"top":"left",f={};t.effects.save(a,r),a.show(),s=t.effects.createWrapper(a).css({overflow:"hidden"}),n="IMG"===a[0].tagName?s:a,o=n[d](),l&&(n.css(d,0),n.css(p,o/2)),f[d]=l?o:0,f[p]=l?0:o/2,n.animate(f,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){l||a.hide(),t.effects.restore(a,r),t.effects.removeWrapper(a),i()}})}}(jQuery),function(t){t.effects.effect.drop=function(e,i){var s,n=t(this),o=["position","top","bottom","left","right","opacity","height","width"],a=t.effects.setMode(n,e.mode||"hide"),r="show"===a,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h?"pos":"neg",u={opacity:r?1:0};t.effects.save(n,o),n.show(),t.effects.createWrapper(n),s=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0)/2,r&&n.css("opacity",0).css(l,"pos"===c?-s:s),u[l]=(r?"pos"===c?"+=":"-=":"pos"===c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===a&&n.hide(),t.effects.restore(n,o),t.effects.removeWrapper(n),i()}})}}(jQuery),function(t){t.effects.effect.explode=function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),g||p.hide(),i()}var o,a,r,h,l,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=t.effects.setMode(p,e.mode||"hide"),g="show"===f,m=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/d),_=Math.ceil(p.outerHeight()/u),b=[];for(o=0;u>o;o++)for(h=m.top+o*_,c=o-(u-1)/2,a=0;d>a;a++)r=m.left+a*v,l=a-(d-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-a*v,top:-o*_}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:_,left:r+(g?l*v:0),top:h+(g?c*_:0),opacity:g?0:1}).animate({left:r+(g?0:l*v),top:h+(g?0:c*_),opacity:g?1:0},e.duration||500,e.easing,s)}}(jQuery),function(t){t.effects.effect.fade=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"toggle");s.animate({opacity:n},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}}(jQuery),function(t){t.effects.effect.fold=function(e,i){var s,n,o=t(this),a=["position","top","bottom","left","right","height","width"],r=t.effects.setMode(o,e.mode||"hide"),h="show"===r,l="hide"===r,c=e.size||15,u=/([0-9]+)%/.exec(c),d=!!e.horizFirst,p=h!==d,f=p?["width","height"]:["height","width"],g=e.duration/2,m={},v={};t.effects.save(o,a),o.show(),s=t.effects.createWrapper(o).css({overflow:"hidden"}),n=p?[s.width(),s.height()]:[s.height(),s.width()],u&&(c=parseInt(u[1],10)/100*n[l?0:1]),h&&s.css(d?{height:0,width:c}:{height:c,width:0}),m[f[0]]=h?n[0]:c,v[f[1]]=h?n[1]:0,s.animate(m,g,e.easing).animate(v,g,e.easing,function(){l&&o.hide(),t.effects.restore(o,a),t.effects.removeWrapper(o),i()})}}(jQuery),function(t){t.effects.effect.highlight=function(e,i){var s=t(this),n=["backgroundImage","backgroundColor","opacity"],o=t.effects.setMode(s,e.mode||"show"),a={backgroundColor:s.css("backgroundColor")};"hide"===o&&(a.opacity=0),t.effects.save(s,n),s.show().css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(a,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===o&&s.hide(),t.effects.restore(s,n),i()}})}}(jQuery),function(t){t.effects.effect.pulsate=function(e,i){var s,n=t(this),o=t.effects.setMode(n,e.mode||"show"),a="show"===o,r="hide"===o,h=a||"hide"===o,l=2*(e.times||5)+(h?1:0),c=e.duration/l,u=0,d=n.queue(),p=d.length;for((a||!n.is(":visible"))&&(n.css("opacity",0).show(),u=1),s=1;l>s;s++)n.animate({opacity:u},c,e.easing),u=1-u;n.animate({opacity:u},c,e.easing),n.queue(function(){r&&n.hide(),i()}),p>1&&d.splice.apply(d,[1,0].concat(d.splice(p,l+1))),n.dequeue()}}(jQuery),function(t){t.effects.effect.puff=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"hide"),o="hide"===n,a=parseInt(e.percent,10)||150,r=a/100,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};t.extend(e,{effect:"scale",queue:!1,fade:!0,mode:n,complete:i,percent:o?a:100,from:o?h:{height:h.height*r,width:h.width*r,outerHeight:h.outerHeight*r,outerWidth:h.outerWidth*r}}),s.effect(e)},t.effects.effect.scale=function(e,i){var s=t(this),n=t.extend(!0,{},e),o=t.effects.setMode(s,e.mode||"effect"),a=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"hide"===o?0:100),r=e.direction||"both",h=e.origin,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},c={y:"horizontal"!==r?a/100:1,x:"vertical"!==r?a/100:1};n.effect="size",n.queue=!1,n.complete=i,"effect"!==o&&(n.origin=h||["middle","center"],n.restore=!0),n.from=e.from||("show"===o?{height:0,width:0,outerHeight:0,outerWidth:0}:l),n.to={height:l.height*c.y,width:l.width*c.x,outerHeight:l.outerHeight*c.y,outerWidth:l.outerWidth*c.x},n.fade&&("show"===o&&(n.from.opacity=0,n.to.opacity=1),"hide"===o&&(n.from.opacity=1,n.to.opacity=0)),s.effect(n)},t.effects.effect.size=function(e,i){var s,n,o,a=t(this),r=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],l=["width","height","overflow"],c=["fontSize"],u=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],d=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=t.effects.setMode(a,e.mode||"effect"),f=e.restore||"effect"!==p,g=e.scale||"both",m=e.origin||["middle","center"],v=a.css("position"),_=f?r:h,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&a.show(),s={height:a.height(),width:a.width(),outerHeight:a.outerHeight(),outerWidth:a.outerWidth()},"toggle"===e.mode&&"show"===p?(a.from=e.to||b,a.to=e.from||s):(a.from=e.from||("show"===p?b:s),a.to=e.to||("hide"===p?b:s)),o={from:{y:a.from.height/s.height,x:a.from.width/s.width},to:{y:a.to.height/s.height,x:a.to.width/s.width}},("box"===g||"both"===g)&&(o.from.y!==o.to.y&&(_=_.concat(u),a.from=t.effects.setTransition(a,u,o.from.y,a.from),a.to=t.effects.setTransition(a,u,o.to.y,a.to)),o.from.x!==o.to.x&&(_=_.concat(d),a.from=t.effects.setTransition(a,d,o.from.x,a.from),a.to=t.effects.setTransition(a,d,o.to.x,a.to))),("content"===g||"both"===g)&&o.from.y!==o.to.y&&(_=_.concat(c).concat(l),a.from=t.effects.setTransition(a,c,o.from.y,a.from),a.to=t.effects.setTransition(a,c,o.to.y,a.to)),t.effects.save(a,_),a.show(),t.effects.createWrapper(a),a.css("overflow","hidden").css(a.from),m&&(n=t.effects.getBaseline(m,s),a.from.top=(s.outerHeight-a.outerHeight())*n.y,a.from.left=(s.outerWidth-a.outerWidth())*n.x,a.to.top=(s.outerHeight-a.to.outerHeight)*n.y,a.to.left=(s.outerWidth-a.to.outerWidth)*n.x),a.css(a.from),("content"===g||"both"===g)&&(u=u.concat(["marginTop","marginBottom"]).concat(c),d=d.concat(["marginLeft","marginRight"]),l=r.concat(u).concat(d),a.find("*[width]").each(function(){var i=t(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};f&&t.effects.save(i,l),i.from={height:s.height*o.from.y,width:s.width*o.from.x,outerHeight:s.outerHeight*o.from.y,outerWidth:s.outerWidth*o.from.x},i.to={height:s.height*o.to.y,width:s.width*o.to.x,outerHeight:s.height*o.to.y,outerWidth:s.width*o.to.x},o.from.y!==o.to.y&&(i.from=t.effects.setTransition(i,u,o.from.y,i.from),i.to=t.effects.setTransition(i,u,o.to.y,i.to)),o.from.x!==o.to.x&&(i.from=t.effects.setTransition(i,d,o.from.x,i.from),i.to=t.effects.setTransition(i,d,o.to.x,i.to)),i.css(i.from),i.animate(i.to,e.duration,e.easing,function(){f&&t.effects.restore(i,l)})})),a.animate(a.to,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){0===a.to.opacity&&a.css("opacity",a.from.opacity),"hide"===p&&a.hide(),t.effects.restore(a,_),f||("static"===v?a.css({position:"relative",top:a.to.top,left:a.to.left}):t.each(["top","left"],function(t,e){a.css(e,function(e,i){var s=parseInt(i,10),n=t?a.to.left:a.to.top;return"auto"===i?n+"px":s+n+"px"})})),t.effects.removeWrapper(a),i()}})}}(jQuery),function(t){t.effects.effect.shake=function(e,i){var s,n=t(this),o=["position","top","bottom","left","right","height","width"],a=t.effects.setMode(n,e.mode||"effect"),r=e.direction||"left",h=e.distance||20,l=e.times||3,c=2*l+1,u=Math.round(e.duration/c),d="up"===r||"down"===r?"top":"left",p="up"===r||"left"===r,f={},g={},m={},v=n.queue(),_=v.length;for(t.effects.save(n,o),n.show(),t.effects.createWrapper(n),f[d]=(p?"-=":"+=")+h,g[d]=(p?"+=":"-=")+2*h,m[d]=(p?"-=":"+=")+2*h,n.animate(f,u,e.easing),s=1;l>s;s++)n.animate(g,u,e.easing).animate(m,u,e.easing);n.animate(g,u,e.easing).animate(f,u/2,e.easing).queue(function(){"hide"===a&&n.hide(),t.effects.restore(n,o),t.effects.removeWrapper(n),i()}),_>1&&v.splice.apply(v,[1,0].concat(v.splice(_,c+1))),n.dequeue()}}(jQuery),function(t){t.effects.effect.slide=function(e,i){var s,n=t(this),o=["position","top","bottom","left","right","width","height"],a=t.effects.setMode(n,e.mode||"show"),r="show"===a,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,u={};t.effects.save(n,o),n.show(),s=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0),t.effects.createWrapper(n).css({overflow:"hidden"}),r&&n.css(l,c?isNaN(s)?"-"+s:-s:s),u[l]=(r?c?"+=":"-=":c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===a&&n.hide(),t.effects.restore(n,o),t.effects.removeWrapper(n),i()}})}}(jQuery),function(t){t.effects.effect.transfer=function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,h=o?a.scrollLeft():0,l=n.offset(),c={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("<div class='ui-effects-transfer'></div>").appendTo(document.body).addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),i()})}}(jQuery),function(t){t.widget("ui.menu",{version:"1.10.3",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,t.proxy(function(t){this.options.disabled&&t.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(t){t.preventDefault()},"click .ui-state-disabled > a":function(t){t.preventDefault()},"click .ui-menu-item:has(a)":function(e){var i=t(e.target).closest(".ui-menu-item");!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.mouseHandled=!0,this.select(e),i.has(".ui-menu").length?this.expand(e):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){var i=t(e.currentTarget);i.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(e,i)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.children(".ui-menu-item").eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){t.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(e){t(e.target).closest(".ui-menu").length||this.collapseAll(e),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var e=t(this);e.data("ui-menu-submenu-carat")&&e.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(e){function i(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var s,n,o,a,r,h=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:h=!1,n=this.previousFilter||"",o=String.fromCharCode(e.keyCode),a=!1,clearTimeout(this.filterTimer),o===n?a=!0:o=n+o,r=RegExp("^"+i(o),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return r.test(t(this).children("a").text())}),s=a&&-1!==s.index(this.active.next())?this.active.nextAll(".ui-menu-item"):s,s.length||(o=String.fromCharCode(e.keyCode),r=RegExp("^"+i(o),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return r.test(t(this).children("a").text())})),s.length?(this.focus(e,s),s.length>1?(this.previousFilter=o,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}h&&e.preventDefault()},_activate:function(t){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i=this.options.icons.submenu,s=this.element.find(this.options.menus);s.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),s=e.prev("a"),n=t("<span>").addClass("ui-menu-icon ui-icon "+i).data("ui-menu-submenu-carat",!0);s.attr("aria-haspopup","true").prepend(n),e.attr("aria-labelledby",s.attr("id"))}),e=s.add(this.element),e.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),e.children(":not(.ui-menu-item)").each(function(){var e=t(this);/[^\-\u2014\u2013\s]/.test(e.text())||e.addClass("ui-widget-content ui-menu-divider")}),e.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){"icons"===t&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(e.submenu),this._super(t,e)},focus:function(t,e){var i,s;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.height(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",t,{item:this.active}))},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.children(".ui-menu-item")[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())),undefined):(this.next(e),undefined)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.children(".ui-menu-item").first())),undefined):(this.next(e),undefined)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(e){this.active=this.active||t(e.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(e,!0),this._trigger("select",e,i)}})}(jQuery),function(t,e){function i(t,e,i){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?i/100:1)]}function s(e,i){return parseInt(t.css(e,i),10)||0}function n(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}t.ui=t.ui||{};var o,a=Math.max,r=Math.abs,h=Math.round,l=/left|center|right/,c=/top|center|bottom/,u=/[\+\-]\d+(\.[\d]+)?%?/,d=/^\w+/,p=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(o!==e)return o;var i,s,n=t("<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),a=n.children()[0];return t("body").append(n),i=a.offsetWidth,n.css("overflow","scroll"),s=a.offsetWidth,i===s&&(s=n[0].clientWidth),n.remove(),o=i-s},getScrollInfo:function(e){var i=e.isWindow?"":e.element.css("overflow-x"),s=e.isWindow?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,o="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:o?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]);return{element:i,isWindow:s,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s?i.width():i.outerWidth(),height:s?i.height():i.outerHeight()}}},t.fn.position=function(e){if(!e||!e.of)return f.apply(this,arguments);e=t.extend({},e);var o,p,g,m,v,_,b=t(e.of),y=t.position.getWithinInfo(e.within),w=t.position.getScrollInfo(y),k=(e.collision||"flip").split(" "),x={};return _=n(b),b[0].preventDefault&&(e.at="left top"),p=_.width,g=_.height,m=_.offset,v=t.extend({},m),t.each(["my","at"],function(){var t,i,s=(e[this]||"").split(" ");1===s.length&&(s=l.test(s[0])?s.concat(["center"]):c.test(s[0])?["center"].concat(s):["center","center"]),s[0]=l.test(s[0])?s[0]:"center",s[1]=c.test(s[1])?s[1]:"center",t=u.exec(s[0]),i=u.exec(s[1]),x[this]=[t?t[0]:0,i?i[0]:0],e[this]=[d.exec(s[0])[0],d.exec(s[1])[0]]}),1===k.length&&(k[1]=k[0]),"right"===e.at[0]?v.left+=p:"center"===e.at[0]&&(v.left+=p/2),"bottom"===e.at[1]?v.top+=g:"center"===e.at[1]&&(v.top+=g/2),o=i(x.at,p,g),v.left+=o[0],v.top+=o[1],this.each(function(){var n,l,c=t(this),u=c.outerWidth(),d=c.outerHeight(),f=s(this,"marginLeft"),_=s(this,"marginTop"),D=u+f+s(this,"marginRight")+w.width,C=d+_+s(this,"marginBottom")+w.height,I=t.extend({},v),P=i(x.my,c.outerWidth(),c.outerHeight());"right"===e.my[0]?I.left-=u:"center"===e.my[0]&&(I.left-=u/2),"bottom"===e.my[1]?I.top-=d:"center"===e.my[1]&&(I.top-=d/2),I.left+=P[0],I.top+=P[1],t.support.offsetFractions||(I.left=h(I.left),I.top=h(I.top)),n={marginLeft:f,marginTop:_},t.each(["left","top"],function(i,s){t.ui.position[k[i]]&&t.ui.position[k[i]][s](I,{targetWidth:p,targetHeight:g,elemWidth:u,elemHeight:d,collisionPosition:n,collisionWidth:D,collisionHeight:C,offset:[o[0]+P[0],o[1]+P[1]],my:e.my,at:e.at,within:y,elem:c})}),e.using&&(l=function(t){var i=m.left-I.left,s=i+p-u,n=m.top-I.top,o=n+g-d,h={target:{element:b,left:m.left,top:m.top,width:p,height:g},element:{element:c,left:I.left,top:I.top,width:u,height:d},horizontal:0>s?"left":i>0?"right":"center",vertical:0>o?"top":n>0?"bottom":"middle"};u>p&&p>r(i+s)&&(h.horizontal="center"),d>g&&g>r(n+o)&&(h.vertical="middle"),h.important=a(r(i),r(s))>a(r(n),r(o))?"horizontal":"vertical",e.using.call(this,t,h)}),c.offset(t.extend(I,{using:l}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,o=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-o-n;e.collisionWidth>o?h>0&&0>=l?(i=t.left+h+e.collisionWidth-o-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+o-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=a(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,o=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-o-n;e.collisionHeight>o?h>0&&0>=l?(i=t.top+h+e.collisionHeight-o-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+o-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=a(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,a=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-a-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-a-o,(0>i||r(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>r(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,a=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-a-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-a-o,t.top+p+f+g>c&&(0>s||r(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-h,t.top+p+f+g>u&&(i>0||u>r(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}},function(){var e,i,s,n,o,a=document.getElementsByTagName("body")[0],r=document.createElement("div");e=document.createElement(a?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},a&&t.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(o in s)e.style[o]=s[o];e.appendChild(r),i=a||document.documentElement,i.insertBefore(e,i.firstChild),r.style.cssText="position: absolute; left: 10.7432222px;",n=t(r).offset().left,t.support.offsetFractions=n>10&&11>n,e.innerHTML="",i.removeChild(e)}()}(jQuery),function(t,e){t.widget("ui.progressbar",{version:"1.10.3",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=t("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()
+},value:function(t){return t===e?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),e)},_constrainedValue:function(t){return t===e&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(i.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}})}(jQuery),function(t){var e=5;t.widget("ui.slider",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),o="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e)})},_createRange:function(){var e=this.options,i="";e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=t("<div></div>").appendTo(this.element),i="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(i+("min"===e.range||"max"===e.range?" ui-slider-range-"+e.range:""))):this.range=t([])},_setupEvents:function(){var t=this.handles.add(this.range).filter("a");this._off(t),this._on(t,this._handleEvents),this._hoverable(t),this._focusable(t)},_destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,h,l,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,o.addClass("ui-state-active").focus(),h=o.offset(),l=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:e.pageX-h.left-o.width()/2,top:e.pageY-h.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_start:function(t,e){var i={handle:this.handles[e],value:this.value()};return this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._trigger("start",t,i)},_slide:function(t,e,i){var s,n,o;this.options.values&&this.options.values.length?(s=this.values(e?0:1),2===this.options.values.length&&this.options.range===!0&&(0===e&&i>s||1===e&&s>i)&&(i=s),i!==this.values(e)&&(n=this.values(),n[e]=i,o=this._trigger("slide",t,{handle:this.handles[e],value:i,values:n}),s=this.values(e?0:1),o!==!1&&this.values(e,i,!0))):i!==this.value()&&(o=this._trigger("slide",t,{handle:this.handles[e],value:i}),o!==!1&&this.value(i))},_stop:function(t,e){var i={handle:this.handles[e],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._trigger("stop",t,i)},_change:function(t,e){if(!this._keySliding&&!this._mouseSliding){var i={handle:this.handles[e],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._lastChangedValue=e,this._trigger("change",t,i)}},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),undefined):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),undefined;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),t.Widget.prototype._setOption.apply(this,arguments),e){case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=0;n>s;s+=1)this._change(null,s);this._animateOff=!1;break;case"min":case"max":this._animateOff=!0,this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this.options.values&&this.options.values.length){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,c={};this.options.values&&this.options.values.length?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),c["horizontal"===h.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[l?"animate":"css"](c,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range[l?"animate":"css"]({width:100-i+"%"},{queue:!1,duration:r.animate}),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range[l?"animate":"css"]({height:100-i+"%"},{queue:!1,duration:r.animate}))},_handleEvents:{keydown:function(i){var s,n,o,a,r=t(i.target).data("ui-slider-handle-index");switch(i.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(i.preventDefault(),!this._keySliding&&(this._keySliding=!0,t(i.target).addClass("ui-state-active"),s=this._start(i,r),s===!1))return}switch(a=this.options.step,n=o=this.options.values&&this.options.values.length?this.values(r):this.value(),i.keyCode){case t.ui.keyCode.HOME:o=this._valueMin();break;case t.ui.keyCode.END:o=this._valueMax();break;case t.ui.keyCode.PAGE_UP:o=this._trimAlignValue(n+(this._valueMax()-this._valueMin())/e);break;case t.ui.keyCode.PAGE_DOWN:o=this._trimAlignValue(n-(this._valueMax()-this._valueMin())/e);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(n===this._valueMax())return;o=this._trimAlignValue(n+a);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(n===this._valueMin())return;o=this._trimAlignValue(n-a)}this._slide(i,r,o)},click:function(t){t.preventDefault()},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),t(e.target).removeClass("ui-state-active"))}}})}(jQuery),function(t){function e(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.widget("ui.spinner",{version:"1.10.3",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e={},i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);void 0!==n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var t=this.element[0]===this.document[0].activeElement;t||(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var t=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=t.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*t.height())&&t.height()>0&&t.height(t.height()),this.options.disabled&&this.disable()},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>&#9650;</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>&#9660;</span>"+"</a>"},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){if("culture"===t||"numberFormat"===t){var i=this._parse(this.element.val());return this.options[t]=e,this.element.val(this._format(i)),void 0}("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(this.buttons.first().find(".ui-icon").removeClass(this.options.icons.up).addClass(e.up),this.buttons.last().find(".ui-icon").removeClass(this.options.icons.down).addClass(e.down)),this._super(t,e),"disabled"===t&&(e?(this.element.prop("disabled",!0),this.buttons.button("disable")):(this.element.prop("disabled",!1),this.buttons.button("enable")))},_setOptions:e(function(t){this._super(t),this._value(this.element.val())}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:e(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:e(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:e(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:e(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(e(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}})}(jQuery),function(t,e){function i(){return++n}function s(t){return t.hash.length>1&&decodeURIComponent(t.href.replace(o,""))===decodeURIComponent(location.href.replace(o,""))}var n=0,o=/#.*$/;t.widget("ui.tabs",{version:"1.10.3",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var e=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var i=this.options.active,s=this.options.collapsible,n=location.hash.substring(1);return null===i&&(n&&this.tabs.each(function(s,o){return t(o).attr("aria-controls")===n?(i=s,!1):e}),null===i&&(i=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===i||-1===i)&&(i=this.tabs.length?0:!1)),i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),-1===i&&(i=s?!1:0)),!s&&i===!1&&this.anchors.length&&(i=0),i},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(i){var s=t(this.document[0].activeElement).closest("li"),n=this.tabs.index(s),o=!0;if(!this._handlePageNav(i)){switch(i.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:n++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:o=!1,n--;break;case t.ui.keyCode.END:n=this.anchors.length-1;break;case t.ui.keyCode.HOME:n=0;break;case t.ui.keyCode.SPACE:return i.preventDefault(),clearTimeout(this.activating),this._activate(n),e;case t.ui.keyCode.ENTER:return i.preventDefault(),clearTimeout(this.activating),this._activate(n===this.options.active?!1:n),e;default:return}i.preventDefault(),clearTimeout(this.activating),n=this._focusNextTab(n,o),i.ctrlKey||(s.attr("aria-selected","false"),this.tabs.eq(n).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",n)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.focus())},_handlePageNav:function(i){return i.altKey&&i.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):i.altKey&&i.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):e},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).focus(),t},_setOption:function(t,i){return"active"===t?(this._activate(i),e):"disabled"===t?(this._setupDisabled(i),e):(this._super(t,i),"collapsible"===t&&(this.element.toggleClass("ui-tabs-collapsible",i),i||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(i),"heightStyle"===t&&this._setupHeightStyle(i),e)},_tabId:function(t){return t.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=t(),this.anchors.each(function(i,n){var o,a,r,h=t(n).uniqueId().attr("id"),l=t(n).closest("li"),c=l.attr("aria-controls");s(n)?(o=n.hash,a=e.element.find(e._sanitizeSelector(o))):(r=e._tabId(l),o="#"+r,a=e.element.find(o),a.length||(a=e._createPanel(r),a.insertAfter(e.panels[i-1]||e.tablist)),a.attr("aria-live","polite")),a.length&&(e.panels=e.panels.add(a)),c&&l.data("ui-tabs-aria-controls",c),l.attr({"aria-controls":o.substring(1),"aria-labelledby":h}),a.attr("aria-labelledby",h)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(e){t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1);for(var i,s=0;i=this.tabs[s];s++)e===!0||-1!==t.inArray(s,e)?t(i).addClass("ui-state-disabled").attr("aria-disabled","true"):t(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=e},_setupEvents:function(e){var i={click:function(t){t.preventDefault()}};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,h=r?t():this._getPanelForTab(o),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():o,newPanel:h};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr({"aria-expanded":"false","aria-hidden":"true"}),i.oldTab.attr("aria-selected","false"),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr({"aria-expanded":"true","aria-hidden":"false"}),i.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(t){return"string"==typeof t&&(t=this.anchors.index(this.anchors.filter("[href$='"+t+"']"))),t},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var s=this.options.disabled;s!==!1&&(i===e?s=!1:(i=this._getIndex(i),s=t.isArray(s)?t.map(s,function(t){return t!==i?t:null}):t.map(this.tabs,function(t,e){return e!==i?e:null})),this._setupDisabled(s))},disable:function(i){var s=this.options.disabled;if(s!==!0){if(i===e)s=!0;else{if(i=this._getIndex(i),-1!==t.inArray(i,s))return;s=t.isArray(s)?t.merge([i],s).sort():[i]}this._setupDisabled(s)}},load:function(e,i){e=this._getIndex(e);var n=this,o=this.tabs.eq(e),a=o.find(".ui-tabs-anchor"),r=this._getPanelForTab(o),h={tab:o,panel:r};s(a[0])||(this.xhr=t.ajax(this._ajaxSettings(a,i,h)),this.xhr&&"canceled"!==this.xhr.statusText&&(o.addClass("ui-tabs-loading"),r.attr("aria-busy","true"),this.xhr.success(function(t){setTimeout(function(){r.html(t),n._trigger("load",i,h)},1)}).complete(function(t,e){setTimeout(function(){"abort"===e&&n.panels.stop(!1,!0),o.removeClass("ui-tabs-loading"),r.removeAttr("aria-busy"),t===n.xhr&&delete n.xhr},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href"),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})}(jQuery),function(t){function e(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))}function i(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")}var s=0;t.widget("ui.tooltip",{version:"1.10.3",options:{content:function(){var e=t(this).attr("title")||"";return t("<a>").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(e,i){var s=this;return"disabled"===e?(this[i?"_disable":"_enable"](),this.options[e]=i,void 0):(this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e)}),void 0)},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0)}),this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.is("[title]")&&e.data("ui-tooltip-title",e.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))})},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s?this._open(e,t,s):(i=s.call(t[0],function(i){t.data("ui-tooltip-open")&&n._delay(function(){e&&(e.type=o),this._open(e,t,i)})}),i&&this._open(e,t,i),void 0)},_open:function(i,s,n){function o(t){l.of=t,a.is(":hidden")||a.position(l)}var a,r,h,l=t.extend({},this.options.position);
+if(n){if(a=this._find(s),a.length)return a.find(".ui-tooltip-content").html(n),void 0;s.is("[title]")&&(i&&"mouseover"===i.type?s.attr("title",""):s.removeAttr("title")),a=this._tooltip(s),e(s,a.attr("id")),a.find(".ui-tooltip-content").html(n),this.options.track&&i&&/^mouse/.test(i.type)?(this._on(this.document,{mousemove:o}),o(i)):a.position(t.extend({of:s},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.show&&this.options.show.delay&&(h=this.delayedShow=setInterval(function(){a.is(":visible")&&(o(l.of),clearInterval(h))},t.fx.interval)),this._trigger("open",i,{tooltip:a}),r={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var i=t.Event(e);i.currentTarget=s[0],this.close(i,!0)}},remove:function(){this._removeTooltip(a)}},i&&"mouseover"!==i.type||(r.mouseleave="close"),i&&"focusin"!==i.type||(r.focusout="close"),this._on(!0,s,r)}},close:function(e){var s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);this.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&n.attr("title",n.data("ui-tooltip-title")),i(n),o.stop(!0),this._hide(o,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]}),this.closing=!0,this._trigger("close",e,{tooltip:o}),this.closing=!1)},_tooltip:function(e){var i="ui-tooltip-"+s++,n=t("<div>").attr({id:i,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return t("<div>").addClass("ui-tooltip-content").appendTo(n),n.appendTo(this.document[0].body),this.tooltips[i]=e,n},_find:function(e){var i=e.data("ui-tooltip-id");return i?t("#"+i):t()},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0),t("#"+i).remove(),s.data("ui-tooltip-title")&&(s.attr("title",s.data("ui-tooltip-title")),s.removeData("ui-tooltip-title"))})}})}(jQuery);
\ No newline at end of file
diff --git a/resources/js/jquery.js b/resources/js/jquery.js
new file mode 100644
index 0000000..2be209d
--- /dev/null
+++ b/resources/js/jquery.js
@@ -0,0 +1,6 @@
+/*! jQuery v2.0.3 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
+//@ sourceMappingURL=jquery-2.0.3.min.map
+*/
+(function(e,undefined){var t,n,r=typeof undefined,i=e.location,o=e.document,s=o.documentElement,a=e.jQuery,u=e.$,l={},c=[],p="2.0.3",f=c.concat,h=c.push,d=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,x=function(e,n){return new x.fn.init(e,n,t)},b=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^-ms-/,N=/-([\da-z])/gi,E=function(e,t){return t.toUpperCase()},S=function(){o.removeEventListener("DOMContentLoaded",S,!1),e.removeEventListener("load",S,!1),x.ready()};x.fn=x.prototype={jquery:p,constructor:x,init:function(e,t,n){var r,i;if(!e)return this;if("string"==typeof e){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:T.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof x?t[0]:t,x.merge(this,x.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:o,!0)),C.test(r[1])&&x.isPlainObject(t))for(r in t)x.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=o.getElementById(r[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?n.ready(e):(e.selector!==undefined&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return d.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,t,n,r,i,o,s=arguments[0]||{},a=1,u=arguments.length,l=!1;for("boolean"==typeof s&&(l=s,s=arguments[1]||{},a=2),"object"==typeof s||x.isFunction(s)||(s={}),u===a&&(s=this,--a);u>a;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],r=e[t],s!==r&&(l&&r&&(x.isPlainObject(r)||(i=x.isArray(r)))?(i?(i=!1,o=n&&x.isArray(n)?n:[]):o=n&&x.isPlainObject(n)?n:{},s[t]=x.extend(l,o,r)):r!==undefined&&(s[t]=r));return s},x.extend({expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=a),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){(e===!0?--x.readyWait:x.isReady)||(x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(o,[x]),x.fn.trigger&&x(o).trigger("ready").off("ready")))},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if("object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}return!0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:JSON.parse,parseXML:function(e){var t,n;if(!e||"string"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(r){t=undefined}return(!t||t.getElementsByTagName("parsererror").length)&&x.error("Invalid XML: "+e),t},noop:function(){},globalEval:function(e){var t,n=eval;e=x.trim(e),e&&(1===e.indexOf("use strict")?(t=o.createElement("script"),t.text=e,o.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(k,"ms-").replace(N,E)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,s=j(e);if(n){if(s){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(s){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:function(e){return null==e?"":v.call(e)},makeArray:function(e,t){var n=t||[];return null!=e&&(j(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:g.call(t,e,n)},merge:function(e,t){var n=t.length,r=e.length,i=0;if("number"==typeof n)for(;n>i;i++)e[r++]=t[i];else while(t[i]!==undefined)e[r++]=t[i++];return e.length=r,e},grep:function(e,t,n){var r,i=[],o=0,s=e.length;for(n=!!n;s>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,s=j(e),a=[];if(s)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(a[a.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(a[a.length]=r);return f.apply([],a)},guid:1,proxy:function(e,t){var n,r,i;return"string"==typeof t&&(n=e[t],t=e,e=n),x.isFunction(e)?(r=d.call(arguments,2),i=function(){return e.apply(t||this,r.concat(d.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):undefined},access:function(e,t,n,r,i,o,s){var a=0,u=e.length,l=null==n;if("object"===x.type(n)){i=!0;for(a in n)x.access(e,t,a,n[a],!0,o,s)}else if(r!==undefined&&(i=!0,x.isFunction(r)||(s=!0),l&&(s?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(x(e),n)})),t))for(;u>a;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return i?e:l?t.call(e):u?t(e[0],n):o},now:Date.now,swap:function(e,t,n,r){var i,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=s[o];return i}}),x.ready.promise=function(t){return n||(n=x.Deferred(),"complete"===o.readyState?setTimeout(x.ready):(o.addEventListener("DOMContentLoaded",S,!1),e.addEventListener("load",S,!1))),n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function j(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}t=x(o),function(e,undefined){var t,n,r,i,o,s,a,u,l,c,p,f,h,d,g,m,y,v="sizzle"+-new Date,b=e.document,w=0,T=0,C=st(),k=st(),N=st(),E=!1,S=function(e,t){return e===t?(E=!0,0):0},j=typeof undefined,D=1<<31,A={}.hasOwnProperty,L=[],q=L.pop,H=L.push,O=L.push,F=L.slice,P=L.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",W="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",$=W.replace("w","w#"),B="\\["+M+"*("+W+")"+M+"*(?:([*^$|!~]?=)"+M+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+$+")|)|)"+M+"*\\]",I=":("+W+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+B.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=RegExp("^"+M+"*,"+M+"*"),X=RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=RegExp(M+"*[+~]"),Y=RegExp("="+M+"*([^\\]'\"]*)"+M+"*\\]","g"),V=RegExp(I),G=RegExp("^"+$+"$"),J={ID:RegExp("^#("+W+")"),CLASS:RegExp("^\\.("+W+")"),TAG:RegExp("^("+W.replace("w","w*")+")"),ATTR:RegExp("^"+B),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:RegExp("^(?:"+R+")$","i"),needsContext:RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Q=/^[^{]+\{\s*\[native \w/,K=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Z=/^(?:input|select|textarea|button)$/i,et=/^h\d$/i,tt=/'|\\/g,nt=RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),rt=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{O.apply(L=F.call(b.childNodes),b.childNodes),L[b.childNodes.length].nodeType}catch(it){O={apply:L.length?function(e,t){H.apply(e,F.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function ot(e,t,r,i){var o,s,a,u,l,f,g,m,x,w;if((t?t.ownerDocument||t:b)!==p&&c(t),t=t||p,r=r||[],!e||"string"!=typeof e)return r;if(1!==(u=t.nodeType)&&9!==u)return[];if(h&&!i){if(o=K.exec(e))if(a=o[1]){if(9===u){if(s=t.getElementById(a),!s||!s.parentNode)return r;if(s.id===a)return r.push(s),r}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(a))&&y(t,s)&&s.id===a)return r.push(s),r}else{if(o[2])return O.apply(r,t.getElementsByTagName(e)),r;if((a=o[3])&&n.getElementsByClassName&&t.getElementsByClassName)return O.apply(r,t.getElementsByClassName(a)),r}if(n.qsa&&(!d||!d.test(e))){if(m=g=v,x=t,w=9===u&&e,1===u&&"object"!==t.nodeName.toLowerCase()){f=gt(e),(g=t.getAttribute("id"))?m=g.replace(tt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",l=f.length;while(l--)f[l]=m+mt(f[l]);x=U.test(e)&&t.parentNode||t,w=f.join(",")}if(w)try{return O.apply(r,x.querySelectorAll(w)),r}catch(T){}finally{g||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,r,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>i.cacheLength&&delete t[e.shift()],t[n]=r}return t}function at(e){return e[v]=!0,e}function ut(e){var t=p.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function lt(e,t){var n=e.split("|"),r=e.length;while(r--)i.attrHandle[n[r]]=t}function ct(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return at(function(t){return t=+t,at(function(n,r){var i,o=e([],n.length,t),s=o.length;while(s--)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}s=ot.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},n=ot.support={},c=ot.setDocument=function(e){var t=e?e.ownerDocument||e:b,r=t.defaultView;return t!==p&&9===t.nodeType&&t.documentElement?(p=t,f=t.documentElement,h=!s(t),r&&r.attachEvent&&r!==r.top&&r.attachEvent("onbeforeunload",function(){c()}),n.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ut(function(e){return e.appendChild(t.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),n.getById=ut(function(e){return f.appendChild(e).id=v,!t.getElementsByName||!t.getElementsByName(v).length}),n.getById?(i.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){return e.getAttribute("id")===t}}):(delete i.find.ID,i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=n.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==j?t.getElementsByTagName(e):undefined}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.CLASS=n.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==j&&h?t.getElementsByClassName(e):undefined},g=[],d=[],(n.qsa=Q.test(t.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||d.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll(":checked").length||d.push(":checked")}),ut(function(e){var n=t.createElement("input");n.setAttribute("type","hidden"),e.appendChild(n).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&d.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||d.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),d.push(",.*:")})),(n.matchesSelector=Q.test(m=f.webkitMatchesSelector||f.mozMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&ut(function(e){n.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",I)}),d=d.length&&RegExp(d.join("|")),g=g.length&&RegExp(g.join("|")),y=Q.test(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},S=f.compareDocumentPosition?function(e,r){if(e===r)return E=!0,0;var i=r.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(r);return i?1&i||!n.sortDetached&&r.compareDocumentPosition(e)===i?e===t||y(b,e)?-1:r===t||y(b,r)?1:l?P.call(l,e)-P.call(l,r):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,n){var r,i=0,o=e.parentNode,s=n.parentNode,a=[e],u=[n];if(e===n)return E=!0,0;if(!o||!s)return e===t?-1:n===t?1:o?-1:s?1:l?P.call(l,e)-P.call(l,n):0;if(o===s)return ct(e,n);r=e;while(r=r.parentNode)a.unshift(r);r=n;while(r=r.parentNode)u.unshift(r);while(a[i]===u[i])i++;return i?ct(a[i],u[i]):a[i]===b?-1:u[i]===b?1:0},t):p},ot.matches=function(e,t){return ot(e,null,null,t)},ot.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Y,"='$1']"),!(!n.matchesSelector||!h||g&&g.test(t)||d&&d.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return ot(t,p,null,[e]).length>0},ot.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},ot.attr=function(e,t){(e.ownerDocument||e)!==p&&c(e);var r=i.attrHandle[t.toLowerCase()],o=r&&A.call(i.attrHandle,t.toLowerCase())?r(e,t,!h):undefined;return o===undefined?n.attributes||!h?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null:o},ot.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},ot.uniqueSort=function(e){var t,r=[],i=0,o=0;if(E=!n.detectDuplicates,l=!n.sortStable&&e.slice(0),e.sort(S),E){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return e},o=ot.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=ot.selectors={cacheLength:50,createPseudo:at,match:J,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(nt,rt),e[3]=(e[4]||e[5]||"").replace(nt,rt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ot.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ot.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return J.CHILD.test(e[0])?null:(e[3]&&e[4]!==undefined?e[2]=e[4]:n&&V.test(n)&&(t=gt(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(nt,rt).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=C[e+" "];return t||(t=RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&C(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=ot.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,h,d,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,y=a&&t.nodeName.toLowerCase(),x=!u&&!a;if(m){if(o){while(g){p=t;while(p=p[g])if(a?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;d=g="only"===e&&!d&&"nextSibling"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&x){c=m[v]||(m[v]={}),l=c[e]||[],h=l[0]===w&&l[1],f=l[0]===w&&l[2],p=h&&m.childNodes[h];while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[w,h,f];break}}else if(x&&(l=(t[v]||(t[v]={}))[e])&&l[0]===w)f=l[1];else while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if((a?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(x&&((p[v]||(p[v]={}))[e]=[w,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||ot.error("unsupported pseudo: "+e);return r[v]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?at(function(e,n){var i,o=r(e,t),s=o.length;while(s--)i=P.call(e,o[s]),e[i]=!(n[i]=o[s])}):function(e){return r(e,0,n)}):r}},pseudos:{not:at(function(e){var t=[],n=[],r=a(e.replace(z,"$1"));return r[v]?at(function(e,t,n,i){var o,s=r(e,null,i,[]),a=e.length;while(a--)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:at(function(e){return function(t){return ot(e,t).length>0}}),contains:at(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:at(function(e){return G.test(e||"")||ot.error("unsupported lang: "+e),e=e.replace(nt,rt).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return et.test(e.nodeName)},input:function(e){return Z.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},i.pseudos.nth=i.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[t]=pt(t);for(t in{submit:!0,reset:!0})i.pseudos[t]=ft(t);function dt(){}dt.prototype=i.filters=i.pseudos,i.setFilters=new dt;function gt(e,t){var n,r,o,s,a,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);a=e,u=[],l=i.preFilter;while(a){(!n||(r=_.exec(a)))&&(r&&(a=a.slice(r[0].length)||a),u.push(o=[])),n=!1,(r=X.exec(a))&&(n=r.shift(),o.push({value:n,type:r[0].replace(z," ")}),a=a.slice(n.length));for(s in i.filter)!(r=J[s].exec(a))||l[s]&&!(r=l[s](r))||(n=r.shift(),o.push({value:n,type:s,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?ot.error(e):k(e,u).slice(0)}function mt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function yt(e,t,n){var i=t.dir,o=n&&"parentNode"===i,s=T++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,a){var u,l,c,p=w+" "+s;if(a){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,a))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[v]||(t[v]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,a)||r,l[1]===!0)return!0}}function vt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,s=[],a=0,u=e.length,l=null!=t;for(;u>a;a++)(o=e[a])&&(!n||n(o,r,i))&&(s.push(o),l&&t.push(a));return s}function bt(e,t,n,r,i,o){return r&&!r[v]&&(r=bt(r)),i&&!i[v]&&(i=bt(i,o)),at(function(o,s,a,u){var l,c,p,f=[],h=[],d=s.length,g=o||Ct(t||"*",a.nodeType?[a]:a,[]),m=!e||!o&&t?g:xt(g,f,e,a,u),y=n?i||(o?e:d||r)?[]:s:m;if(n&&n(m,y,a,u),r){l=xt(y,h),r(l,[],a,u),c=l.length;while(c--)(p=l[c])&&(y[h[c]]=!(m[h[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?P.call(o,p):f[c])>-1&&(o[l]=!(s[l]=p))}}else y=xt(y===s?y.splice(d,y.length):y),i?i(null,s,y,u):O.apply(s,y)})}function wt(e){var t,n,r,o=e.length,s=i.relative[e[0].type],a=s||i.relative[" "],l=s?1:0,c=yt(function(e){return e===t},a,!0),p=yt(function(e){return P.call(t,e)>-1},a,!0),f=[function(e,n,r){return!s&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>l;l++)if(n=i.relative[e[l].type])f=[yt(vt(f),n)];else{if(n=i.filter[e[l].type].apply(null,e[l].matches),n[v]){for(r=++l;o>r;r++)if(i.relative[e[r].type])break;return bt(l>1&&vt(f),l>1&&mt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&wt(e.slice(l,r)),o>r&&wt(e=e.slice(r)),o>r&&mt(e))}f.push(n)}return vt(f)}function Tt(e,t){var n=0,o=t.length>0,s=e.length>0,a=function(a,l,c,f,h){var d,g,m,y=[],v=0,x="0",b=a&&[],T=null!=h,C=u,k=a||s&&i.find.TAG("*",h&&l.parentNode||l),N=w+=null==C?1:Math.random()||.1;for(T&&(u=l!==p&&l,r=n);null!=(d=k[x]);x++){if(s&&d){g=0;while(m=e[g++])if(m(d,l,c)){f.push(d);break}T&&(w=N,r=++n)}o&&((d=!m&&d)&&v--,a&&b.push(d))}if(v+=x,o&&x!==v){g=0;while(m=t[g++])m(b,y,l,c);if(a){if(v>0)while(x--)b[x]||y[x]||(y[x]=q.call(f));y=xt(y)}O.apply(f,y),T&&!a&&y.length>0&&v+t.length>1&&ot.uniqueSort(f)}return T&&(w=N,u=C),b};return o?at(a):a}a=ot.compile=function(e,t){var n,r=[],i=[],o=N[e+" "];if(!o){t||(t=gt(e)),n=t.length;while(n--)o=wt(t[n]),o[v]?r.push(o):i.push(o);o=N(e,Tt(i,r))}return o};function Ct(e,t,n){var r=0,i=t.length;for(;i>r;r++)ot(e,t[r],n);return n}function kt(e,t,r,o){var s,u,l,c,p,f=gt(e);if(!o&&1===f.length){if(u=f[0]=f[0].slice(0),u.length>2&&"ID"===(l=u[0]).type&&n.getById&&9===t.nodeType&&h&&i.relative[u[1].type]){if(t=(i.find.ID(l.matches[0].replace(nt,rt),t)||[])[0],!t)return r;e=e.slice(u.shift().value.length)}s=J.needsContext.test(e)?0:u.length;while(s--){if(l=u[s],i.relative[c=l.type])break;if((p=i.find[c])&&(o=p(l.matches[0].replace(nt,rt),U.test(u[0].type)&&t.parentNode||t))){if(u.splice(s,1),e=o.length&&mt(u),!e)return O.apply(r,o),r;break}}}return a(e,f)(o,t,!h,r,U.test(e)),r}n.sortStable=v.split("").sort(S).join("")===v,n.detectDuplicates=E,c(),n.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(p.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||lt("type|href|height|width",function(e,t,n){return n?undefined:e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||lt("value",function(e,t,n){return n||"input"!==e.nodeName.toLowerCase()?undefined:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||lt(R,function(e,t,n){var r;return n?undefined:(r=e.getAttributeNode(t))&&r.specified?r.value:e[t]===!0?t.toLowerCase():null}),x.find=ot,x.expr=ot.selectors,x.expr[":"]=x.expr.pseudos,x.unique=ot.uniqueSort,x.text=ot.getText,x.isXMLDoc=ot.isXML,x.contains=ot.contains}(e);var D={};function A(e){var t=D[e]={};return x.each(e.match(w)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?D[e]||A(e):x.extend({},e);var t,n,r,i,o,s,a=[],u=!e.once&&[],l=function(p){for(t=e.memory&&p,n=!0,s=i||0,i=0,o=a.length,r=!0;a&&o>s;s++)if(a[s].apply(p[0],p[1])===!1&&e.stopOnFalse){t=!1;break}r=!1,a&&(u?u.length&&l(u.shift()):t?a=[]:c.disable())},c={add:function(){if(a){var n=a.length;(function s(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&c.has(n)||a.push(n):n&&n.length&&"string"!==r&&s(n)})})(arguments),r?o=a.length:t&&(i=n,l(t))}return this},remove:function(){return a&&x.each(arguments,function(e,t){var n;while((n=x.inArray(t,a,n))>-1)a.splice(n,1),r&&(o>=n&&o--,s>=n&&s--)}),this},has:function(e){return e?x.inArray(e,a)>-1:!(!a||!a.length)},empty:function(){return a=[],o=0,this},disable:function(){return a=u=t=undefined,this},disabled:function(){return!a},lock:function(){return u=undefined,t||c.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!a||n&&!u||(t=t||[],t=[e,t.slice?t.slice():t],r?u.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!n}};return c},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var s=o[0],a=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var s=o[2],a=o[3];r[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=s.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=d.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),s=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?d.call(arguments):r,n===a?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},a,u,l;if(r>1)for(a=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(s(t,l,n)).fail(o.reject).progress(s(t,u,a)):--i;return i||o.resolveWith(l,n),o.promise()}}),x.support=function(t){var n=o.createElement("input"),r=o.createDocumentFragment(),i=o.createElement("div"),s=o.createElement("select"),a=s.appendChild(o.createElement("option"));return n.type?(n.type="checkbox",t.checkOn=""!==n.value,t.optSelected=a.selected,t.reliableMarginRight=!0,t.boxSizingReliable=!0,t.pixelPosition=!1,n.checked=!0,t.noCloneChecked=n.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!a.disabled,n=o.createElement("input"),n.value="t",n.type="radio",t.radioValue="t"===n.value,n.setAttribute("checked","t"),n.setAttribute("name","t"),r.appendChild(n),t.checkClone=r.cloneNode(!0).cloneNode(!0).lastChild.checked,t.focusinBubbles="onfocusin"in e,i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===i.style.backgroundClip,x(function(){var n,r,s="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",a=o.getElementsByTagName("body")[0];a&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",a.appendChild(n).appendChild(i),i.innerHTML="",i.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",x.swap(a,null!=a.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===i.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(i,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(i,null)||{width:"4px"}).width,r=i.appendChild(o.createElement("div")),r.style.cssText=i.style.cssText=s,r.style.marginRight=r.style.width="0",i.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),a.removeChild(n))}),t):t}({});var L,q,H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,O=/([A-Z])/g;function F(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=x.expando+Math.random()}F.uid=1,F.accepts=function(e){return e.nodeType?1===e.nodeType||9===e.nodeType:!0},F.prototype={key:function(e){if(!F.accepts(e))return 0;var t={},n=e[this.expando];if(!n){n=F.uid++;try{t[this.expando]={value:n},Object.defineProperties(e,t)}catch(r){t[this.expando]=n,x.extend(e,t)}}return this.cache[n]||(this.cache[n]={}),n},set:function(e,t,n){var r,i=this.key(e),o=this.cache[i];if("string"==typeof t)o[t]=n;else if(x.isEmptyObject(o))x.extend(this.cache[i],t);else for(r in t)o[r]=t[r];return o},get:function(e,t){var n=this.cache[this.key(e)];return t===undefined?n:n[t]},access:function(e,t,n){var r;return t===undefined||t&&"string"==typeof t&&n===undefined?(r=this.get(e,t),r!==undefined?r:this.get(e,x.camelCase(t))):(this.set(e,t,n),n!==undefined?n:t)},remove:function(e,t){var n,r,i,o=this.key(e),s=this.cache[o];if(t===undefined)this.cache[o]={};else{x.isArray(t)?r=t.concat(t.map(x.camelCase)):(i=x.camelCase(t),t in s?r=[t,i]:(r=i,r=r in s?[r]:r.match(w)||[])),n=r.length;while(n--)delete s[r[n]]}},hasData:function(e){return!x.isEmptyObject(this.cache[e[this.expando]]||{})},discard:function(e){e[this.expando]&&delete this.cache[e[this.expando]]}},L=new F,q=new F,x.extend({acceptData:F.accepts,hasData:function(e){return L.hasData(e)||q.hasData(e)},data:function(e,t,n){return L.access(e,t,n)},removeData:function(e,t){L.remove(e,t)},_data:function(e,t,n){return q.access(e,t,n)},_removeData:function(e,t){q.remove(e,t)}}),x.fn.extend({data:function(e,t){var n,r,i=this[0],o=0,s=null;if(e===undefined){if(this.length&&(s=L.get(i),1===i.nodeType&&!q.get(i,"hasDataAttrs"))){for(n=i.attributes;n.length>o;o++)r=n[o].name,0===r.indexOf("data-")&&(r=x.camelCase(r.slice(5)),P(i,r,s[r]));q.set(i,"hasDataAttrs",!0)}return s}return"object"==typeof e?this.each(function(){L.set(this,e)}):x.access(this,function(t){var n,r=x.camelCase(e);if(i&&t===undefined){if(n=L.get(i,e),n!==undefined)return n;if(n=L.get(i,r),n!==undefined)return n;if(n=P(i,r,undefined),n!==undefined)return n}else this.each(function(){var n=L.get(this,r);L.set(this,r,t),-1!==e.indexOf("-")&&n!==undefined&&L.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){L.remove(this,e)})}});function P(e,t,n){var r;if(n===undefined&&1===e.nodeType)if(r="data-"+t.replace(O,"-$1").toLowerCase(),n=e.getAttribute(r),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:H.test(n)?JSON.parse(n):n}catch(i){}L.set(e,t,n)}else n=undefined;return n}x.extend({queue:function(e,t,n){var r;return e?(t=(t||"fx")+"queue",r=q.get(e,t),n&&(!r||x.isArray(n)?r=q.access(e,t,x.makeArray(n)):r.push(n)),r||[]):undefined},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),s=function(){x.dequeue(e,t)
+};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,s,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return q.get(e,n)||q.access(e,n,{empty:x.Callbacks("once memory").add(function(){q.remove(e,[t+"queue",n])})})}}),x.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),n>arguments.length?x.queue(this[0],e):t===undefined?this:this.each(function(){var n=x.queue(this,e,t);x._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=x.Deferred(),o=this,s=this.length,a=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=undefined),e=e||"fx";while(s--)n=q.get(o[s],e+"queueHooks"),n&&n.empty&&(r++,n.empty.add(a));return a(),i.promise(t)}});var R,M,W=/[\t\r\n\f]/g,$=/\r/g,B=/^(?:input|select|textarea|button)$/i;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[x.propFix[e]||e]})},addClass:function(e){var t,n,r,i,o,s=0,a=this.length,u="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,s=0,a=this.length,u=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,i=0,o=x(this),s=e.match(w)||[];while(t=s[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===r||"boolean"===n)&&(this.className&&q.set(this,"__className__",this.className),this.className=this.className||e===!1?"":q.get(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(W," ").indexOf(t)>=0)return!0;return!1},val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=x.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,x(this).val()):e,null==i?i="":"number"==typeof i?i+="":x.isArray(i)&&(i=x.map(i,function(e){return null==e?"":e+""})),t=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&t.set(this,i,"value")!==undefined||(this.value=i))});if(i)return t=x.valHooks[i.type]||x.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&(n=t.get(i,"value"))!==undefined?n:(n=i.value,"string"==typeof n?n.replace($,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,s=o?null:[],a=o?i+1:r.length,u=0>i?a:o?i:0;for(;a>u;u++)if(n=r[u],!(!n.selected&&u!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),s=i.length;while(s--)r=i[s],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,t,n){var i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===r?x.prop(e,t,n):(1===s&&x.isXMLDoc(e)||(t=t.toLowerCase(),i=x.attrHooks[t]||(x.expr.match.bool.test(t)?M:R)),n===undefined?i&&"get"in i&&null!==(o=i.get(e,t))?o:(o=x.find.attr(e,t),null==o?undefined:o):null!==n?i&&"set"in i&&(o=i.set(e,n,t))!==undefined?o:(e.setAttribute(t,n+""),n):(x.removeAttr(e,t),undefined))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)&&(e[r]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,t,n){var r,i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return o=1!==s||!x.isXMLDoc(e),o&&(t=x.propFix[t]||t,i=x.propHooks[t]),n!==undefined?i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||B.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),M={set:function(e,t,n){return t===!1?x.removeAttr(e,n):e.setAttribute(n,n),n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,t){var n=x.expr.attrHandle[t]||x.find.attr;x.expr.attrHandle[t]=function(e,t,r){var i=x.expr.attrHandle[t],o=r?undefined:(x.expr.attrHandle[t]=undefined)!=n(e,t,r)?t.toLowerCase():null;return x.expr.attrHandle[t]=i,o}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,t){return x.isArray(t)?e.checked=x.inArray(x(e).val(),t)>=0:undefined}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var I=/^key/,z=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,X=/^([^.]*)(?:\.(.+)|)$/;function U(){return!0}function Y(){return!1}function V(){try{return o.activeElement}catch(e){}}x.event={global:{},add:function(e,t,n,i,o){var s,a,u,l,c,p,f,h,d,g,m,y=q.get(e);if(y){n.handler&&(s=n,n=s.handler,o=s.selector),n.guid||(n.guid=x.guid++),(l=y.events)||(l=y.events={}),(a=y.handle)||(a=y.handle=function(e){return typeof x===r||e&&x.event.triggered===e.type?undefined:x.event.dispatch.apply(a.elem,arguments)},a.elem=e),t=(t||"").match(w)||[""],c=t.length;while(c--)u=X.exec(t[c])||[],d=m=u[1],g=(u[2]||"").split(".").sort(),d&&(f=x.event.special[d]||{},d=(o?f.delegateType:f.bindType)||d,f=x.event.special[d]||{},p=x.extend({type:d,origType:m,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&x.expr.match.needsContext.test(o),namespace:g.join(".")},s),(h=l[d])||(h=l[d]=[],h.delegateCount=0,f.setup&&f.setup.call(e,i,g,a)!==!1||e.addEventListener&&e.addEventListener(d,a,!1)),f.add&&(f.add.call(e,p),p.handler.guid||(p.handler.guid=n.guid)),o?h.splice(h.delegateCount++,0,p):h.push(p),x.event.global[d]=!0);e=null}},remove:function(e,t,n,r,i){var o,s,a,u,l,c,p,f,h,d,g,m=q.hasData(e)&&q.get(e);if(m&&(u=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(a=X.exec(t[l])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h){p=x.event.special[h]||{},h=(r?p.delegateType:p.bindType)||h,f=u[h]||[],a=a[2]&&RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=f.length;while(o--)c=f[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(f.splice(o,1),c.selector&&f.delegateCount--,p.remove&&p.remove.call(e,c));s&&!f.length&&(p.teardown&&p.teardown.call(e,d,m.handle)!==!1||x.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)x.event.remove(e,h+t[l],n,r,!0);x.isEmptyObject(u)&&(delete m.handle,q.remove(e,"events"))}},trigger:function(t,n,r,i){var s,a,u,l,c,p,f,h=[r||o],d=y.call(t,"type")?t.type:t,g=y.call(t,"namespace")?t.namespace.split("."):[];if(a=u=r=r||o,3!==r.nodeType&&8!==r.nodeType&&!_.test(d+x.event.triggered)&&(d.indexOf(".")>=0&&(g=d.split("."),d=g.shift(),g.sort()),c=0>d.indexOf(":")&&"on"+d,t=t[x.expando]?t:new x.Event(d,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=g.join("."),t.namespace_re=t.namespace?RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=undefined,t.target||(t.target=r),n=null==n?[t]:x.makeArray(n,[t]),f=x.event.special[d]||{},i||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!i&&!f.noBubble&&!x.isWindow(r)){for(l=f.delegateType||d,_.test(l+d)||(a=a.parentNode);a;a=a.parentNode)h.push(a),u=a;u===(r.ownerDocument||o)&&h.push(u.defaultView||u.parentWindow||e)}s=0;while((a=h[s++])&&!t.isPropagationStopped())t.type=s>1?l:f.bindType||d,p=(q.get(a,"events")||{})[t.type]&&q.get(a,"handle"),p&&p.apply(a,n),p=c&&a[c],p&&x.acceptData(a)&&p.apply&&p.apply(a,n)===!1&&t.preventDefault();return t.type=d,i||t.isDefaultPrevented()||f._default&&f._default.apply(h.pop(),n)!==!1||!x.acceptData(r)||c&&x.isFunction(r[d])&&!x.isWindow(r)&&(u=r[c],u&&(r[c]=null),x.event.triggered=d,r[d](),x.event.triggered=undefined,u&&(r[c]=u)),t.result}},dispatch:function(e){e=x.event.fix(e);var t,n,r,i,o,s=[],a=d.call(arguments),u=(q.get(this,"events")||{})[e.type]||[],l=x.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),t=0;while((i=s[t++])&&!e.isPropagationStopped()){e.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(o.namespace))&&(e.handleObj=o,e.data=o.data,r=((x.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,a),r!==undefined&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!==this;u=u.parentNode||this)if(u.disabled!==!0||"click"!==e.type){for(r=[],n=0;a>n;n++)o=t[n],i=o.selector+" ",r[i]===undefined&&(r[i]=o.needsContext?x(i,this).index(u)>=0:x.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&s.push({elem:u,handlers:r})}return t.length>a&&s.push({elem:this,handlers:t.slice(a)}),s},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,t){var n,r,i,s=t.button;return null==e.pageX&&null!=t.clientX&&(n=e.target.ownerDocument||o,r=n.documentElement,i=n.body,e.pageX=t.clientX+(r&&r.scrollLeft||i&&i.scrollLeft||0)-(r&&r.clientLeft||i&&i.clientLeft||0),e.pageY=t.clientY+(r&&r.scrollTop||i&&i.scrollTop||0)-(r&&r.clientTop||i&&i.clientTop||0)),e.which||s===undefined||(e.which=1&s?1:2&s?3:4&s?2:0),e}},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,s=e,a=this.fixHooks[i];a||(this.fixHooks[i]=a=z.test(i)?this.mouseHooks:I.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new x.Event(s),t=r.length;while(t--)n=r[t],e[n]=s[n];return e.target||(e.target=o),3===e.target.nodeType&&(e.target=e.target.parentNode),a.filter?a.filter(e,s):e},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==V()&&this.focus?(this.focus(),!1):undefined},delegateType:"focusin"},blur:{trigger:function(){return this===V()&&this.blur?(this.blur(),!1):undefined},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&x.nodeName(this,"input")?(this.click(),!1):undefined},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==undefined&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)},x.Event=function(e,t){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.getPreventDefault&&e.getPreventDefault()?U:Y):this.type=e,t&&x.extend(this,t),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,undefined):new x.Event(e,t)},x.Event.prototype={isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=U,e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=U,e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=U,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,t,n,r,i){var o,s;if("object"==typeof e){"string"!=typeof t&&(n=n||t,t=undefined);for(s in e)this.on(s,t,n,e[s],i);return this}if(null==n&&null==r?(r=t,n=t=undefined):null==r&&("string"==typeof t?(r=n,n=undefined):(r=n,n=t,t=undefined)),r===!1)r=Y;else if(!r)return this;return 1===i&&(o=r,r=function(e){return x().off(e),o.apply(this,arguments)},r.guid=o.guid||(o.guid=x.guid++)),this.each(function(){x.event.add(this,e,r,n,t)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,x(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return(t===!1||"function"==typeof t)&&(n=t,t=undefined),n===!1&&(n=Y),this.each(function(){x.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];return n?x.event.trigger(e,t,n,!0):undefined}});var G=/^.[^:#\[\.,]*$/,J=/^(?:parents|prev(?:Until|All))/,Q=x.expr.match.needsContext,K={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t=x(e,this),n=t.length;return this.filter(function(){var e=0;for(;n>e;e++)if(x.contains(this,t[e]))return!0})},not:function(e){return this.pushStack(et(this,e||[],!0))},filter:function(e){return this.pushStack(et(this,e||[],!1))},is:function(e){return!!et(this,"string"==typeof e&&Q.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],s=Q.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(s?s.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?g.call(x(e),this[0]):g.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function Z(e,t){while((e=e[t])&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return Z(e,"nextSibling")},prev:function(e){return Z(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return e.contentDocument||x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(K[e]||x.unique(i),J.test(e)&&i.reverse()),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,t,n){var r=[],i=n!==undefined;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&x(e).is(n))break;r.push(e)}return r},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function et(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(G.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return g.call(t,e)>=0!==n})}var tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,nt=/<([\w:]+)/,rt=/<|&#?\w+;/,it=/<(?:script|style|link)/i,ot=/^(?:checkbox|radio)$/i,st=/checked\s*(?:[^=]|=\s*.checked.)/i,at=/^$|\/(?:java|ecma)script/i,ut=/^true\/(.*)/,lt=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ct={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ct.optgroup=ct.option,ct.tbody=ct.tfoot=ct.colgroup=ct.caption=ct.thead,ct.th=ct.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===undefined?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(mt(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&dt(mt(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++)1===e.nodeType&&(x.cleanData(mt(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var t=this[0]||{},n=0,r=this.length;if(e===undefined&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!it.test(e)&&!ct[(nt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(tt,"<$1></$2>");try{for(;r>n;n++)t=this[n]||{},1===t.nodeType&&(x.cleanData(mt(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=f.apply([],e);var r,i,o,s,a,u,l=0,c=this.length,p=this,h=c-1,d=e[0],g=x.isFunction(d);if(g||!(1>=c||"string"!=typeof d||x.support.checkClone)&&st.test(d))return this.each(function(r){var i=p.eq(r);g&&(e[0]=d.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(r=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),i=r.firstChild,1===r.childNodes.length&&(r=i),i)){for(o=x.map(mt(r,"script"),ft),s=o.length;c>l;l++)a=r,l!==h&&(a=x.clone(a,!0,!0),s&&x.merge(o,mt(a,"script"))),t.call(this[l],a,l);if(s)for(u=o[o.length-1].ownerDocument,x.map(o,ht),l=0;s>l;l++)a=o[l],at.test(a.type||"")&&!q.access(a,"globalEval")&&x.contains(u,a)&&(a.src?x._evalUrl(a.src):x.globalEval(a.textContent.replace(lt,"")))}return this}}),x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=[],i=x(e),o=i.length-1,s=0;for(;o>=s;s++)n=s===o?this:this.clone(!0),x(i[s])[t](n),h.apply(r,n.get());return this.pushStack(r)}}),x.extend({clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=x.contains(e.ownerDocument,e);if(!(x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(s=mt(a),o=mt(e),r=0,i=o.length;i>r;r++)yt(o[r],s[r]);if(t)if(n)for(o=o||mt(e),s=s||mt(a),r=0,i=o.length;i>r;r++)gt(o[r],s[r]);else gt(e,a);return s=mt(a,"script"),s.length>0&&dt(s,!u&&mt(e,"script")),a},buildFragment:function(e,t,n,r){var i,o,s,a,u,l,c=0,p=e.length,f=t.createDocumentFragment(),h=[];for(;p>c;c++)if(i=e[c],i||0===i)if("object"===x.type(i))x.merge(h,i.nodeType?[i]:i);else if(rt.test(i)){o=o||f.appendChild(t.createElement("div")),s=(nt.exec(i)||["",""])[1].toLowerCase(),a=ct[s]||ct._default,o.innerHTML=a[1]+i.replace(tt,"<$1></$2>")+a[2],l=a[0];while(l--)o=o.lastChild;x.merge(h,o.childNodes),o=f.firstChild,o.textContent=""}else h.push(t.createTextNode(i));f.textContent="",c=0;while(i=h[c++])if((!r||-1===x.inArray(i,r))&&(u=x.contains(i.ownerDocument,i),o=mt(f.appendChild(i),"script"),u&&dt(o),n)){l=0;while(i=o[l++])at.test(i.type||"")&&n.push(i)}return f},cleanData:function(e){var t,n,r,i,o,s,a=x.event.special,u=0;for(;(n=e[u])!==undefined;u++){if(F.accepts(n)&&(o=n[q.expando],o&&(t=q.cache[o]))){if(r=Object.keys(t.events||{}),r.length)for(s=0;(i=r[s])!==undefined;s++)a[i]?x.event.remove(n,i):x.removeEvent(n,i,t.handle);q.cache[o]&&delete q.cache[o]}delete L.cache[n[L.expando]]}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}});function pt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function ft(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function ht(e){var t=ut.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function dt(e,t){var n=e.length,r=0;for(;n>r;r++)q.set(e[r],"globalEval",!t||q.get(t[r],"globalEval"))}function gt(e,t){var n,r,i,o,s,a,u,l;if(1===t.nodeType){if(q.hasData(e)&&(o=q.access(e),s=q.set(t,o),l=o.events)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;r>n;n++)x.event.add(t,i,l[i][n])}L.hasData(e)&&(a=L.access(e),u=x.extend({},a),L.set(t,u))}}function mt(e,t){var n=e.getElementsByTagName?e.getElementsByTagName(t||"*"):e.querySelectorAll?e.querySelectorAll(t||"*"):[];return t===undefined||t&&x.nodeName(e,t)?x.merge([e],n):n}function yt(e,t){var n=t.nodeName.toLowerCase();"input"===n&&ot.test(e.type)?t.checked=e.checked:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}x.fn.extend({wrapAll:function(e){var t;return x.isFunction(e)?this.each(function(t){x(this).wrapAll(e.call(this,t))}):(this[0]&&(t=x(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var vt,xt,bt=/^(none|table(?!-c[ea]).+)/,wt=/^margin/,Tt=RegExp("^("+b+")(.*)$","i"),Ct=RegExp("^("+b+")(?!px)[a-z%]+$","i"),kt=RegExp("^([+-])=("+b+")","i"),Nt={BODY:"block"},Et={position:"absolute",visibility:"hidden",display:"block"},St={letterSpacing:0,fontWeight:400},jt=["Top","Right","Bottom","Left"],Dt=["Webkit","O","Moz","ms"];function At(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Dt.length;while(i--)if(t=Dt[i]+n,t in e)return t;return r}function Lt(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function qt(t){return e.getComputedStyle(t,null)}function Ht(e,t){var n,r,i,o=[],s=0,a=e.length;for(;a>s;s++)r=e[s],r.style&&(o[s]=q.get(r,"olddisplay"),n=r.style.display,t?(o[s]||"none"!==n||(r.style.display=""),""===r.style.display&&Lt(r)&&(o[s]=q.access(r,"olddisplay",Rt(r.nodeName)))):o[s]||(i=Lt(r),(n&&"none"!==n||!i)&&q.set(r,"olddisplay",i?n:x.css(r,"display"))));for(s=0;a>s;s++)r=e[s],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[s]||"":"none"));return e}x.fn.extend({css:function(e,t){return x.access(this,function(e,t,n){var r,i,o={},s=0;if(x.isArray(t)){for(r=qt(e),i=t.length;i>s;s++)o[t[s]]=x.css(e,t[s],!1,r);return o}return n!==undefined?x.style(e,t,n):x.css(e,t)},e,t,arguments.length>1)},show:function(){return Ht(this,!0)},hide:function(){return Ht(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Lt(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=vt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=x.camelCase(t),u=e.style;return t=x.cssProps[a]||(x.cssProps[a]=At(u,a)),s=x.cssHooks[t]||x.cssHooks[a],n===undefined?s&&"get"in s&&(i=s.get(e,!1,r))!==undefined?i:u[t]:(o=typeof n,"string"===o&&(i=kt.exec(n))&&(n=(i[1]+1)*i[2]+parseFloat(x.css(e,t)),o="number"),null==n||"number"===o&&isNaN(n)||("number"!==o||x.cssNumber[a]||(n+="px"),x.support.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),s&&"set"in s&&(n=s.set(e,n,r))===undefined||(u[t]=n)),undefined)}},css:function(e,t,n,r){var i,o,s,a=x.camelCase(t);return t=x.cssProps[a]||(x.cssProps[a]=At(e.style,a)),s=x.cssHooks[t]||x.cssHooks[a],s&&"get"in s&&(i=s.get(e,!0,n)),i===undefined&&(i=vt(e,t,r)),"normal"===i&&t in St&&(i=St[t]),""===n||n?(o=parseFloat(i),n===!0||x.isNumeric(o)?o||0:i):i}}),vt=function(e,t,n){var r,i,o,s=n||qt(e),a=s?s.getPropertyValue(t)||s[t]:undefined,u=e.style;return s&&(""!==a||x.contains(e.ownerDocument,e)||(a=x.style(e,t)),Ct.test(a)&&wt.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=s.width,u.width=r,u.minWidth=i,u.maxWidth=o)),a};function Ot(e,t,n){var r=Tt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function Ft(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,s=0;for(;4>o;o+=2)"margin"===n&&(s+=x.css(e,n+jt[o],!0,i)),r?("content"===n&&(s-=x.css(e,"padding"+jt[o],!0,i)),"margin"!==n&&(s-=x.css(e,"border"+jt[o]+"Width",!0,i))):(s+=x.css(e,"padding"+jt[o],!0,i),"padding"!==n&&(s+=x.css(e,"border"+jt[o]+"Width",!0,i)));return s}function Pt(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=qt(e),s=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=vt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Ct.test(i))return i;r=s&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+Ft(e,t,n||(s?"border":"content"),r,o)+"px"}function Rt(e){var t=o,n=Nt[e];return n||(n=Mt(e,t),"none"!==n&&n||(xt=(xt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(xt[0].contentWindow||xt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=Mt(e,t),xt.detach()),Nt[e]=n),n}function Mt(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,t){x.cssHooks[t]={get:function(e,n,r){return n?0===e.offsetWidth&&bt.test(x.css(e,"display"))?x.swap(e,Et,function(){return Pt(e,t,r)}):Pt(e,t,r):undefined},set:function(e,n,r){var i=r&&qt(e);return Ot(e,n,r?Ft(e,t,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,t){return t?x.swap(e,{display:"inline-block"},vt,[e,"marginRight"]):undefined}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,t){x.cssHooks[t]={get:function(e,n){return n?(n=vt(e,t),Ct.test(n)?x(e).position()[t]+"px":n):undefined}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+jt[r]+t]=o[r]||o[r-2]||o[0];return i}},wt.test(e)||(x.cssHooks[e+t].set=Ot)});var Wt=/%20/g,$t=/\[\]$/,Bt=/\r?\n/g,It=/^(?:submit|button|image|reset|file)$/i,zt=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&zt.test(this.nodeName)&&!It.test(e)&&(this.checked||!ot.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(Bt,"\r\n")}}):{name:t.name,value:n.replace(Bt,"\r\n")}}).get()}}),x.param=function(e,t){var n,r=[],i=function(e,t){t=x.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(t===undefined&&(t=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){i(this.name,this.value)});else for(n in e)_t(n,e[n],t,i);return r.join("&").replace(Wt,"+")};function _t(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||$t.test(e)?r(e,i):_t(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)_t(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)
+},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var Xt,Ut,Yt=x.now(),Vt=/\?/,Gt=/#.*$/,Jt=/([?&])_=[^&]*/,Qt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Kt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Zt=/^(?:GET|HEAD)$/,en=/^\/\//,tn=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,nn=x.fn.load,rn={},on={},sn="*/".concat("*");try{Ut=i.href}catch(an){Ut=o.createElement("a"),Ut.href="",Ut=Ut.href}Xt=tn.exec(Ut.toLowerCase())||[];function un(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function ln(e,t,n,r){var i={},o=e===on;function s(a){var u;return i[a]=!0,x.each(e[a]||[],function(e,a){var l=a(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):undefined:(t.dataTypes.unshift(l),s(l),!1)}),u}return s(t.dataTypes[0])||!i["*"]&&s("*")}function cn(e,t){var n,r,i=x.ajaxSettings.flatOptions||{};for(n in t)t[n]!==undefined&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,t,n){if("string"!=typeof e&&nn)return nn.apply(this,arguments);var r,i,o,s=this,a=e.indexOf(" ");return a>=0&&(r=e.slice(a),e=e.slice(0,a)),x.isFunction(t)?(n=t,t=undefined):t&&"object"==typeof t&&(i="POST"),s.length>0&&x.ajax({url:e,type:i,dataType:"html",data:t}).done(function(e){o=arguments,s.html(r?x("<div>").append(x.parseHTML(e)).find(r):e)}).complete(n&&function(e,t){s.each(n,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ut,type:"GET",isLocal:Kt.test(Xt[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":sn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?cn(cn(e,x.ajaxSettings),t):cn(x.ajaxSettings,e)},ajaxPrefilter:un(rn),ajaxTransport:un(on),ajax:function(e,t){"object"==typeof e&&(t=e,e=undefined),t=t||{};var n,r,i,o,s,a,u,l,c=x.ajaxSetup({},t),p=c.context||c,f=c.context&&(p.nodeType||p.jquery)?x(p):x.event,h=x.Deferred(),d=x.Callbacks("once memory"),g=c.statusCode||{},m={},y={},v=0,b="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===v){if(!o){o={};while(t=Qt.exec(i))o[t[1].toLowerCase()]=t[2]}t=o[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===v?i:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return v||(e=y[n]=y[n]||e,m[e]=t),this},overrideMimeType:function(e){return v||(c.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>v)for(t in e)g[t]=[g[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||b;return n&&n.abort(t),k(0,t),this}};if(h.promise(T).complete=d.add,T.success=T.done,T.error=T.fail,c.url=((e||c.url||Ut)+"").replace(Gt,"").replace(en,Xt[1]+"//"),c.type=t.method||t.type||c.method||c.type,c.dataTypes=x.trim(c.dataType||"*").toLowerCase().match(w)||[""],null==c.crossDomain&&(a=tn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===Xt[1]&&a[2]===Xt[2]&&(a[3]||("http:"===a[1]?"80":"443"))===(Xt[3]||("http:"===Xt[1]?"80":"443")))),c.data&&c.processData&&"string"!=typeof c.data&&(c.data=x.param(c.data,c.traditional)),ln(rn,c,t,T),2===v)return T;u=c.global,u&&0===x.active++&&x.event.trigger("ajaxStart"),c.type=c.type.toUpperCase(),c.hasContent=!Zt.test(c.type),r=c.url,c.hasContent||(c.data&&(r=c.url+=(Vt.test(r)?"&":"?")+c.data,delete c.data),c.cache===!1&&(c.url=Jt.test(r)?r.replace(Jt,"$1_="+Yt++):r+(Vt.test(r)?"&":"?")+"_="+Yt++)),c.ifModified&&(x.lastModified[r]&&T.setRequestHeader("If-Modified-Since",x.lastModified[r]),x.etag[r]&&T.setRequestHeader("If-None-Match",x.etag[r])),(c.data&&c.hasContent&&c.contentType!==!1||t.contentType)&&T.setRequestHeader("Content-Type",c.contentType),T.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+("*"!==c.dataTypes[0]?", "+sn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)T.setRequestHeader(l,c.headers[l]);if(c.beforeSend&&(c.beforeSend.call(p,T,c)===!1||2===v))return T.abort();b="abort";for(l in{success:1,error:1,complete:1})T[l](c[l]);if(n=ln(on,c,t,T)){T.readyState=1,u&&f.trigger("ajaxSend",[T,c]),c.async&&c.timeout>0&&(s=setTimeout(function(){T.abort("timeout")},c.timeout));try{v=1,n.send(m,k)}catch(C){if(!(2>v))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,t,o,a){var l,m,y,b,w,C=t;2!==v&&(v=2,s&&clearTimeout(s),n=undefined,i=a||"",T.readyState=e>0?4:0,l=e>=200&&300>e||304===e,o&&(b=pn(c,T,o)),b=fn(c,b,T,l),l?(c.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(x.lastModified[r]=w),w=T.getResponseHeader("etag"),w&&(x.etag[r]=w)),204===e||"HEAD"===c.type?C="nocontent":304===e?C="notmodified":(C=b.state,m=b.data,y=b.error,l=!y)):(y=C,(e||!C)&&(C="error",0>e&&(e=0))),T.status=e,T.statusText=(t||C)+"",l?h.resolveWith(p,[m,C,T]):h.rejectWith(p,[T,C,y]),T.statusCode(g),g=undefined,u&&f.trigger(l?"ajaxSuccess":"ajaxError",[T,c,l?m:y]),d.fireWith(p,[T,C]),u&&(f.trigger("ajaxComplete",[T,c]),--x.active||x.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,t){return x.get(e,undefined,t,"script")}}),x.each(["get","post"],function(e,t){x[t]=function(e,n,r,i){return x.isFunction(n)&&(i=i||r,r=n,n=undefined),x.ajax({url:e,type:t,dataType:i,data:n,success:r})}});function pn(e,t,n){var r,i,o,s,a=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),r===undefined&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in a)if(a[i]&&a[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}s||(s=i)}o=o||s}return o?(o!==u[0]&&u.unshift(o),n[o]):undefined}function fn(e,t,n,r){var i,o,s,a,u,l={},c=e.dataTypes.slice();if(c[1])for(s in e.converters)l[s.toLowerCase()]=e.converters[s];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(s=l[u+" "+o]||l["* "+o],!s)for(i in l)if(a=i.split(" "),a[1]===o&&(s=l[u+" "+a[0]]||l["* "+a[0]])){s===!0?s=l[i]:l[i]!==!0&&(o=a[0],c.unshift(a[1]));break}if(s!==!0)if(s&&e["throws"])t=s(t);else try{t=s(t)}catch(p){return{state:"parsererror",error:s?p:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===undefined&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),x.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=x("<script>").prop({async:!0,charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&i("error"===e.type?404:200,e.type)}),o.head.appendChild(t[0])},abort:function(){n&&n()}}}});var hn=[],dn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=hn.pop()||x.expando+"_"+Yt++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,s,a=t.jsonp!==!1&&(dn.test(t.url)?"url":"string"==typeof t.data&&!(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&dn.test(t.data)&&"data");return a||"jsonp"===t.dataTypes[0]?(i=t.jsonpCallback=x.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,a?t[a]=t[a].replace(dn,"$1"+i):t.jsonp!==!1&&(t.url+=(Vt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return s||x.error(i+" was not called"),s[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){s=arguments},r.always(function(){e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,hn.push(i)),s&&x.isFunction(o)&&o(s[0]),s=o=undefined}),"script"):undefined}),x.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(e){}};var gn=x.ajaxSettings.xhr(),mn={0:200,1223:204},yn=0,vn={};e.ActiveXObject&&x(e).on("unload",function(){for(var e in vn)vn[e]();vn=undefined}),x.support.cors=!!gn&&"withCredentials"in gn,x.support.ajax=gn=!!gn,x.ajaxTransport(function(e){var t;return x.support.cors||gn&&!e.crossDomain?{send:function(n,r){var i,o,s=e.xhr();if(s.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(i in e.xhrFields)s[i]=e.xhrFields[i];e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(i in n)s.setRequestHeader(i,n[i]);t=function(e){return function(){t&&(delete vn[o],t=s.onload=s.onerror=null,"abort"===e?s.abort():"error"===e?r(s.status||404,s.statusText):r(mn[s.status]||s.status,s.statusText,"string"==typeof s.responseText?{text:s.responseText}:undefined,s.getAllResponseHeaders()))}},s.onload=t(),s.onerror=t("error"),t=vn[o=yn++]=t("abort"),s.send(e.hasContent&&e.data||null)},abort:function(){t&&t()}}:undefined});var xn,bn,wn=/^(?:toggle|show|hide)$/,Tn=RegExp("^(?:([+-])=|)("+b+")([a-z%]*)$","i"),Cn=/queueHooks$/,kn=[An],Nn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Tn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),s=(x.cssNumber[e]||"px"!==o&&+r)&&Tn.exec(x.css(n.elem,e)),a=1,u=20;if(s&&s[3]!==o){o=o||s[3],i=i||[],s=+r||1;do a=a||".5",s/=a,x.style(n.elem,e,s+o);while(a!==(a=n.cur()/r)&&1!==a&&--u)}return i&&(s=n.start=+s||+r||0,n.unit=o,n.end=i[1]?s+(i[1]+1)*i[2]:+i[2]),n}]};function En(){return setTimeout(function(){xn=undefined}),xn=x.now()}function Sn(e,t,n){var r,i=(Nn[t]||[]).concat(Nn["*"]),o=0,s=i.length;for(;s>o;o++)if(r=i[o].call(n,t,e))return r}function jn(e,t,n){var r,i,o=0,s=kn.length,a=x.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=xn||En(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,s=0,u=l.tweens.length;for(;u>s;s++)l.tweens[s].run(o);return a.notifyWith(e,[l,o,n]),1>o&&u?n:(a.resolveWith(e,[l]),!1)},l=a.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:xn||En(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?a.resolveWith(e,[l,t]):a.rejectWith(e,[l,t]),this}}),c=l.props;for(Dn(c,l.opts.specialEasing);s>o;o++)if(r=kn[o].call(l,e,c,l.opts))return r;return x.map(c,Sn,l),x.isFunction(l.opts.start)&&l.opts.start.call(e,l),x.fx.timer(x.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function Dn(e,t){var n,r,i,o,s;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),s=x.cssHooks[r],s&&"expand"in s){o=s.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(jn,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Nn[n]=Nn[n]||[],Nn[n].unshift(t)},prefilter:function(e,t){t?kn.unshift(e):kn.push(e)}});function An(e,t,n){var r,i,o,s,a,u,l=this,c={},p=e.style,f=e.nodeType&&Lt(e),h=q.get(e,"fxshow");n.queue||(a=x._queueHooks(e,"fx"),null==a.unqueued&&(a.unqueued=0,u=a.empty.fire,a.empty.fire=function(){a.unqueued||u()}),a.unqueued++,l.always(function(){l.always(function(){a.unqueued--,x.queue(e,"fx").length||a.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(p.display="inline-block")),n.overflow&&(p.overflow="hidden",l.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],wn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show")){if("show"!==i||!h||h[r]===undefined)continue;f=!0}c[r]=h&&h[r]||x.style(e,r)}if(!x.isEmptyObject(c)){h?"hidden"in h&&(f=h.hidden):h=q.access(e,"fxshow",{}),o&&(h.hidden=!f),f?x(e).show():l.done(function(){x(e).hide()}),l.done(function(){var t;q.remove(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)s=Sn(f?h[r]:0,r,l),r in h||(h[r]=s.start,f&&(s.end=s.start,s.start="width"===r||"height"===r?1:0))}}function Ln(e,t,n,r,i){return new Ln.prototype.init(e,t,n,r,i)}x.Tween=Ln,Ln.prototype={constructor:Ln,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=Ln.propHooks[this.prop];return e&&e.get?e.get(this):Ln.propHooks._default.get(this)},run:function(e){var t,n=Ln.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Ln.propHooks._default.set(this),this}},Ln.prototype.init.prototype=Ln.prototype,Ln.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Ln.propHooks.scrollTop=Ln.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(qn(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Lt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),s=function(){var t=jn(this,x.extend({},e),o);(i||q.get(this,"finish"))&&t.stop(!0)};return s.finish=s,i||o.queue===!1?this.each(s):this.queue(o.queue,s)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=undefined),t&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=x.timers,s=q.get(this);if(i)s[i]&&s[i].stop&&r(s[i]);else for(i in s)s[i]&&s[i].stop&&Cn.test(i)&&r(s[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));(t||!n)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=q.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,s=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;s>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function qn(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=jt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:qn("show"),slideUp:qn("hide"),slideToggle:qn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=Ln.prototype.init,x.fx.tick=function(){var e,t=x.timers,n=0;for(xn=x.now();t.length>n;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||x.fx.stop(),xn=undefined},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){bn||(bn=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(bn),bn=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===undefined?this:this.each(function(t){x.offset.setOffset(this,e,t)});var t,n,i=this[0],o={top:0,left:0},s=i&&i.ownerDocument;if(s)return t=s.documentElement,x.contains(t,i)?(typeof i.getBoundingClientRect!==r&&(o=i.getBoundingClientRect()),n=Hn(s),{top:o.top+n.pageYOffset-t.clientTop,left:o.left+n.pageXOffset-t.clientLeft}):o},x.offset={setOffset:function(e,t,n){var r,i,o,s,a,u,l,c=x.css(e,"position"),p=x(e),f={};"static"===c&&(e.style.position="relative"),a=p.offset(),o=x.css(e,"top"),u=x.css(e,"left"),l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1,l?(r=p.position(),s=r.top,i=r.left):(s=parseFloat(o)||0,i=parseFloat(u)||0),x.isFunction(t)&&(t=t.call(e,n,a)),null!=t.top&&(f.top=t.top-a.top+s),null!=t.left&&(f.left=t.left-a.left+i),"using"in t?t.using.call(e,f):p.css(f)}},x.fn.extend({position:function(){if(this[0]){var e,t,n=this[0],r={top:0,left:0};return"fixed"===x.css(n,"position")?t=n.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(r=e.offset()),r.top+=x.css(e[0],"borderTopWidth",!0),r.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-r.top-x.css(n,"marginTop",!0),left:t.left-r.left-x.css(n,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,n){var r="pageYOffset"===n;x.fn[t]=function(i){return x.access(this,function(t,i,o){var s=Hn(t);return o===undefined?s?s[n]:t[i]:(s?s.scrollTo(r?e.pageXOffset:o,r?o:e.pageYOffset):t[i]=o,undefined)},t,i,arguments.length,null)}});function Hn(e){return x.isWindow(e)?e:9===e.nodeType&&e.defaultView}x.each({Height:"height",Width:"width"},function(e,t){x.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){x.fn[r]=function(r,i){var o=arguments.length&&(n||"boolean"!=typeof r),s=n||(r===!0||i===!0?"margin":"border");return x.access(this,function(t,n,r){var i;return x.isWindow(t)?t.document.documentElement["client"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body["scroll"+e],i["scroll"+e],t.body["offset"+e],i["offset"+e],i["client"+e])):r===undefined?x.css(t,n,s):x.style(t,n,r,s)},t,o?r:undefined,o,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}),"object"==typeof e&&"object"==typeof e.document&&(e.jQuery=e.$=x)})(window);
diff --git a/resources/lang/de.php b/resources/lang/de.php
new file mode 100644
index 0000000..2354ca4
--- /dev/null
+++ b/resources/lang/de.php
@@ -0,0 +1,365 @@
+﻿<?php
+/**
+* Deutsch translation
+*
+* @author   Revo
+* @author   Nero51282
+* @version  1.1
+*/
+$translate = array(
+	'Access server' => 'Auf Server zugreifen',
+	'Access relay' => 'Auf Relay zugreifen',
+	'Disconnect' => 'Trennen',
+	'Servers' => 'Server',
+	'Server' => 'Server',
+	'Password' => 'Passwort',
+	'Admin level' => 'Admin Level',
+	'Connection' => 'Verbindung',
+	'Please put a password.' => 'Bitte erstellen Sie ein Passwort.',
+	'Connection error' => 'Verbindungs Fehler',
+	'Connection error: invalid session.' => 'Verbindungs Fehler : invalid Session.',
+	'Servers configuration' => 'Server Konfiguration',
+	'Online configuration' => 'Online Konfiguration',
+	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'Es ist Ihre erste Verbindung und kein Server ist konfiguriert. Wählen Sie ein Passwort, um Ihre Server zu konfigurieren.',
+	'Unable to save password.' => 'Passwort kann nicht gespeichert werden.',
+	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Online Konfiguration is deaktiviert. Benutzen Sie "./config/servers.cfg.php".',
+	'Offline server.' => 'Offline Server.',
+	'Authentication error.' => 'Authentifizierung Fehler.',
+	'Add to favourite' => 'Zu Favoriten hinzufügen',
+	'Current map' => 'Laufende Map',
+	'Name' => 'Name',
+	'Author' => 'Autor',
+	'Environment' => 'Umgebung',
+	'Map UId' => 'Map UId',
+	'Game mode' => 'Spiel Modus',
+	'No thumbnail' => 'Keine Vorschau',
+	'Server name' => 'Server Name',
+	'Status' => 'Status',
+	'Server login' => 'Server Login',
+	'Connected on' => 'Verbunden zu',
+	'Dedicated version' => 'Server Version',
+	'Statistics' => 'Statistiken',
+	'Uptime' => 'Läuft seit',
+	'Number of connections' => 'Anzahl der Verbindungen',
+	'Average connection time' => 'Verbindungszeit Ø',
+	'Average number of players' => 'Spieler Anzahl Ø',
+	'Recv net rate' => 'Empfangsrate',
+	'Send net rate' => 'Senderate',
+	'Total receiving size' => 'Totaler Empfang',
+	'Total sending size' => 'Totale Emission',
+	'Players' => 'Spieler',
+	'Detailed mode' => 'Detaillierte Modus',
+	'Simple mode' => 'Einfacher Modus',
+	'Nickname' => 'Nickname',
+	'Login' => 'Login',
+	'For the selection' => 'Für die Auswahl',
+	'Ban' => 'Sperren',
+	'Kick' => 'Kicken',
+	'Spectator' => 'Zuschauer',
+	'Player' => 'Spieler',
+	'Team' => 'Team',
+	'Guest' => 'Einladen',
+	'Ignore' => 'Auslassen',
+	'Red team' => 'Rote Team',
+	'Blue team' => 'Blaue Team',
+	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Ergebnisse wurden geändert : Les scores ont été modifiés : $00fblaue Team$fff hat !scoreTeamBlue und l\'$f00rote Team $fffhat !scoreTeamRed',
+	'Server options' => 'Server Optionen',
+	'General' => 'Allgemein',
+	'Comment' => 'Kommentar',
+	'Player password' => 'Spieler Passwort',
+	'Spectator password' => 'Zuschauer Passwort',
+	'Nb max of players' => 'Max Spieler Anzahl',
+	'Next value' => 'Nächster Wert',
+	'Nb max of spectators' => 'Max Zuschauer Anzahl',
+	'Advanced' => 'Erweitert',
+	'P2P Upload' => 'P2P Upload',
+	'P2P Download' => 'P2P Download',
+	'Ladder mode' => 'Ladder Modus',
+	'Vehicles quality' => 'Fahrzeuge Qualität',
+	'Vote expiration' => 'Wahl Ablaufzeit',
+	'sec' => 'sek', // Second
+	'Vote ratio' => 'Wahl Ratio',
+	'Hidden server' => 'Versteckte Server',
+	'Map download' => 'Maps Download',
+	'Replays auto save' => 'Replays automatik speichern',
+	'Buddy notification' => 'Buddy Benachrichtigung',
+	'Save' => 'Speichern',
+	'Inactive' => 'Inaktiv',
+	'Forced' => 'Erzwungen',
+	'Fast' => 'Schnell',
+	'High' => 'Hoch',
+	'Game infos' => 'Spiel-Info',
+	'Game information' => 'Spiel-Info',
+	'Color' => 'Farbe',
+	'Black' => 'Schwarz',
+	'Red' => 'Rot',
+	'Green' => 'Grün',
+	'Blue' => 'Blau',
+	'Orange' => 'Orange',
+	'Pink' => 'Rosa',
+	'Purple' => 'Violett',
+	'Grey' => 'Grau',
+	'White' => 'Weiß',
+	'Message destination' => 'Nachrichtenziel',
+	'Chat' => 'Chat',
+	'Show server lines' => 'Server-Linien zeigen',
+	'Hide server lines' => 'Server-Linien ausblenden',
+	'Default color: yellow' => 'Standard-Farbe : gelb',
+	'Message' => 'Nachricht',
+	'Destination' => 'Ziel',
+	'Send' => 'Senden',
+	'Unable to create the folder' => 'Das Verzeichnis konnte nicht erstellt werden',
+	'Unable to rename the folder' => 'Das Verzeichnis konnte nicht umbenannt werden',
+	'Unable to move the folder' => 'Das Verzeichnis konnte nicht verschoben werden',
+	'Unable to delete the folder' => 'Das Verzeichnis konnte nicht gelöscht werden',
+	'List' => 'Liste',
+	'Go to the current map' => 'Zur aktuelle Map',
+	'Map' => 'Map',
+	'Delete' => 'Entfernen',
+	'Move after the current map' => 'Hinter die aktuelle Map verschieben',
+	'Unable to rename the map' => 'Die Map konnte nicht umbenannt werden',
+	'Unable to move the map' => 'Die Map konnte nicht verschoben werden',
+	'Unable to delete the map' => 'Die Map konnte nicht gelöscht werden',
+	'Local' => 'Lokal',
+	'Do you really want to remove this selection?' => 'Möchten Sie diese Auswahl wirklich entfernen?',
+	'Move' => 'Verschieben',
+	'Rename' => 'Umbennenen',
+	'Download' => 'Herunterladen',
+	'Insert' => 'Einfügen',
+	'Add' => 'Hinzufügen',
+	'Cancel' => 'Abbrechen',
+	'Replace the special characters' => 'Sonderzeichen ersetzen',
+	'in the folder:' => 'im Ordner:',
+	'Root' => 'Root',
+	'The map,is currently used by the server.' => 'Die Map wird momentan vom Server verwendet.',
+	'MatchSettings' => 'MatchSettings',
+	'Contains' => 'Enthält',
+	'Modified' => 'Geändert',
+	'Edit' => 'Editieren',
+	'Load' => 'Laden',
+	'Save ' => 'Speichern',
+	'Create' => 'Erstellen',
+	'Unable to save the MatchSettings' => 'Unmöglich, MatchSettings zu speichern',
+	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'MatchSettings "!matchSettingName" wurde erfolgreich in Ordner erstellt',
+	'a MatchSettings' => 'ein MatchSettings',
+	'Create a MatchSettings' => 'Erstellen ein MatchSettings',
+	'MatchSettings name' => 'MatchSettings Name',
+	'Maps' => 'Maps',
+	'Make selection' => 'Auswahl treffen',
+	'Import all folder' => 'ganze Ordner importieren',
+	'Select' => 'Wählen',
+	'MatchSettings selected maps:' => 'MatchSettings ausgewählte Maps:',
+	'View the MatchSettings selection' => 'MatchSettings Auswahl ansehen',
+	'MatchSettings selection' => 'MatchSettings Auswahl',
+	'Remove map from the selection' => 'Map von der Auswahl entfernen',
+	'Close' => 'Schließen',
+	'HotSeat' => 'HotSeat',
+	'Time limit' => 'Zeitlimit',
+	'Rounds count' => 'Runden Zahl',
+	'Filter' => 'Filter',
+	'Lan' => 'Lan',
+	'Internet' => 'Internet',
+	'Solo' => 'Solo',
+	'Sort index' => 'Sortierungsindex',
+	'Random map order' => 'Zufällige Maps Ordnung',
+	'Default game mode' => 'Game Mode Standardeinstellung',
+	'No map selected for the MatchSettings.' => 'Keine Map ist für MatchSettings ausgewählt.',
+	'The MatchSettings name already exists! It will be overwritten.' => 'Diese MatchSettings Name ist schon verwendet! Die wird überschrieben.',
+	'Order' => 'Ordnen',
+	'Automatic sort' => 'Automatische Sortierung',
+	'Random' => 'Zufällig',
+	'Manual sort' => 'Manuelle Sortierung',
+	'Save the current MatchSettings' => 'MatchSettings speichern',
+	'Reset' => 'Neu stellen',
+	'Transfer mode' => 'Transfer-Modus',
+	'at the end of list' => 'zum Ende der Liste',
+	'after current map' => 'hinter aktuelle Map',
+	'only in the folder' => 'nur in den Ordner',
+	'Options' => 'Optionen',
+	'Go to the maps list when upload is complete' => 'Zur Maps-Liste gehen, wenn Upload fertig ist',
+	'Upload' => 'Upload',
+	'Failed' => 'Gescheitert',
+	'Upload a file' => 'Datei hochladen',
+	'Drop files here to upload' => 'Dateien hier ablegen zum Hochladen',
+	'Upload not finished' => 'Upload nicht fertig',
+	'from' => 'von',
+	'Kb' => 'Kb',
+	'Mb' => 'Mb',
+	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} hat eine ungültige Dateierweiterung. Erlaubte Formate sind {extensions}.',
+	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} ist zu groß. Maximale Dateigröße ist {sizeLimit}.',
+	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} ist zu klein. Minimale Dateigröße ist {minSizeLimit}.',
+	'{file} is empty, please select files again without it.' => '{file} ist leer. Wählen Sie noch einmal bitte.',
+	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Die Dateien werden hochgeladen. Wenn Sie jetzt die Seite verlassen wird der Upload abgebrochen.',
+	'No file was uploaded' => 'Keine Datei wurde hochgeladen',
+	'The file is empty.' => 'Die Datei ist leer.',
+	'The file size is too large.' => 'Die Dateigröße ist zu groß.',
+	'The file has invalid extension (allowed extensions:' => 'Die Datei hat eine ungültige Dateierweiterung (erlaubte Dateierweiterungen:',
+	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Die Datai wurde nicht hochgeladen. Der Upload wurde abgebrochen oder ein Server-Fehler ist aufgetreten.',
+	'Server error. The upload destination folder isn\'t writable.' => 'Server Fehler. Der Upload Zielordner ist nicht beschreibbar.',
+	'Plugins' => 'Plugins',
+	'plugin installed' => 'Plugin installiert',
+	'plugins installed' => 'Plugins installiert',
+	'Cannot include another plugins config file.' => 'Keine weitere Plugins Konfiguration Datei kann addiert werden.',
+	'Variable "$PLUGINS" not found.' => 'Variable "$PLUGINS" nicht gefunden.',
+	'Plugins are extensions to add features to Adminserv.' => 'Plugins lassen Sie neue Funktionen zu AdminServ hinzufügen.',
+	'Install a plugin' => 'Wie installiert man Plugins??',
+	'See all plugins:' => 'Zeige alle Plugins:',
+	'Click here' => 'Klicken Sie hier',
+	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Entpacken sie das Plugin und verschieben Sie den Inhalt in den &laquo; plugins &raquo; Ordner von AdminServ.',
+	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'Fügen Sie den Namen des Plugin Ordners in der Konfiguratiosdatei der Erweiterungen ein(extension.cfg.php).',
+	'Create a new plugin' => 'Wie erstellt man sein eigenes Plugin?',
+	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>Um ein Plugin zu erstellen, gehe in de Plugin Orner und kopiere den Ordner _newplugin. Ersetze die Werte in der config.ini Datei und bennene den Order um.<br />Dort befinden sich zwei PHP Dateien:</p><ul><li>script.php : Diese Datei wird vor dem Header der Seite ausgeführt. Hier werden alle Plugin Scripte plaziert.</li><li>view.php : Diese Datei ist für die Anzeige des Plugins verantworlich und wird nach dem Header der seite ausgeführt. Hier wird der ganze HTML Code plaziert.</li></ul><p>Die benötigten Recourcen (classes, js, css) können Sie in die Dateien einbinden.</p>',
+	'Unable to delete the playlist' => 'Unmöglich, die Playlist zu löschen',
+	'Player login' => 'Spieler Login',
+	'Clean the list' => 'Liste reinigen',
+	'The list is already empty.' => 'Die Liste ist schon Leer.',
+	'No player' => 'Kein Spieler auf dem Server',
+	'IP address' => 'IP Adresse',
+	'Client' => 'Client',
+	'Blacklist' => 'Blacklist',
+	'Remove from the list' => 'Aus der Liste löschen',
+	'Select a player' => 'Wählen Sie einen Spieler',
+	'Enter another login' => 'Geben Sie einen anderen Login',
+	'Add in the' => 'Addieren zu',
+	'Playlists' => 'Playlists',
+	'Playlist' => 'Playlist',
+	'Type' => 'Art',
+	'Playlist name' => 'Playlist Name',
+	'New playlist' => 'Neue Playlist',
+	'players' => 'Spieler',
+	'player' => 'Spieler',
+	'No playlist' => 'Kein Playlist wird gefunden',
+	'You are not allowed to configure the servers' => 'Sie sind nicht erlaubt, Servers zu Konfigurieren.',
+	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Kein Server ist verfügbar. Um einen Server zu addieren, Konfigurieren Sie die Datei "config/servers.cfg.php"',
+	'The servers configuration file isn\'t recognized by AdminServ.' => 'Die Datei für die Servers Konfiguration wird nicht von AdminServ anerkannt.',
+	'This server has been duplicated.' => 'Dieser Server wurde erfolgreich dupliziert.',
+	'Unable to duplicate server.' => 'Unmöglich, den Server zu vervielfältigen.',
+	'copy' => 'Kopie',
+	'Servers list' => 'Servers Liste',
+	'Address' => 'Adresse',
+	'Port' => 'Port',
+	'SuperAdmin level' => 'SuperAdmin Stufe',
+	'User level' => 'User Stufe',
+	'Manage' => 'Management',
+	'None' => 'Keiner',
+	'Local network' => 'Lokalen Netzwerk',
+	'All' => 'Alle',
+	'Removed' => 'Entfernt',
+	'Missing' => 'Vermisst',
+	'No server' => 'Kein Server',
+	'servers' => 'Server',
+	'server' => 'Server',
+	'Duplicate' => 'Vervielfältigen',
+	'Modify' => 'Ändern',
+	'The "!serverName" server has been deleted.' => 'Der Server"!serverName" wurde gelöscht.',
+	'This server has been modified.' => 'Dieser Server wurde modifiziert.',
+	'Unable to modify the server.' => 'Unmöglich, der Server zu modifizieren.',
+	'This server has been added.' => 'Der Server wurde erfolgreich addiert.',
+	'Unable to add the server.' => 'Unmöglich, der Server zu addieren.',
+	'Add server' => 'Server hinzufügen',
+	'Edit server' => 'Server bearbeiten',
+	'Back' => 'Zurück',
+	'Connection information' => 'Verbindung Informationen',
+	'Server name without color' => 'Server Name ohne Farbe',
+	'IP address or domain name' => 'IP Adresse oder Domain-Name',
+	'XMLRPC port' => 'XMLRPC Port',
+	'Port for remote control' => 'Port für Fernsteuerung',
+	'Optionnal information' => 'optionale Angaben',
+	'Server MatchSettings' => 'Server MatchSettings',
+	'Current server MatchSettings name' => 'Server\'s aktuelle MatchSettings Name',
+	'Possible values for the admin level:' => 'Mögliche Werte für Admin Stufe :',
+	'all => all access' => 'all => Zugriff zu alle',
+	'local => local network access' => 'local => Lokalen Netzwerk Zugriff',
+	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => Zugriff zu einer oder mehreren IP Adressen',
+	'none => removed from the access list' => 'none => aus der Zugriffliste entfernt',
+	'No server available' => 'Keiner Server ist verfügbar',
+	'No game mode available' => 'Kein Spielmodus ist verfügbar',
+	'Map end time' => 'Map Ende Zeit',
+	'Round/lap end time' => 'Round/Lap Ende Zeit',
+	'Respawn' => 'Respawn',
+	'Default' => 'Standard',
+	'Auto (based on map)' => 'Auto (hängt von der Map)',
+	'Choose time' => 'Zeit Wählen',
+	'Return to the default value' => 'Zurück auf den Standardwert',
+	'All WarmUp duration' => 'Alle WarmUps Dauer',
+	'Enable' => 'Aktivieren',
+	'Disable' => 'Deaktivieren',
+	'Force show of all opponents' => 'Force show alle Gegner',
+	'Let player choose' => 'Lassen Spieler wählen',
+	'All opponents' => 'Alle Gegner',
+	'minimal opponents' => 'minimale Gegner',
+	'Choose opponents number' => 'Gegner Nummer Wählen',
+	'Script name' => 'Script Name',
+	'Use new rules' => 'Neue Regeln verwenden',
+	'Points limit' => 'Punkte Begrenzung',
+	'Custom points limit' => 'Benutzerdefinierte Punkte Begrenzung',
+	'Force laps' => 'Lap enden',
+	'Start synchronization period' => 'Synchronisierungszeit am Start',
+	'Maximal points' => 'Maximal Punkte',
+	'Number of laps' => 'Laps Nummer',
+	'Rounds per map' => 'Runden pro Map',
+	'Number of winners' => 'Gewinner Nummer',
+	'No player available' => 'Kein Spieler zur Verfügung',
+	'New' => 'Neu',
+	'Parent folder' => 'Vorgängerordner',
+	'Folder options' => 'Ordner-Optionen',
+	'Do you really want to remove this folder !currentDir?' => 'Möchten Sie den Ordner !currentDir wirklich entfernen ?',
+	'Rename folder' => 'Ordner umbenennen',
+	'Move folder' => 'Ordner verschieben',
+	'Move folder <b>!currentDir</b> in:' => 'Ordner <b>!currentDir</b> verschieben nach :',
+	'The server is not accessible.' => 'Der Server ist nicht verfügbar.',
+	'You are not allowed at this admin level' => 'Sie besitzen nicht die benötigten Rechte.',
+	'The password doesn\'t match to the server.' => 'Falsche Kennwort.',
+	'Client not initialized' => 'client nicht initialisiert',
+	'Unknown command' => 'Unbekannter Befehl',
+	'$99FThis round is a draw.' => '$99FUnentschiedene Runde.',
+	'$99FThe $<$00FBlue team$> wins this round.' => '$99FDas $00Fblaue Team gewinnt diese Runde.',
+	'$99FThe $<$F00Red team$> wins this round.' => '$99FDas $F00rote Team gewinnt diese Runde.',
+	'maps' => 'Maps',
+	'map' => 'Map',
+	'No map' => 'Kein Map wird gefunden',
+	'matchsettings' => 'Matchsettings',
+	'matchsetting' => 'Matchsetting',
+	'No matchsetting' => 'Kein Matchsetting',
+	'text->XML conversion error' => 'text->XML Konvertierungsfehler',
+	'Saving XML file error' => 'XML Datei Speicherungsfehler',
+	'The folder "logs" is not writable.' => 'Der Ordner "logs" kann nicht geschrieben werden.',
+	'The folder "logs" does not exist.' => 'Der Ordner "logs" existiert nicht.',
+	'Unable to create log file:' => 'Unmöglich, die Log Datei zu erstellen :',
+	'Unable to add log in file:' => 'Unmöglich, Log zur Datei zu addieren :',
+	'This server does not exist' => 'Dieser Server existiert nicht',
+	'Change password' => 'Kennwort ändern',
+	'Current' => 'Aktuell',
+	'The current password doesn\'t match.' => 'Das aktuelle Passwort ist falsch.',
+	'The password has been changed.' => 'Das Kennwort wurde geändert.',
+	'Not rated' => 'Nicht bewertet',
+	'Unable to delete server.' => 'Unmöglich, der Server zu löschen',
+	'Guest-Ban' => 'Einladen-Sperren',
+	'Access as player' => 'Als Spieler beitreten',
+	'Access as spectator' => 'Als Zuschauer beitreten',
+	'Disable horns' => 'Deaktivieren Hupen',
+	'Current vote' => 'Aktuelle Bewertung',
+	'Cancel vote' => 'Abbrechen stimmen',
+	'Change order' => 'Ändern Sie die Reihenfolge',
+	'Servers order' => 'Server um',
+	'This path was not required rights:' => 'Dieser Weg war nicht Rechte erforderlich:',
+	'needs' => 'Bedürfnisse',
+	'Plugin error: script.php or view.php file is missing.' => 'Plugin-Fehler: script.php oder view.php Datei fehlt.',
+	'No server admin levels configured.' => 'Nicht konfiguriert Server Admin Ebenen.',
+	'Gold time' => 'Gold Zeit',
+	'Cost' => 'Kosten',
+	'Team infos' => 'Team Informationen',
+	'Script settings' => 'Script-Einstellungen',
+	'Script settings updated.' => 'Script-Einstellungen aktualisiert.',
+	'Change authentication password' => 'Ändern Sie Passwort-Authentifizierung',
+	'You changed the password "!authLevel", remember it at the next connection!' => 'Sie das Passwort geändert "!authLevel", erinnern sie bei der nächsten Verbindung!',
+	'Automatic' => 'Automatisch',
+	'Choose number' => 'Wählen Sie die Anzahl',
+	'Client inputs max latency' => 'Client Eingaben max Latenzzeit',
+	'Script info' => 'Informationen',
+	'Compatible map types' => 'Kompatibel Maptypen',
+	'Script parameters' => 'Skriptparameter',
+	'Value' => 'Wert',
+	'The server already exist! Change the name.' => 'Der Server existiert bereits! Ändern Sie den Namen.',
+);
+?>
\ No newline at end of file
diff --git a/resources/lang/dk.php b/resources/lang/dk.php
new file mode 100644
index 0000000..d488add
--- /dev/null
+++ b/resources/lang/dk.php
@@ -0,0 +1,377 @@
+﻿<?php
+/**
+* Danish translation
+*
+* @author   Steppie
+* @version  1.0
+*/
+$translate = array(
+	'Access server' => 'Tilslut server',
+	'Access relay' => 'Tilslut reply',
+	'Disconnect' => 'Afbryd forbindelse',
+	'Servers' => 'Servere',
+	'Server' => 'Server',
+	'Password' => 'Adgangskode',
+	'Admin level' => 'Admin niveau',
+	'Connection' => 'Opret forbindelse',
+	'Please put a password.' => 'Indtast venligst en adgangskode.',
+	'Connection error' => 'Forbindelsen fejlede',
+	'Connection error: invalid session.' => 'Forbindelsen fejlede: invalid Session.',
+	'Servers configuration' => 'Servere Konfiguration',
+	'Online configuration' => 'Online Konfiguration',
+	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'Det er din første forbindelse. Vælg en adgangskode for at konfigurer dine servere.',
+	'Unable to save password.' => 'Adgangskode kan ikke gemmes.',
+	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Online Konfiguration er deaktiveret. Brug istedet: "./config/servers.cfg.php".',
+	'Offline server.' => 'Offline Server.',
+	'Authentication error.' => 'Godkendelse fejlede.',
+	'Add to favourite' => 'Tilføj til farvorit',
+	'Current map' => 'Nuværende bane',
+	'Name' => 'Navn',
+	'Author' => 'Forfatter',
+	'Environment' => 'Miljø',
+	'Map UId' => 'Bane UId',
+	'Game mode' => 'Spil stil',
+	'No thumbnail' => 'Ingen skitse',
+	'Server name' => 'Server Navn',
+	'Status' => 'Status',
+	'Server login' => 'Server Login',
+	'Connected on' => 'Forbind til',
+	'Dedicated version' => 'Dedikeret Version',
+	'Statistics' => 'Statistik',
+	'Uptime' => 'Oppetid',
+	'Number of connections' => 'Tilslutnings antal',
+	'Average connection time' => 'Gennemsnitlig tilslutning tid',
+	'Average number of players' => 'Gennemsnitlig spiller antal',
+	'Recv net rate' => 'Upload rate',
+	'Send net rate' => 'Download rate',
+	'Total receiving size' => 'Total modtaget størrelse',
+	'Total sending size' => 'Total sendt størrelse',
+	'Players' => 'Spillere',
+	'Detailed mode' => 'Detaljeret tilstand',
+	'Simple mode' => 'Simpel tilstand',
+	'Nickname' => 'Kælenavn',
+	'Login' => 'Login',
+	'For the selection' => 'For de valgte',
+	'Ban' => 'Ban',
+	'Kick' => 'Spark ud!',
+	'Spectator' => 'Tilskuer',
+	'Player' => 'Spiller',
+	'Team' => 'Hold',
+	'Guest' => 'Gæst',
+	'Ignore' => 'Ignorer',
+	'Red team' => 'Rød hold',
+	'Blue team' => 'Blå hold',
+	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Stillingen er blevet ændret : $00fBlå hold$fff har !scoreTeamBlue og $f00Rød hold $fffhar !scoreTeamRed',
+	'Server options' => 'Server indstillinger',
+	'General' => 'Generelt',
+	'Comment' => 'Kommentar',
+	'Player password' => 'Spiller adgangskode',
+	'Spectator password' => 'Tilskure adgangskode',
+	'Nb max of players' => 'Max spiller antal',
+	'Next value' => 'Næste værdi',
+	'Nb max of spectators' => 'Max tilskure antal',
+	'Advanced' => 'Avanceret',
+	'P2P Upload' => 'P2P Upload',
+	'P2P Download' => 'P2P Download',
+	'Ladder mode' => 'Ladder tilstand',
+	'Vehicles quality' => 'Model kvalitet',
+	'Vote expiration' => 'Afstemning udløb',
+	'sec' => 'sek', // Second
+	'Vote ratio' => 'Afstemning Ratio',
+	'Hidden server' => 'Skjul Server',
+	'Map download' => 'Bane Download',
+	'Replays auto save' => 'Replays automatisk gem',
+	'Buddy notification' => 'Ven notifikation',
+	'Save' => 'Gem',
+	'Inactive' => 'Inaktiv',
+	'Forced' => 'Tvungen',
+	'Fast' => 'Hurtig',
+	'High' => 'Høj',
+	'Game infos' => 'Spil info',
+	'Game information' => 'Spil information',
+	'Color' => 'Farve',
+	'Black' => 'Sort',
+	'Red' => 'Rød',
+	'Green' => 'Grøn',
+	'Blue' => 'Blå',
+	'Orange' => 'Orange',
+	'Pink' => 'Rosa',
+	'Purple' => 'Violet',
+	'Grey' => 'Grå',
+	'White' => 'Hvid',
+	'Message destination' => 'Besked destination',
+	'Chat' => 'Chat',
+	'Show server lines' => 'Vis server linier',
+	'Hide server lines' => 'Skjul server linier',
+	'Default color: yellow' => 'Standard farve: gul',
+	'Message' => 'Besked',
+	'Destination' => 'Destination',
+	'Send' => 'Send',
+	'Unable to create the folder' => 'Kunne ikke oprette mappe',
+	'Unable to rename the folder' => 'Kunne ikke omdøbe mappe',
+	'Unable to move the folder' => 'Kunne ikke flytte mappe',
+	'Unable to delete the folder' => 'Kunne ikke slette mappe',
+	'List' => 'Liste',
+	'Go to the current map' => 'Gå til aktuel bane',
+	'Map' => 'Bane',
+	'Delete' => 'Slet',
+	'Move after the current map' => 'Flyt efter aktuelle bane',
+	'Unable to rename the map' => 'Kunne ikke omdøbe banen',
+	'Unable to move the map' => 'Kunne ikke flytte banen',
+	'Unable to delete the map' => 'Kunne ikke slette banen',
+	'Local' => 'Lokal',
+	'Do you really want to remove this selection?' => 'Ønsker du virkelig at slette disse valgte?',
+	'Move' => 'Flyt',
+	'Rename' => 'Omdøb',
+	'Download' => 'Download',
+	'Insert' => 'Indsæt',
+	'Add' => 'Tilføj',
+	'Cancel' => 'Annuller',
+	'Replace the special characters' => 'Udskift specielle karakter',
+	'in the folder:' => 'i mappen:',
+	'Root' => 'Root',
+	'The map,is currently used by the server.' => 'Banen bruges lige nu af serveren',
+	'MatchSettings' => 'MatchSettings',
+	'Contains' => 'Indholder',
+	'Modified' => 'Ændre',
+	'Edit' => 'Ændre',
+	'Load' => 'Indlæs',
+	'Save ' => 'Gem',
+	'Create' => 'Opret',
+	'Unable to save the MatchSettings' => 'Kunne ikke gemme MatchSettings',
+	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'MatchSettings "!matchSettingName" blev med succes oprettet i mappen',
+	'a MatchSettings' => 'en MatchSettings',
+	'Create a MatchSettings' => 'Opret en MatchSettings',
+	'MatchSettings name' => 'MatchSettings Navn',
+	'Maps' => 'Baner',
+	'Make selection' => 'Udvælg',
+	'Import all folder' => 'Importer alle mapper',
+	'Select' => 'Vælg',
+	'MatchSettings selected maps:' => 'MatchSettings udvalgte baner:',
+	'View the MatchSettings selection' => 'Vis MatchSettings udvalgte',
+	'MatchSettings selection' => 'MatchSettings udvalgte',
+	'Remove map from the selection' => 'Slet bane fra udvalgte',
+	'Close' => 'Luk',
+	'HotSeat' => 'HotSeat',
+	'Time limit' => 'Tids begrænsning',
+	'Rounds count' => 'Runde tæller',
+	'Filter' => 'Filter',
+	'Lan' => 'Lan',
+	'Internet' => 'Internet',
+	'Solo' => 'Solo',
+	'Sort index' => 'Sorter index',
+	'Random map order' => 'Tilfældig bane orden',
+	'Default game mode' => 'Standard spil tilstand',
+	'No map selected for the MatchSettings.' => 'Ingen bane valgt fra MatchSettings.',
+	'The MatchSettings name already exists! It will be overwritten.' => 'MatchSettings findes allerede og bliver overskrevet.',
+	'Order' => 'Rækkefølge',
+	'Automatic sort' => 'Automatisk sorter',
+	'Random' => 'Tilfældig',
+	'Manual sort' => 'Manuel sortering',
+	'Save the current MatchSettings' => 'Gem nuværende MatchSettings',
+	'Reset' => 'Reset',
+	'Transfer mode' => 'Transfer-Mode',
+	'at the end of list' => 'til slutning af liste',
+	'after current map' => 'efter aktuelle bane',
+	'only in the folder' => 'kun i mappen',
+	'Options' => 'Muligheder',
+	'Go to the maps list when upload is complete' => 'Gå til bane, når overførslen er færdig',
+	'Upload' => 'Upload',
+	'Failed' => 'Fejlede',
+	'Upload a file' => 'Upload en fil',
+	'Drop files here to upload' => 'Drop filer til upload',
+	'Upload not finished' => 'Upload er ikke færdig',
+	'from' => 'fra',
+	'Kb' => 'Kb',
+	'Mb' => 'Mb',
+	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} er ikke en gyldig filtype. Kun filtyper {extensions} er gyldige.',
+	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} er for stor. Maksimal filstørrelse er {sizeLimit}.',
+	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} er for lille. Minimal filstørrelse er {minSizeLimit}.',
+	'{file} is empty, please select files again without it.' => '{file} er tom, vælg venligst filer igen, uden denne.',
+	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Filerne bliver uploadet, hvis du forlader siden nu, vil upload blive annulleret.',
+	'No file was uploaded' => 'Ingen filer blev uploadet',
+	'The file is empty.' => 'Filen er tom.',
+	'The file size is too large.' => 'Filen er for stor.',
+	'The file has invalid extension (allowed extensions:' => 'Filen er ikke gyldig (godkendte filtyper:',
+	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Filen blev ikke uploadet. Upload blev annulleret eller en server fejl er opstået.',
+	'Server error. The upload destination folder isn\'t writable.' => 'Server fejl. Upload folder er skrivebeskyttet.',
+	'Plugins' => 'Tilføjelser',
+	'plugin installed' => 'Tilføjelse blev installeret',
+	'plugins installed' => 'Tilføjelser blev installeret',
+	'Cannot include another plugins config file.' => 'Kan ikke inkluder en anden tilføjelses konfig fil.',
+	'Variable "$PLUGINS" not found.' => 'Variabel "$PLUGINS" blev ikke fundet.',
+	'Plugins are extensions to add features to Adminserv.' => 'Tilføjelser er udvidelser der tilføje funktioner til AdminServ .',
+	'Install a plugin' => 'Installer en tilføjelse?',
+	'See all plugins:' => 'Se alle tilføjelser :',
+	'Click here' => 'Klik her',
+	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Udpak tilføjelsen til &laquo; plugins &raquo; mappen i AdminServ.',
+	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'I Configuration Extension, tilføjes navnet på den tilføjelsesmappe du lige at tilføjet.',
+	'Create a new plugin' => 'Opret en ny tilføjelse ?',
+	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values ​​in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>For at oprette en tilføjelse, gå til plugins mappen og kopiere filen _newplugin. Udskift værdierne i config.ini filen og mappe navn <br /> Så er der to PHP-filer:</p><ul><li>script.php: Denne fil indlæses inden header af hjemmesiden. Dette er her hvor alle plugin script vil blive placeret.</li><li>view.php: Denne fil er visningen af pluginet, indlæses efter header. Dette er her hvor html-koden skal placeres.</li></ul><p>Du skal oprette ressourcer (classes, js, css) derefter inkluder disse filer.</p>',
+	'Unable to delete the playlist' => 'Kunne ikke slette playlisten',
+	'Player login' => 'Spiller login',
+	'Clean the list' => 'Rengør listen',
+	'The list is already empty.' => 'Listen er allerede tom.',
+	'No player' => 'Ingen spiller',
+	'IP address' => 'IP Adresse',
+	'Client' => 'Client',
+	'Blacklist' => 'Blacklist',
+	'Remove from the list' => 'Fjern fra listen',
+	'Select a player' => 'Vølg en spiller',
+	'Enter another login' => 'Indtast et andet login',
+	'Add in the' => 'Tilføj til',
+	'Playlists' => 'Playlists',
+	'Playlist' => 'Playlist',
+	'Type' => 'Art',
+	'Playlist name' => 'Playlist navn',
+	'New playlist' => 'Ny playlist',
+	'players' => 'Spillere',
+	'player' => 'Spiller',
+	'No playlist' => 'Ingen playlist',
+	'You are not allowed to configure the servers' => 'Du har rettighed til at konfigurer serverne.',
+	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Ingen server tilgænglig, For at tilføje, ret "config/servers.cfg.php" filen',
+	'The servers configuration file isn\'t recognized by AdminServ.' => 'Server konfigurations filen er ikke gyldig til AdminServ.',
+	'This server has been duplicated.' => 'Denne server er blevet buplikeret.',
+	'Unable to duplicate server.' => 'Kunne ikke dupliker.',
+	'copy' => 'Kopier',
+	'Servers list' => 'Servers Liste',
+	'Address' => 'Adresse',
+	'Port' => 'Port',
+	'SuperAdmin level' => 'SuperAdmin niveau',
+	'User level' => 'User niveau',
+	'Manage' => 'Administrer',
+	'None' => 'Ingen',
+	'Local network' => 'Lokal netværk',
+	'All' => 'Alle',
+	'Removed' => 'Fjern',
+	'Missing' => 'Mangler',
+	'No server' => 'Ingen Server',
+	'servers' => 'Servere',
+	'server' => 'Server',
+	'Duplicate' => 'Dupliker',
+	'Modify' => 'Ændre',
+	'The "!serverName" server has been deleted.' => 'Serveren "!serverName" blev slettet.',
+	'This server has been modified.' => 'Serveren blev ændret.',
+	'Unable to modify the server.' => 'Kunne ikke ændre server.',
+	'This server has been added.' => 'Serveren blev tilføjet.',
+	'Unable to add the server.' => 'Kunne ikke tilføje serveren.',
+	'Add server' => 'Tilføj Server',
+	'Edit server' => 'Ændre server',
+	'Back' => 'Tilbage',
+	'Connection information' => 'Forbindelses information',
+	'Server name without color' => 'Servernavn uden farve',
+	'IP address or domain name' => 'IP Adresse eller domænenavn',
+	'XMLRPC port' => 'XMLRPC Port',
+	'Port for remote control' => 'Port til fjernstyring',
+	'Optional information' => 'Valgfri Information',
+	'Server MatchSettings' => 'Server MatchSettings',
+	'Current server MatchSettings name' => 'Serveren\' aktuelle MatchSettings Navn',
+	'Possible values for the admin level:' => 'Mulige størrelse for Admin niveau :',
+	'all => all access' => 'all => Adgang til alle',
+	'local => local network access' => 'local => Lokal netværk adgang',
+	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => Adgang for én eller flere IP adresser',
+	'none => removed from the access list' => 'none => fjern fra adgangsliste',
+	'No server available' => 'Ingen server tilgængelig',
+	'No game mode available' => 'Ingen spil tilstand tilgængelig',
+	'Map end time' => 'Bane slut tid',
+	'Round/lap end time' => 'Rounde/Omgang slut tid',
+	'Respawn' => 'Respawn',
+	'Default' => 'Standard',
+	'Auto (based on map)' => 'Auto (Baseret på banen)',
+	'Choose time' => 'Vælg tid',
+	'Return to the default value' => 'Tilbage til standard værdi',
+	'All WarmUp duration' => 'Alle WarmUps varighed',
+	'Enable' => 'Aktiver',
+	'Disable' => 'Deaktiver',
+	'Force show of all opponents' => 'Tving vis af alle modstandere',
+	'Let player choose' => 'Lad spillere vælge',
+	'All opponents' => 'Alle modtandere',
+	'minimal opponents' => 'minimal modtandere',
+	'Choose opponents number' => 'Vælg modstander nummer',
+	'Script name' => 'Script Navn',
+	'Use new rules' => 'Brug nye regler',
+	'Points limit' => 'Points grænse',
+	'Custom points limit' => 'Brugerdefineret points grænse',
+	'Force laps' => 'Tving omgang',
+	'Start synchronization period' => 'Start synkroniserings period',
+	'Maximal points' => 'Maksimal Points',
+	'Number of laps' => 'Antal omgange',
+	'Rounds per map' => 'Runder pr. bane',
+	'Number of winners' => 'Antal vindere',
+	'No player available' => 'Ingen spiller tilgængelig',
+	'New' => 'Ny',
+	'Parent folder' => 'Hoved mappe',
+	'Folder options' => 'Mappe indstilling',
+	'Do you really want to remove this folder !currentDir?' => 'Ønsker du virkelig at slette denne mappe !currentDir?',
+	'Rename folder' => 'Omdøb mappe',
+	'Move folder' => 'Flyt mappe',
+	'Move folder <b>!currentDir</b> in:' => 'Flyt mappen <b>!currentDir</b> i:',
+	'The server is not accessible.' => 'Serveren er ikke tilgængelig.',
+	'You are not allowed at this admin level' => 'Du har tilladelse med denne admin niveau.',
+	'The password doesn\'t match to the server.' => 'Forkert kodeord til server.',
+	'Client not initialized' => 'Klienten ikke initialiseret',
+	'Unknown command' => 'Ukendt kommando',
+	'$99FThis round is a draw.' => '$99FRunden er uafgjort.',
+	'$99FThe $<$00FBlue team$> wins this round.' => '$99FDet $<$00FBlue team$> vinner denne runde.',
+	'$99FThe $<$F00Red team$> wins this round.' => '$99FDet $<$F00Red team$> vinner denne runde.',
+	'maps' => 'Baner',
+	'map' => 'Bane',
+	'No map' => 'Ingen baner',
+	'matchsettings' => 'Matchsettings',
+	'matchsetting' => 'Matchsetting',
+	'No matchsetting' => 'Ingen Matchsetting',
+	'text->XML conversion error' => 'text->XML Konverteringsfejl',
+	'Saving XML file error' => 'Kunne ikke gemme XML fil',
+	'The folder "logs" is not writable.' => 'Mappen "logs" er skrivebeskyttet.',
+	'The folder "logs" does not exist.' => 'Mappen "logs" findes ikke.',
+	'Unable to create log file:' => 'Kunne ikke oprette log fil:',
+	'Unable to add log in file:' => 'Kunne ikke tilføje log i filen:',
+	'This server does not exist' => 'Denne server findes ikke',
+	'Change password' => 'Ændre adgangskode',
+	'Current' => 'Aktuel',
+	'The current password doesn\'t match.' => 'Det aktuelle kodeord passer ikke.',
+	'The password has been changed.' => 'Adgangskoden er blevet ændret.',
+	'Not rated' => 'Ikke bedømt',
+	'Unable to delete server.' => 'Kunne ikke slette server',
+	'Guest-Ban' => 'Gæst-Ban',
+	'Access as player' => 'Tilslut som spiller',
+	'Access as spectator' => 'Tilslut som tilskure',
+	'Disable horns' => 'Deaktiver horn',
+	'Current vote' => 'Aktuel afstemning',
+	'Cancel vote' => 'Annuller afstemning',
+	'Change order' => 'Ændre rækkefølge',
+	'Servers order' => 'Server rækkefølge',
+	'This path was not required rights:' => 'Denne sti var ikke påkrævet rettigheder:',
+	'needs' => 'behov',
+	'Plugin error: script.php or view.php file is missing.' => 'Tilføjelse-fejl: script.php eller view.php fil mangler.',
+	'No server admin levels configured.' => 'Ingen server admin niveau konfigureret.',
+	'Gold time' => 'Guld tid',
+	'Cost' => 'Værdi',
+	'Team infos' => 'Hold Information',
+	'Script settings' => 'Script-indstillinger',
+	'Script settings updated.' => 'Script-indstillinger opdateret.',
+	'Change authentication password' => 'Skift autentificerings adgangskode',
+	'You changed the password "!authLevel", remember it at the next connection!' => 'Du har ændret adgangskode "!authLevel", husk det til næste login!',
+	'Automatic' => 'Automatisk',
+	'Choose number' => 'Vælg nummer',
+	'Client inputs max latency' => 'Client inputs max latency',
+	'Script info' => 'Script Information',
+	'Compatible map types' => 'Kompatible bane typer',
+	'Script parameters' => 'Script parametre',
+	'Value' => 'Værdi',
+	'The server already exist! Change the name.' => 'Serveren findes allerede! Ændre navnet.',
+	'Version' => 'Version',
+	'Disable vote ratio' => 'Deaktiver stemme forholdet',
+	'Manage server options' => 'Administrer server indstillinger',
+	'Import' => 'Importer',
+	'Export' => 'Eksporter',
+	'No export available' => 'Ingen eksport tilgængelig',
+	'No such file or file is not readable' => 'Filen findes ikke eller filen kan ikke læses',
+	'Server options are exported in' => 'Server indstillinger overføres til',
+	'Unable to export server options' => 'Kunne ikke overføre server indstillinger',
+	'Maps base folder' => 'Hoved bane mappe',
+	'Default path from maps folder for listing maps' => 'Standard sti fra "bane" mappen til visning af baner',
+	'No folder' => 'Ingen mappe',
+	'Server selection' => 'Vælg server',
+);
+?>
\ No newline at end of file
diff --git a/resources/lang/es.php b/resources/lang/es.php
new file mode 100644
index 0000000..8516daf
--- /dev/null
+++ b/resources/lang/es.php
@@ -0,0 +1,355 @@
+<?php
+/**
+* Español translation
+*
+* @author   Revo
+* @author   Kev717
+* @version  1.1
+*/
+$translate = array(
+	'Access server' => 'Acceder al servidor',
+	'Access relay' => 'Acceder al repetidor',
+	'Disconnect' => 'Desconexión',
+	'Servers' => 'Servidores',
+	'Server' => 'Servidor',
+	'Password' => 'Contraseña',
+	'Admin level' => 'Nivel admin',
+	'Connection' => 'Conexión',
+	'Please put a password.' => 'Por favor, ponga una contraseña.',
+	'Connection error' => 'Error de conexión',
+	'Connection error: invalid session.' => 'Error de conexión : sesión no válido.',
+	'Servers configuration' => 'Configuración dos servidores',
+	'Online configuration' => 'Configuration en línea',
+	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'Esta es su primera conexión y no hay un servidor configurado. Elija una contraseña para configurar los servidores.',
+	'Unable to save password.' => 'Imposible guardar el contraseña',
+	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Configuración en línea está desactivado. Utilice el fichero "./config/servers.cfg.php".',
+	'Offline server.' => 'Servidor offline.',
+	'Authentication error.' => 'Error de autenticación.',
+	'Add to favourite' => 'Añadir a favoritos',
+	'Current map' => 'Mapa actual',
+	'Name' => 'Nombre',
+	'Author' => 'Autor',
+	'Environment' => 'Ambiente',
+	'Map UId' => 'Mapa UId',
+	'Game mode' => 'Modo de juego',
+	'No thumbnail' => 'No hay miniatura',
+	'Server name' => 'Nombre del servidor',
+	'Status' => 'Estado',
+	'Server login' => 'Login servidor',
+	'Connected on' => 'Conectado a',
+	'Dedicated version' => 'Versión dedicada',
+	'Statistics' => 'Estadísticas',
+	'Uptime' => 'Empezado desde',
+	'Number of connections' => 'Número de conexiones',
+	'Average connection time' => 'Tiempo de conexión promedio',
+	'Average number of players' => 'Número de jugadores promedio',
+	'Recv net rate' => 'Tasa de recepción',
+	'Send net rate' => 'Tasa de envío',
+	'Total receiving size' => 'Recepción total',
+	'Total sending size' => 'Emisión total',
+	'Players' => 'Jugadores',
+	'Detailed mode' => 'Modo detalle',
+	'Simple mode' => 'Modo sencillo',
+	'Nickname' => 'Seudónimo',
+	'Login' => 'Login',
+	'For the selection' => 'Para la selección',
+	'Ban' => 'Banear',
+	'Kick' => 'Kicker',
+	'Spectator' => 'Espectador',
+	'Player' => 'Jugador',
+	'Team' => 'Equipo',
+	'Guest' => 'Invitar',
+	'Ignore' => 'Ignorar',
+	'Red team' => 'Equipo rojo',
+	'Blue team' => 'Equipo azul',
+	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Los resultados han sido modificados : el $00fequipo azul$fff con !scoreTeamBlue y el $f00equipo rojo $fffcon !scoreTeamRed',
+	'Server options' => 'Opciones servidor',
+	'General' => 'General',
+	'Comment' => 'Comentarios',
+	'Player password' => 'Contraseña jugador',
+	'Spectator password' => 'Contraseña espectador',
+	'Nb max of players' => 'N° máximo de jugadores',
+	'Next value' => 'Próximo valor',
+	'Nb max of spectators' => 'N° máximo de espectadores',
+	'Advanced' => 'Avanzado',
+	'P2P Upload' => 'Carga P2P',
+	'P2P Download' => 'Descarga P2P',
+	'Ladder mode' => 'Modo ladder',
+	'Vehicles quality' => 'Calidad de los vehículos',
+	'Vote expiration' => 'Expiración del voto',
+	'sec' => 'seg', // Second
+	'Vote ratio' => 'Voto ratio',
+	'Hidden server' => 'Servidor oculto',
+	'Map download' => 'Descarga de los mapas',
+	'Replays auto save' => 'Guardar automáticamente los replays',
+	'Buddy notification' => 'Notificaciones amigos',
+	'Save' => 'Guardar',
+	'Inactive' => 'Inactivo',
+	'Forced' => 'Forzado',
+	'Fast' => 'Rápida',
+	'High' => 'Alta',
+	'Game infos' => 'Infos de jeu',
+	'Game information' => 'Información juego',
+	'Color' => 'Color',
+	'Black' => 'Negro',
+	'Red' => 'Rojo',
+	'Green' => 'Verde',
+	'Blue' => 'Azul',
+	'Orange' => 'Naranja',
+	'Pink' => 'Rosa',
+	'Purple' => 'Púrpura',
+	'Grey' => 'Gris',
+	'White' => 'Blanco',
+	'Message destination' => 'Destinación del mensaje',
+	'Chat' => 'Chat',
+	'Show server lines' => 'Visualizar las líneas servidor',
+	'Hide server lines' => 'Ocultar las líneas servidor',
+	'Default color: yellow' => 'Color por defecto : amarillo',
+	'Message' => 'Mensaje',
+	'Destination' => 'Destinación',
+	'Send' => 'Enviar',
+	'Unable to create the folder' => 'Imposible crear el carpeta',
+	'Unable to rename the folder' => 'Imposible renombrar el carpeta',
+	'Unable to move the folder' => 'Imposible desplazar el carpeta',
+	'Unable to delete the folder' => 'Imposible borrar el carpeta',
+	'List' => 'Lista',
+	'Go to the current map' => 'Vaya a mapa actual',
+	'Map' => 'Mapa',
+	'Delete' => 'Borrar',
+	'Move after the current map' => 'Desplazar después el mapa actual',
+	'Unable to rename the map' => 'Imposible renombrar el mapa',
+	'Unable to move the map' => 'Imposible desplazar el mapa',
+	'Unable to delete the map' => 'Imposible borrar el mapa',
+	'Local' => 'Local',
+	'Do you really want to remove this selection?' => '¿Desea realmente borrar este selección?',
+	'Move' => 'Desplazar',
+	'Rename' => 'Renombrar',
+	'Download' => 'Descargar',
+	'Insert' => 'Insertar',
+	'Add' => 'Añadir',
+	'Cancel' => 'Cancelar',
+	'Replace the special characters' => 'Reemplazar caracteres especiales',
+	'in the folder:' => 'en el carpeta :',
+	'Root' => 'Raíz',
+	'The map,is currently used by the server.' => 'El mapa,está siendo utilizado actualmente por el servidor.',
+	'MatchSettings' => 'MatchSettings',
+	'Contains' => 'Contiene',
+	'Modified' => 'Modificado el',
+	'Edit' => 'Editar',
+	'Load' => 'Cargar',
+	'Save ' => 'Guardar',
+	'Create' => 'Crear',
+	'Unable to save the MatchSettings' => 'Imposible guardar el MatchSettings',
+	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'El MatchSettings "!matchSettingName" a sido creada en la carpeta',
+	'a MatchSettings' => 'un MatchSettings',
+	'Create a MatchSettings' => 'Crear un MatchSettings',
+	'MatchSettings name' => 'Nombre del MatchSettings',
+	'Maps' => 'Mapas',
+	'Make selection' => 'Haga una selección',
+	'Import all folder' => 'Importar la carpeta completa',
+	'Select' => 'Seleccionar',
+	'MatchSettings selected maps:' => 'Los mapas seleccionados para MatchSettings:',
+	'View the MatchSettings selection' => 'Ver MatchSettings selección',
+	'MatchSettings selection' => 'Selección del MatchSettings',
+	'Remove map from the selection' => 'Quitar esta mapa de la selección',
+	'Close' => 'Cerrar',
+	'HotSeat' => 'HotSeat',
+	'Time limit' => 'Límite de tiempo',
+	'Rounds count' => 'Nombre de rounds',
+	'Filter' => 'Filtros',
+	'Lan' => 'Lan',
+	'Internet' => 'Internet',
+	'Solo' => 'Solo',
+	'Sort index' => 'Índice de clasificación',
+	'Random map order' => 'Orden de los mapas aleatorio',
+	'Default game mode' => 'Modo de juego por defecto',
+	'No map selected for the MatchSettings.' => 'Ningún mapa seleccionado para MatchSettings.',
+	'The MatchSettings name already exist! It will be overwritten.' => 'MatchSettings nombre ya existe! Va a ser sobreescrito.',
+	'Order' => 'Orden',
+	'Automatic sort' => 'Clasificación automática',
+	'Random' => 'Aleatorio',
+	'Manual sort' => 'Clasificación manual',
+	'Save the current MatchSettings' => 'Guardar el MatchSettings actual',
+	'Reset' => 'Reinicializar',
+	'Transfer mode' => 'Modo del transferencia',
+	'at the end of list' => 'al final de la lista',
+	'after current map' => 'después mapa actual',
+	'only in the folder' => 'en el carpeta sólo',
+	'Options' => 'Opciones',
+	'Go to the maps list when upload is complete' => 'Vaya a la lista de mapas después de la carga completa',
+	'Upload' => 'Carga',
+	'Failed' => 'Fracasado',
+	'Upload a file' => 'Examinar...',
+	'Drop files here to upload' => 'Arrastrar ficheros aquí para enviar',
+	'Upload not finished' => 'La carga no está terminado',
+	'from' => 'de',
+	'Kb' => 'Ko',
+	'Mb' => 'Mo',
+	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} tiene una extensión no válida. Sólo {extensions} de formatos están permitidos.',
+	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} es demasiado pesado. El tamaño máximo es {sizeLimit}.',
+	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} es demasiado pequeño. El tamaño mínimo es de {minSizeLimit}.',
+	'{file} is empty, please select files again without it.' => '{file} está vacía. Por favor, seleccione un fichero que no está vacío.',
+	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Los ficheros se están transfiriendo. Si sale de la página, se cancelará el envío.',
+	'No file was uploaded' => 'No existe el fichero fue subido',
+	'The file is empty.' => 'El fichero está vacío.',
+	'The file size is too large.' => 'El tamaño del fichero es mayor que el límite permitido.',
+	'The file has invalid extension (allowed extensions:' => 'La extensión de fichero no es válido (extensiones permitidas:',
+	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'El fichero no se ha enviado. El envío ha sido cancelada o se produjo un error en el servidor.',
+	'Server error. The upload destination folder isn\'t writable.' => 'Error del servidor. La carpeta de destino no es escribible archivos.',
+	'Plugins' => 'Plugins',
+	'plugin installed' => 'plugin instalado',
+	'plugins installed' => 'plugins instalados',
+	'Cannot include another plugins config file.' => 'Imposible incluir otro fichero de configuración de plugins.',
+	'Variable "$PLUGINS" not found.' => 'Variable "$PLUGINS" no se encuentra.',
+	'Install a plugin' => '¿Cómo instalar un plugin?',
+	'Click here' => 'Haga clic aquí',
+	'Create a new plugin' => '¿Cómo crear un plugin?',
+	'Unable to delete the playlist' => 'Imposible borrar el lista',
+	'Player login' => 'Login jugador',
+	'Clean the list' => 'Vaciar la lista',
+	'The list is already empty.' => 'La lista ya está vacía.',
+	'No player' => 'Ningún jugador',
+	'IP address' => 'Dirección IP',
+	'Client' => 'Cliente',
+	'Blacklist' => 'Poner en la lista negra',
+	'Remove from the list' => 'Quitar de la lista',
+	'Select a player' => 'Seleccionar un jugador',
+	'Enter another login' => 'Introduzca otro inicio login',
+	'Add in the' => 'Añadir al',
+	'Playlists' => 'Listas',
+	'Playlist' => 'Lista',
+	'Type' => 'Tipo',
+	'Playlist name' => 'Nombre de la lista',
+	'New playlist' => 'Nueva lista',
+	'players' => 'jugadores',
+	'player' => 'jugador',
+	'No playlist' => 'Ninguna lista',
+	'You are not allowed to configure the servers' => 'Usted no está autorizado a configurar los servidores.',
+	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Ningún servidor está diponible. Para añadir uno, ha de configurar el fichero "config/servers.cfg.php"',
+	'The servers configuration file isn\'t recognized by AdminServ.' => 'El servidor de fichero de configuración no es reconocido por Adminserv.',
+	'This server has been duplicated.' => 'El servidor se ha duplicado.',
+	'Unable to duplicate server.' => 'Imposible duplicado el servidor.',
+	'copy' => 'copia',
+	'Servers list' => 'Lista de servidores',
+	'Address' => 'Dirección',
+	'Port' => 'Puerto',
+	'SuperAdmin level' => 'Nivel SuperAdmin',
+	'User level' => 'Nivel User',
+	'Manage' => 'Gestión',
+	'None' => 'Ningún',
+	'Local network' => 'Red local',
+	'All' => 'Todos',
+	'Removed' => 'Quitar',
+	'Missing' => 'Desaparecido',
+	'No server' => 'Ningún servidor',
+	'servers' => 'servidores',
+	'server' => 'servidor',
+	'Duplicate' => 'Duplicar',
+	'Modify' => 'Modificar',
+	'The "!serverName" server has been deleted.' => 'El servidor "!serverName" se ha borrar.',
+	'This server has been modified.' => 'El servidor ha sido modificado.',
+	'Unable to modify the server.' => 'Imposible modificado el servidor.',
+	'This server has been added.' => 'El servidor ha sido añadido.',
+	'Unable to add the server.' => 'Imposible añadido el servidor.',
+	'Add server' => 'Añadir un servidor',
+	'Edit server' => 'Editar un servidor',
+	'Back' => 'Atrás',
+	'Connection information' => 'Informacióon del conexión',
+	'Server name without color' => 'Nombre del servidor sin color',
+	'IP address or domain name' => 'Dirección IP o nombre de dominio',
+	'XMLRPC port' => 'Puerto XMLRPC',
+	'Port for remote control' => 'Puerto para control remoto',
+	'Optionnal information' => 'Informacióon opcionales',
+	'Server MatchSettings' => 'MatchSettings del servidor',
+	'Current server MatchSettings name' => 'Nombre del MatchSettings actual del servidor',
+	'Possible values for the admin level:' => 'Los valores posibles para los administradores de niveles:',
+	'all => all access' => 'all => accesos lost todos',
+	'local => local network access' => 'local => acceso a la red local',
+	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => acceso a una o más direcciones IP',
+	'none => removed from the access list' => 'none => acceso quitar de la lista',
+	'No server available' => 'Ningún servidor está diponible',
+	'No game mode available' => 'Ningún modo de juego está diponible',
+	'Map end time' => 'Tiempo de fin de mapa',
+	'Round/lap end time' => 'Tiempo de fin de round/lap',
+	'Respawn' => 'Respawn',
+	'Default' => 'Por defecto',
+	'Auto (based on map)' => 'Auto (de acuerdo con el mapa)',
+	'Choose time' => 'Elija el tiempo',
+	'Return to the default value' => 'Revertir y la valor por defecto',
+	'All WarmUp duration' => 'Número de vueltas de calentamiento',
+	'Enable' => 'Activado',
+	'Disable' => 'Desactivado',
+	'Force show of all opponents' => 'Obligar visualización de los adversarios',
+	'Let player choose' => 'Deje la elección al jugador',
+	'All opponents' => 'Todos los adversarios',
+	'minimal opponents' => 'adversarios mínimo',
+	'Choose opponents number' => 'Elija el número de adversarios',
+	'Script name' => 'Nombre del escritura',
+	'Use new rules' => 'El uso de las nuevas normas',
+	'Points limit' => 'Límite de puntos',
+	'Custom points limit' => 'Límite de puntos personalizado',
+	'Force laps' => 'Obligar el vuelta',
+	'Start synchronization period' => 'Tiempo de sincronización de la partida',
+	'Maximal points' => 'Puntos máximos',
+	'Number of laps' => 'Número de vueltas',
+	'Rounds per map' => 'Número de round por mapa',
+	'Number of winners' => 'Número de ganadores',
+	'No player available' => 'Ningún jugador disponible',
+	'New' => 'Nuevo',
+	'Parent folder' => 'Carpeta de origen',
+	'Folder options' => 'Opciones de carpeta',
+	'Do you really want to remove this folder !currentDir?' => '¿Desea realmente borrar este carpeta !currentDir?',
+	'Rename folder' => 'Renombrar un carpeta',
+	'Move folder' => 'Desplazar un carpeta',
+	'Move folder <b>!currentDir</b> in:' => 'Desplazar el carpeta <b>!currentDir</b> en :',
+	'The server is not accessible.' => 'No se puede acceder al servidor.',
+	'You are not allowed at this admin level' => 'No está autorizado en ese nivel de administración.',
+	'The password doesn\'t match to the server.' => 'La contraseña no coincide con el servidor.',
+	'Client not initialized' => 'El cliente no está inicializado',
+	'Unknown command' => 'El comando no es reconocido',
+	'$99FThis round is a draw.' => '$99FSin partida.',
+	'$99FThe $<$00FBlue team$> wins this round.' => '$99FEl $00Fequipo azur gana esta ronda.',
+	'$99FThe $<$F00Red team$> wins this round.' => '$99FEl $F00equipo rojo gana esta ronda.',
+	'maps' => 'mapas',
+	'map' => 'mapa',
+	'No map' => 'Nunguna mapa',
+	'matchsettings' => 'matchsettings',
+	'matchsetting' => 'matchsetting',
+	'No matchsetting' => 'Ningún matchsetting',
+	'text->XML conversion error' => 'Error al convertir el texto->XML',
+	'Saving XML file error' => 'Error guardar el fichero XML',
+	'The folder "logs" is not writable.' => 'La carpeta "logs" no se puede escribir registro.',
+	'The folder "logs" does not exist.' => 'La carpeta "logs" no existe.',
+	'Unable to create log file:' => 'Imposible crear el fichero de registro:',
+	'Unable to add log in file:' => 'Imposible añadir un fichero al registro:',
+	'This server does not exist' => 'Este servidor no existe',
+	'Change password' => 'Cambiar la contraseña',
+	'Current' => 'Actual',
+	'The current password doesn\'t match.' => 'La contraseña actual no coincide.',
+	'The password has been changed.' => 'La contraseña ha sido cambiada.',
+	'Not rated' => 'No clasificado',
+	'Unable to delete server.' => 'Imposible borrar esta servidor.',
+	'Guest-Ban' => 'Invitados-Baneados',
+	'Access as player' => 'Acceder en jugador',
+	'Access as spectator' => 'Acceder en espectador',
+	'Disable horns' => 'Claxones desactivados',
+	'Current vote' => 'Actual voto',
+	'Cancel vote' => 'Cancelar el voto',
+	'Change order' => 'Cambiar el orden',
+	'Servers order' => 'Orden dos servidores',
+	'This path was not required rights:' => 'La ruta de acceso no está obligado derechos:',
+	'needs' => 'necesidades',
+	'Plugin error: script.php or view.php file is missing.' => 'Plugin error: el fichero script.php o view.php esta desaparecido.',
+	'No server admin levels configured.' => 'Ningún nivel de administración configurado para esta servidor.',
+	'Gold time' => 'Tiempo oro',
+	'Cost' => 'Costo',
+	'Team infos' => 'Noticias del equipo',
+	'Script settings' => 'Los parámetros de script',
+	'Script settings updated.' => 'Parámetros actualizados script.',
+	'Change authentication password' => 'Cambiar la contraseña de una cuenta',
+	'You changed the password "!authLevel", remember it at the next connection!' => 'Usted acaba de cambiar la contraseña "!authLevel", piensa en ello en el siguiente inicio de sesión!',
+	'Automatic' => 'Automático',
+	'Choose number' => 'Elija un número',
+	'Client inputs max latency' => 'Max latencia clientes',
+);
+?>
\ No newline at end of file
diff --git a/resources/lang/fr.php b/resources/lang/fr.php
new file mode 100644
index 0000000..9687ca3
--- /dev/null
+++ b/resources/lang/fr.php
@@ -0,0 +1,406 @@
+<?php
+/**
+* French translation
+*
+* @author   Kev717
+* @version  1.4
+*/
+$translate = array(
+	'Access server' => 'Accéder au serveur',
+	'Access relay' => 'Accéder au relai',
+	'Disconnect' => 'Déconnexion',
+	'Servers' => 'Serveurs',
+	'Server' => 'Serveur',
+	'Password' => 'Mot de passe',
+	'Admin level' => 'Niveau admin',
+	'Connection' => 'Connexion',
+	'Please put a password.' => 'Veuillez mettre un mot de passe.',
+	'Connection error' => 'Erreur de connexion',
+	'Connection error: invalid session.' => 'Erreur de connexion : session invalide.',
+	'Servers configuration' => 'Configuration des serveurs',
+	'Online configuration' => 'Configuration en ligne',
+	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'C\'est votre 1ère connexion et aucun serveur n\'est configuré. Choisissez un mot de passe pour configurer vos serveurs.',
+	'Unable to save password.' => 'Impossible d\'enregistrer le mot de passe',
+	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'La configuration en ligne est désactivée. Utilisez le fichier "./config/servers.cfg.php".',
+	'Offline server.' => 'Serveur hors ligne.',
+	'Authentication error.' => 'Erreur d\'authentification.',
+	'Add to favourite' => 'Ajouter aux favoris',
+	'Current map' => 'Map en cours',
+	'Name' => 'Nom',
+	'Author' => 'Auteur',
+	'Environment' => 'Environnement',
+	'Map UId' => 'Map UId',
+	'Game mode' => 'Mode de jeu',
+	'No thumbnail' => 'Pas de miniature',
+	'Server name' => 'Nom du serveur',
+	'Status' => 'Statut',
+	'Server login' => 'Login serveur',
+	'Connected on' => 'Connecté sur',
+	'Dedicated version' => 'Version dédié',
+	'Statistics' => 'Statistiques',
+	'Uptime' => 'Démarré depuis',
+	'Number of connections' => 'Nombre de connexions',
+	'Average connection time' => 'Temps de connexion moyen',
+	'Average number of players' => 'Nombre de joueurs moyen',
+	'Recv net rate' => 'Taux de récéption',
+	'Send net rate' => 'Taux d\'envoi',
+	'Total receiving size' => 'Réception totale',
+	'Total sending size' => 'Emission totale',
+	'Players' => 'Joueurs',
+	'Detailed mode' => 'Mode détail',
+	'Simple mode' => 'Mode simple',
+	'Nickname' => 'Pseudo',
+	'Login' => 'Login',
+	'For the selection' => 'Pour la sélection',
+	'Ban' => 'Bannir',
+	'Kick' => 'Kicker',
+	'Spectator' => 'Spectateur',
+	'Player' => 'Joueur',
+	'Team' => 'Équipe',
+	'Guest' => 'Inviter',
+	'Ignore' => 'Ignorer',
+	'Red team' => 'Équipe rouge',
+	'Blue team' => 'Équipe bleue',
+	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Les scores ont été modifiés : l\'$00féquipe bleue$fff à !scoreTeamBlue et l\'$f00équipe rouge $fffà !scoreTeamRed',
+	'Server options' => 'Options du serveur',
+	'General' => 'Général',
+	'Comment' => 'Commentaire',
+	'Player password' => 'Mot de passe joueur',
+	'Spectator password' => 'Mot de passe spectateur',
+	'Nb max of players' => 'Nb max de joueurs',
+	'Next value' => 'Prochaine valeur',
+	'Nb max of spectators' => 'Nb max de spectateurs',
+	'Advanced' => 'Avancé',
+	'P2P Upload' => 'P2P Upload',
+	'P2P Download' => 'P2P Download',
+	'Ladder mode' => 'Mode ladder',
+	'Vehicles quality' => 'Qualité des véhicules',
+	'Vote expiration' => 'Expiration du vote',
+	'sec' => 'sec', // Second
+	'Vote ratio' => 'Ratio vote',
+	'Hidden server' => 'Serveur caché',
+	'Map download' => 'Téléchargement des maps',
+	'Replays auto save' => 'Sauvegarde auto des replays',
+	'Buddy notification' => 'Notifications des amis',
+	'Save' => 'Enregistrer',
+	'Inactive' => 'Inactif',
+	'Forced' => 'Forcé',
+	'Fast' => 'Rapide',
+	'High' => 'Haute',
+	'Game infos' => 'Infos de jeu',
+	'Game information' => 'Informations de jeu',
+	'Color' => 'Couleur',
+	'Black' => 'Noir',
+	'Red' => 'Rouge',
+	'Green' => 'Vert',
+	'Blue' => 'Bleu',
+	'Orange' => 'Orange',
+	'Pink' => 'Rose',
+	'Purple' => 'Violet',
+	'Grey' => 'Gris',
+	'White' => 'Blanc',
+	'Message destination' => 'Destination du message',
+	'Chat' => 'Chat',
+	'Show server lines' => 'Afficher les lignes du serveur',
+	'Hide server lines' => 'Masquer les lignes du serveur',
+	'Default color: yellow' => 'Couleur par défaut : jaune',
+	'Message' => 'Message',
+	'Destination' => 'Destination',
+	'Send' => 'Envoyer',
+	'Unable to create the folder' => 'Impossible de créer le dossier',
+	'Unable to rename the folder' => 'Impossible de renommer le dossier',
+	'Unable to move the folder' => 'Impossible de déplacer le dossier',
+	'Unable to delete the folder' => 'Impossible de supprimer le dossier',
+	'List' => 'Liste',
+	'Go to the current map' => 'Aller à la map en cours',
+	'Map' => 'Map',
+	'Delete' => 'Supprimer',
+	'Move after the current map' => 'Déplacer après la map en cours',
+	'Unable to rename the map' => 'Impossible de renommer la map',
+	'Unable to move the map' => 'Impossible de déplacer la map',
+	'Unable to delete the map' => 'Impossible de supprimer la map',
+	'Local' => 'Local',
+	'Do you really want to remove this selection?' => 'Voulez-vous vraiment supprimer cette sélection ?',
+	'Move' => 'Déplacer',
+	'Rename' => 'Renommer',
+	'Download' => 'Télécharger',
+	'Insert' => 'Insérer',
+	'Add' => 'Ajouter',
+	'Cancel' => 'Annuler',
+	'Replace the special characters' => 'Remplacer les caractères spéciaux',
+	'in the folder:' => 'dans le dossier :',
+	'Root' => 'Racine',
+	'The map,is currently used by the server.' => 'La map,est actuellement utilisée par le serveur.',
+	'MatchSettings' => 'MatchSettings',
+	'Contains' => 'Contient',
+	'Modified' => 'Modifié le',
+	'Edit' => 'Éditer',
+	'Load' => 'Charger',
+	'Save ' => 'Sauvegarder',
+	'Create' => 'Créer',
+	'Unable to save the MatchSettings' => 'Impossible d\'enregistrer le MatchSettings',
+	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'Le MatchSettings "!matchSettingName" a bien été créé dans le dossier',
+	'a MatchSettings' => 'un MatchSettings',
+	'Create a MatchSettings' => 'Créer un MatchSettings',
+	'MatchSettings name' => 'Nom du MatchSettings',
+	'Maps' => 'Maps',
+	'Make selection' => 'Faire une sélection',
+	'Import all folder' => 'Importer tout le dossier',
+	'Select' => 'Sélectionner',
+	'MatchSettings selected maps:' => 'Maps sélectionnées pour le MatchSettings :',
+	'View the MatchSettings selection' => 'Voir la sélection du MatchSettings',
+	'MatchSettings selection' => 'Sélection du MatchSettings',
+	'Remove map from the selection' => 'Enlever cette map de la sélection',
+	'Close' => 'Fermer',
+	'HotSeat' => 'HotSeat',
+	'Time limit' => 'Limite de temps',
+	'Rounds count' => 'Nombre de rounds',
+	'Filter' => 'Filtres',
+	'Lan' => 'Lan',
+	'Internet' => 'Internet',
+	'Solo' => 'Solo',
+	'Sort index' => 'Index de tri',
+	'Random map order' => 'Ordre des maps aléatoire',
+	'Default game mode' => 'Mode de jeu par défaut',
+	'No map selected for the MatchSettings.' => 'Aucune map sélectionnée pour le MatchSettings.',
+	'The MatchSettings name already exist! It will be overwritten.' => 'Le nom du MatchSettings existe déjà ! Il sera écrasé.',
+	'Order' => 'Ordonner',
+	'Automatic sort' => 'Tri automatique',
+	'Random' => 'Aléatoire',
+	'Manual sort' => 'Tri manuel',
+	'Save the current MatchSettings' => 'Sauvegarder le MatchSettings courant',
+	'Reset' => 'Réinitialiser',
+	'Transfer mode' => 'Mode de transfert',
+	'at the end of list' => 'à la fin de la liste',
+	'after current map' => 'après la map en cours',
+	'only in the folder' => 'dans le dossier seulement',
+	'Options' => 'Options',
+	'Go to the maps list when upload is complete' => 'Aller à la liste des maps une fois l\'upload terminé',
+	'Upload' => 'Upload',
+	'Failed' => 'Échoué',
+	'Upload a file' => 'Parcourir...',
+	'Drop files here to upload' => 'Glissez les fichiers ici pour envoyer',
+	'Upload not finished' => 'L\'upload n\'est pas terminé',
+	'from' => 'de',
+	'Kb' => 'Ko',
+	'Mb' => 'Mo',
+	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} a une extension invalide. Seulement les formats {extensions} sont autorisés.',
+	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} est trop lourd. La taille maximale est de {sizeLimit}.',
+	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} est trop petit. La taille minimale est de {minSizeLimit}.',
+	'{file} is empty, please select files again without it.' => '{file} est vide. Veuillez sélectionner un fichier qui n\'est pas vide.',
+	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Les fichiers sont en cours de transfert. Si vous quittez la page, l\'envoi sera annulé.',
+	'No file was uploaded' => 'Aucun fichier n\'a été uploadé',
+	'The file is empty.' => 'Le fichier est vide.',
+	'The file size is too large.' => 'La taille du fichier est supérieure à la limite autorisé.',
+	'The file has invalid extension (allowed extensions:' => 'L\'extension du fichier est invalide (extensions autorisées :',
+	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Le fichier n\'a pas été envoyé. L\'envoi a été annulé ou une erreur du serveur est survenue.',
+	'Server error. The upload destination folder isn\'t writable.' => 'Erreur du serveur. Le dossier de destination des uploads n\'est pas écrivable.',
+	'Plugins' => 'Plugins',
+	'plugin installed' => 'plugin installé',
+	'plugins installed' => 'plugins installés',
+	'Cannot include another plugins config file.' => 'Impossible d\'inclure un autre fichier de config pour les plugins.',
+	'Variable "$PLUGINS" not found.' => 'Variable "$PLUGINS" non trouvée.',
+	'Plugins are extensions to add features to Adminserv.' => 'Les plugins sont des extensions permettant d\'ajouter des fonctionnalités pour AdminServ.',
+	'Install a plugin' => 'Comment installer un plugin ?',
+	'See all plugins:' => 'Voir tous les plugins :',
+	'Click here' => 'Cliquez-ici',
+	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Dézippez le plugin et placez son contenu dans le dossier &laquo; plugins &raquo; d\'AdminServ.',
+	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'Dans la configuration Extension, ajoutez le nom du dossier du plugin précédement ajouté.',
+	'Create a new plugin' => 'Comment créer son plugin ?',
+	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values ​​in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>Pour créer son plugin, allez dans le dossier plugins et dupliquez le dossier _newplugin. Remplacez les valeurs dans le fichier config.ini ainsi que le nom du dossier.<br />Il y a ensuite 2 fichiers PHP :</p><ul><li>script.php : ce fichier est exécuté avant le header du site. C\'est là que tout le script du plugin sera placé.</li><li>view.php : ce fichier est l\'affichage du plugin exécuté après le header. C\'est là que sera placé tout le code html.</li></ul><p>A vous de créer les ressources (classes, js, css) puis de les inclure dans ces fichiers.</p>',
+	'Unable to delete the playlist' => 'Impossible de supprimer la playlist',
+	'Player login' => 'Login joueur',
+	'Clean the list' => 'Vider la liste',
+	'The list is already empty.' => 'La liste est déjà vide.',
+	'No player' => 'Aucun joueur',
+	'IP address' => 'Adresse IP',
+	'Client' => 'Client',
+	'Blacklist' => 'Blacklister',
+	'Remove from the list' => 'Retirer de la liste',
+	'Select a player' => 'Sélectionnez un joueur',
+	'Enter another login' => 'Entrez un autre login',
+	'Add in the' => 'Ajouter à la',
+	'Playlists' => 'Playlists',
+	'Playlist' => 'Playlist',
+	'Type' => 'Type',
+	'Playlist name' => 'Nom de la playlist',
+	'New playlist' => 'Nouvelle playlist',
+	'players' => 'joueurs',
+	'player' => 'joueur',
+	'No playlist' => 'Aucune playlist',
+	'You are not allowed to configure the servers' => 'Vous n\'êtes pas autorisé à configurer les serveurs.',
+	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Aucun serveur n\'est disponible. Pour en ajouter un, il faut configurer le fichier "config/servers.cfg.php"',
+	'The servers configuration file isn\'t recognized by AdminServ.' => 'Le fichier de configuration des serveurs n\'est pas reconnu par AdminServ.',
+	'This server has been duplicated.' => 'Le serveur a bien été dupliqué.',
+	'Unable to duplicate server.' => 'Impossible de dupliquer le serveur.',
+	'copy' => 'copie',
+	'Servers list' => 'Liste des serveurs',
+	'Address' => 'Adresse',
+	'Port' => 'Port',
+	'SuperAdmin level' => 'Niveau SuperAdmin',
+	'User level' => 'Niveau User',
+	'Manage' => 'Gestion',
+	'None' => 'Aucun',
+	'Local network' => 'Réseau local',
+	'All' => 'Tous',
+	'Removed' => 'Enlevé',
+	'Missing' => 'Manquant',
+	'No server' => 'Aucun serveur',
+	'servers' => 'serveurs',
+	'server' => 'serveur',
+	'Duplicate' => 'Dupliquer',
+	'Modify' => 'Modifier',
+	'The "!serverName" server has been deleted.' => 'Le serveur "!serverName" a été supprimé.',
+	'This server has been modified.' => 'Le serveur a bien été modifié.',
+	'Unable to modify the server.' => 'Impossible de modifier le serveur.',
+	'This server has been added.' => 'Le serveur a bien été ajouté.',
+	'Unable to add the server.' => 'Impossible d\'ajouter le serveur.',
+	'Add server' => 'Ajouter un serveur',
+	'Edit server' => 'Éditer un serveur',
+	'Back' => 'Retour',
+	'Connection information' => 'Informations de connexion',
+	'Server name without color' => 'Nom du serveur sans couleur',
+	'IP address or domain name' => 'Adresse IP ou nom de domaine',
+	'XMLRPC port' => 'Port XMLRPC',
+	'Port for remote control' => 'Port permettant le contrôle à distance',
+	'Optionnal information' => 'Informations optionnelles',
+	'Server MatchSettings' => 'MatchSettings du serveur',
+	'Current server MatchSettings name' => 'Nom du MatchSettings courant du serveur',
+	'Possible values for the admin level:' => 'Valeurs possibles pour les niveaux admins :',
+	'all => all access' => 'all => accès à tous',
+	'local => local network access' => 'local => accès au réseau local',
+	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => accès à une ou plusieurs adresses IP',
+	'none => removed from the access list' => 'none => accès enlevé de la liste',
+	'No server available' => 'Aucun serveur disponible',
+	'No game mode available' => 'Aucun mode de jeu disponible',
+	'Map end time' => 'Temps de fin de map',
+	'Round/lap end time' => 'Temps de fin de round/lap',
+	'Respawn' => 'Respawn',
+	'Default' => 'Par défaut',
+	'Auto (based on map)' => 'Auto (en fonction de la map)',
+	'Choose time' => 'Choisir le temps',
+	'Return to the default value' => 'Revenir à la valeur par défaut',
+	'All WarmUp duration' => 'Nombre de WarmUp',
+	'Enable' => 'Activé',
+	'Disable' => 'Désactivé',
+	'Force show of all opponents' => 'Forcer l\'affichage des adversaires',
+	'Let player choose' => 'Laisser le choix au joueur',
+	'All opponents' => 'Tous les adversaires',
+	'minimal opponents' => 'adversaires minimum',
+	'Choose opponents number' => 'Choisir le nombre d\'adversaires',
+	'Script name' => 'Nom du script',
+	'Use new rules' => 'Utiliser les nouvelles règles',
+	'Points limit' => 'Limite de points',
+	'Custom points limit' => 'Limite de points personnalisée',
+	'Force laps' => 'Forcer le tour',
+	'Start synchronization period' => 'Temps de synchronisation du départ',
+	'Maximal points' => 'Points maximum',
+	'Number of laps' => 'Nombre de tours',
+	'Rounds per map' => 'Nombre de round par map',
+	'Number of winners' => 'Nombre de vainqueurs',
+	'No player available' => 'Aucun joueur disponible',
+	'New' => 'Nouveau',
+	'Parent folder' => 'Dossier parent',
+	'Folder options' => 'Options du dossier',
+	'Do you really want to remove this folder !currentDir?' => 'Voulez-vous vraiment supprimer le dossier !currentDir ?',
+	'Rename folder' => 'Renommer un dossier',
+	'Move folder' => 'Déplacer un dossier',
+	'Move folder <b>!currentDir</b> in:' => 'Déplacer le dossier <b>!currentDir</b> dans :',
+	'The server is not accessible.' => 'Le serveur n\'est pas accessible.',
+	'You are not allowed at this admin level' => 'Vous n\'êtes pas autorisé dans ce niveau admin.',
+	'The password doesn\'t match to the server.' => 'Le mot de passe ne correspond pas au serveur.',
+	'Client not initialized' => 'Le client n\'est pas initialisé',
+	'Unknown command' => 'La commande n\'est pas reconnue',
+	'$99FThis round is a draw.' => '$99FMatch nul.',
+	'$99FThe $<$00FBlue team$> wins this round.' => '$99FL\'$00Féquipe bleue remporte ce tour.',
+	'$99FThe $<$F00Red team$> wins this round.' => '$99FL\'$F00équipe rouge remporte ce tour.',
+	'maps' => 'maps',
+	'map' => 'map',
+	'No map' => 'Aucune map',
+	'matchsettings' => 'matchsettings',
+	'matchsetting' => 'matchsetting',
+	'No matchsetting' => 'Aucun matchsetting',
+	'text->XML conversion error' => 'Erreur de conversion texte->XML',
+	'Saving XML file error' => 'Erreur d\'entregistrement du fichier XML',
+	'The folder "logs" is not writable.' => 'Le dossier "logs" ne permet pas l\'écriture de log.',
+	'The folder "logs" does not exist.' => 'Le dossier "logs" n\'existe pas.',
+	'Unable to create log file:' => 'Impossible de créer le fichier de log :',
+	'Unable to add log in file:' => 'Impossible d\'ajouter un log au fichier :',
+	'This server does not exist' => 'Ce serveur n\'existe pas',
+	'Change password' => 'Changer le mot de passe',
+	'Current' => 'Actuel',
+	'The current password doesn\'t match.' => 'Le mot de passe actuel ne correspond pas.',
+	'The password has been changed.' => 'Le mot de passe a bien été changé.',
+	'Not rated' => 'Non classé',
+	'Unable to delete server.' => 'Impossible de supprimer ce serveur',
+	'Guest-Ban' => 'Invités-Bannis',
+	'Access as player' => 'Accéder en joueur',
+	'Access as spectator' => 'Accéder en spectateur',
+	'Disable horns' => 'Désactiver les klaxons',
+	'Current vote' => 'Vote en cours',
+	'Cancel vote' => 'Annuler le vote',
+	'Change order' => 'Changer l\'ordre',
+	'Servers order' => 'Ordre des serveurs',
+	'This path was not required rights:' => 'Le chemin suivant n\'a pas les droits requis :',
+	'needs' => 'a besoin de',
+	'Plugin error: script.php or view.php file is missing.' => 'Erreur de plugin : le fichier script.php ou view.php est manquant.',
+	'No server admin levels configured.' => 'Aucun niveau admin configuré pour ce serveur.',
+	'Gold time' => 'Temps or',
+	'Cost' => 'Coût',
+	'Team infos' => 'Infos sur les équipes',
+	'Script settings' => 'Paramètres de script',
+	'Script settings updated.' => 'Paramètres de script mis à jour.',
+	'Change authentication password' => 'Changer le mot de passe d\'un compte',
+	'You changed the password "!authLevel", remember it at the next connection!' => 'Vous venez de changer le mot de passe "!authLevel", pensez-y à la prochaine connexion !',
+	'Automatic' => 'Automatique',
+	'Choose number' => 'Choisir un nombre',
+	'Client inputs max latency' => 'Latence max des clients',
+	'Script info' => 'Informations',
+	'Compatible map types' => 'Types de map compatibles',
+	'Script parameters' => 'Paramètres',
+	'Value' => 'Valeur',
+	'The server already exist! Change the name.' => 'Le serveur existe déjà ! Changez le nom.',
+	'Version' => 'Version',
+	'Disable vote ratio' => 'Désactiver le ratio vote',
+	'Manage server options' => 'Gérer les options du serveur',
+	'Import' => 'Importer',
+	'Export' => 'Exporter',
+	'No export available' => 'Pas d\'export disponible',
+	'No such file or file is not readable' => 'Le fichier n\'existe pas ou n\'est pas lisible',
+	'Server options are exported in' => 'Les options du serveur sont exportées dans',
+	'Unable to export server options' => 'Impossible d\'exporter les options du serveur',
+	'Maps base folder' => 'Dossier de base pour les maps',
+	'Default path from maps folder for listing maps' => 'Chemin par défaut à partir du dossier "Maps" pour lister les maps',
+	'No folder' => 'Aucun dossier',
+	'Server selection' => 'Sélection du serveur',
+	'Configuration' => 'Configuration',
+	'Force the scores' => 'Forcer les scores',
+	'Folders' => 'Dossiers',
+	'Admin levels' => 'Niveaux d\'admin',
+	'admin levels' => 'niveaux d\'admin',
+	'Admin levels list' => 'Liste des niveaux d\'admin',
+	'Access' => 'Accès',
+	'Permissions' => 'Permissions',
+	'authorized access' => 'accès autorisés',
+	'authorized permissions' => 'permissions autorisées',
+	'Add level' => 'Ajouter un niveau',
+	'Edit level' => 'Éditer un niveau',
+	'Level name' => 'Nom du niveau',
+	'Level type' => 'Type de niveau',
+	'Add access' => 'Ajouter un accès',
+	'All access' => 'Tous les accès',
+	'Selected access' => 'Accès sélectionnés',
+	'Add permission' => 'Ajouter une permission',
+	'All permissions' => 'Toutes les permissions',
+	'Selected permissions' => 'Permissions sélectionnées',
+	'Levels order' => 'Ordre des niveaux',
+	'This admin level has been duplicated.' => 'Le niveau admin a bien été dupliqué.',
+	'Unable to duplicate admin level.' => 'Impossible de dupliquer le niveau admin.',
+	'The "!levelName" admin level has been deleted.' => 'Le niveau admin "!levelName" a été supprimé.',
+	'Unable to delete admin level.' => 'Impossible de supprimer le niveau admin.',
+	'This admin level has been modified.' => 'Le niveau admin a bien été modifié.',
+	'Unable to modify the admin level.' => 'Impossible de modifier le niveau admin.',
+	'This admin level has been added.' => 'Le niveau admin a bien été ajouté.',
+	'Unable to add the admin level.' => 'Impossible d\'ajouter le niveau admin.',
+);
+?>
\ No newline at end of file
diff --git a/resources/lang/nl.php b/resources/lang/nl.php
new file mode 100644
index 0000000..c800a86
--- /dev/null
+++ b/resources/lang/nl.php
@@ -0,0 +1,364 @@
+<?php
+/**
+* Dutch translation
+*
+* @author   Weerwolf
+* @version  1.0
+*/
+$translate = array(
+	'Access server' => 'Toegang Server',
+	'Access relay' => 'Toegang Relay',
+	'Disconnect' => 'Verbinding Verbreken',
+	'Servers' => 'Servers',
+	'Server' => 'Server',
+	'Password' => 'Wachtwoord',
+	'Admin level' => 'Admin Level',
+	'Connection' => 'Verbinding',
+	'Please put a password.' => 'Wachtwoord Invoeren',
+	'Connection error' => 'Verbindingsfout',
+	'Connection error: invalid session.' => 'Verbindingsfout: Ongeldige Sessie',
+	'Servers configuration' => 'Server Configuratie',
+	'Online configuration' => 'Online Configuratie',
+	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'Dit is je 1e verbinding en er zijn geen servers geconfigureerd. Kies een wachtwoord om server te gaan configureren',
+	'Unable to save password.' => 'Wachtwoord kan niet opgeslagen worden.',
+	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Online configuratie is uitgeschakeld. Gebruik "./config/servers.cfg.php" om servers te configureren.',
+	'Offline server.' => 'Server Offline.',
+	'Authentication error.' => 'Aanmeldingsfout.',
+	'Add to favourite' => 'Aan favorieten Toevoegen',
+	'Current map' => 'Huidige Map',
+	'Name' => 'Naam',
+	'Author' => 'Auteur',
+	'Environment' => 'Omgeving',
+	'Map UId' => 'Map UId',
+	'Game mode' => 'Spel Mode',
+	'No thumbnail' => 'Geen Voorbeeld',
+	'Server name' => 'Server Naam',
+	'Status' => 'Status',
+	'Server login' => 'Server Login',
+	'Connected on' => 'Verbonden met',
+	'Dedicated version' => 'Server Versie',
+	'Statistics' => 'Statestieken',
+	'Uptime' => 'Tijd Online',
+	'Number of connections' => 'Aantal verbindingen',
+	'Average connection time' => 'Gemiddelde Tijd Verbinding',
+	'Average number of players' => 'Gemiddeld aantal Spelers',
+	'Recv net rate' => 'Downloadsnelheid',
+	'Send net rate' => 'Uploadsnelheid',
+	'Total receiving size' => 'Totaal Ontvangen',
+	'Total sending size' => 'Totaal Verzonden',
+	'Players' => 'Spelers',
+	'Detailed mode' => 'Detail Weergave',
+	'Simple mode' => 'Eenvoudige Weergave',
+	'Nickname' => 'Schuilnaam',
+	'Login' => 'Login',
+	'For the selection' => 'Voor De Selectie',
+	'Ban' => 'Uitsluiten',
+	'Kick' => 'Verwijderen',
+	'Spectator' => 'Toeschouwer',
+	'Player' => 'Speler',
+	'Team' => 'Team',
+	'Guest' => 'Gast',
+	'Ignore' => 'Negeren',
+	'Red team' => 'Rode Team',
+	'Blue team' => 'Blauwe Team',
+	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Ergebnisse wurden geändert : Les scores ont été modifiés : $00fblaue Team$fff hat !scoreTeamBlue und l\'$f00rote Team $fffhat !scoreTeamRed',
+	'Server options' => 'Server Opties',
+	'General' => 'Algemeen',
+	'Comment' => 'Commentaar',
+	'Player password' => 'Speler Wachtwoord',
+	'Spectator password' => 'Toeschouwer Wachtwoord',
+	'Nb max of players' => 'Max Aantal Spelers',
+	'Next value' => 'Volgende Waarde',
+	'Nb max of spectators' => 'Max Aantal Toeschouwers',
+	'Advanced' => 'Geavanceerd',
+	'P2P Upload' => 'P2P Upload',
+	'P2P Download' => 'P2P Download',
+	'Ladder mode' => 'Ladder Mode',
+	'Vehicles quality' => 'Voertuig Kwaliteit',
+	'Vote expiration' => 'Stemtijd',
+	'sec' => 'seconden', // Second
+	'Vote ratio' => 'Stem Percentage',
+	'Hidden server' => 'Verborgen Server',
+	'Map download' => 'Maps Downloaden',
+	'Replays auto save' => 'Automatisch herhalingen opslaan',
+	'Buddy notification' => 'Notificatie Vrienden',
+	'Save' => 'Opslaan',
+	'Inactive' => 'Inactief',
+	'Forced' => 'Geforceerd',
+	'Fast' => 'Snel',
+	'High' => 'Hoog',
+	'Game infos' => 'Spelinformatie',
+	'Game information' => 'Spelnformatie',
+	'Color' => 'Kleur',
+	'Black' => 'Zwart',
+	'Red' => 'Rood',
+	'Green' => 'Groen',
+	'Blue' => 'Blauw',
+	'Orange' => 'Oranje',
+	'Pink' => 'Roze',
+	'Purple' => 'Paars',
+	'Grey' => 'Grijs',
+	'White' => 'Wit',
+	'Message destination' => 'Bestemming bericht',
+	'Chat' => 'Chat',
+	'Show server lines' => 'Regels Server Tonen',
+	'Hide server lines' => 'Regels Server Verbergen',
+	'Default color: yellow' => 'Standaard Kleur: Geel',
+	'Message' => 'Bericht',
+	'Destination' => 'Bestemming',
+	'Send' => 'Versturen',
+	'Unable to create the folder' => 'Aanmaken Directory Mislukt',
+	'Unable to rename the folder' => 'Hernoemen Directory Mislukt',
+	'Unable to move the folder' => 'Verplaatsen Directory Mislukt',
+	'Unable to delete the folder' => 'Verwijderen Directory Mislukt',
+	'List' => 'Lijst',
+	'Go to the current map' => 'Ga Naar De Huidige Map',
+	'Map' => 'Map',
+	'Delete' => 'Verwijderen',
+	'Move after the current map' => 'Plaats Achter De Huidige Map',
+	'Unable to rename the map' => 'De Map Kon Niet Worden Hernoemd',
+	'Unable to move the map' => 'De Map Kon Niet Worden Verplaatst',
+	'Unable to delete the map' => 'De Map Kon Niet Worden Verwijderd',
+	'Local' => 'Lokaal',
+	'Do you really want to remove this selection?' => 'Wil Je Echt De Huidige Selectie Verwijderen',
+	'Move' => 'Verplaatsen',
+	'Rename' => 'Hernoemen',
+	'Download' => 'Downloaden',
+	'Insert' => 'Invoegen',
+	'Add' => 'Toevoegen',
+	'Cancel' => 'Afbreken',
+	'Replace the special characters' => 'Vervang de speciale tekens',
+	'in the folder:' => 'In De Directory:',
+	'Root' => 'Root',
+	'The map,is currently used by the server.' => 'Deze map wordt op dit moment door de server gebruikt.',
+	'MatchSettings' => 'MatchSettings',
+	'Contains' => 'Bevat',
+	'Modified' => 'Aangepast',
+	'Edit' => 'Aanpassen',
+	'Load' => 'Laden',
+	'Save ' => 'Opslaan',
+	'Create' => 'Aanmaken',
+	'Unable to save the MatchSettings' => 'Oplsaan MatchSettings Mislukt',
+	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'MatchSettings "!matchSettingName" Aanmaken In De Directory Geslaagd',
+	'a MatchSettings' => 'MatchSettings',
+	'Create a MatchSettings' => 'MatchSettings Aanmaken',
+	'MatchSettings name' => 'Naam MatchSettings',
+	'Maps' => 'Maps',
+	'Make selection' => 'Maak Een Selectie',
+	'Import all folder' => 'Importeer Hele Dirtectory',
+	'Select' => 'Selecteren',
+	'MatchSettings selected maps:' => 'MatchSettings Geslecteerde Maps:',
+	'View the MatchSettings selection' => 'MatchSettings Gekozen Selectie Bekijken',
+	'MatchSettings selection' => 'MatchSettings Selectie',
+	'Remove map from the selection' => 'Map Uit De Selectie Verwijderen',
+	'Close' => 'Sluiten',
+	'HotSeat' => 'HotSeat',
+	'Time limit' => 'Tijdlimiet',
+	'Rounds count' => 'Aantal Ronden',
+	'Filter' => 'Filter',
+	'Lan' => 'Lan',
+	'Internet' => 'Internet',
+	'Solo' => 'Solo',
+	'Sort index' => 'Sortering Index',
+	'Random map order' => 'Willekeurig Map Volgorde',
+	'Default game mode' => 'Standaard Spel Mode',
+	'No map selected for the MatchSettings.' => 'Geen Map voor de MatchSettings Geselecteerd.',
+	'The MatchSettings name already exists! It will be overwritten.' => 'De Naam Voor Deze MatchSettings Bestaat Al, En Zal Worden Overschreven.',
+	'Order' => 'Rangschikken',
+	'Automatic sort' => 'Automatisch Sorteren',
+	'Random' => 'Willekeurig',
+	'Manual sort' => 'Handmatig Sorteren',
+	'Save the current MatchSettings' => 'De Huidige MatchSettings Opslaan',
+	'Reset' => 'Resetten',
+	'Transfer mode' => 'Overdrachtsmode',
+	'at the end of list' => 'Aan Het Einde Van de Lijst',
+	'after current map' => 'Achter De Huidige Map',
+	'only in the folder' => 'Alleen In De Directory',
+	'Options' => 'Opties',
+	'Go to the maps list when upload is complete' => 'Ga Naar De Maplijst Als De Upload Klaar Is',
+	'Upload' => 'Upload',
+	'Failed' => 'Mislukt',
+	'Upload a file' => 'Bestand Uploaden',
+	'Drop files here to upload' => 'Sleep Bestanden Hier Om Te Uploaden',
+	'Upload not finished' => 'Uploaden Nog Niet Klaar',
+	'from' => 'Van',
+	'Kb' => 'Kb',
+	'Mb' => 'Mb',
+	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} Heeft Een Ongeldig Bestandsformaat. Toegestane Formaten Zijn: {extensions}.',
+	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} Is te Groot. De Maximale Groote is: {sizeLimit}.',
+	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} Is Te Klein. De Minimale Grootte is: {minSizeLimit}.',
+	'{file} is empty, please select files again without it.' => '{file} Is Leeg. Selecteer Nogmaals.',
+	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'De Bestanden Worden Geupload. Als Je Nu Het Scherm Sluit, Wordt De Upload Afgebroken.',
+	'No file was uploaded' => 'Er Zijn Geen Bestanden Geupload',
+	'The file is empty.' => 'Het Bestand Is Leeg.',
+	'The file size is too large.' => 'Het Bestand Is Te Groot.',
+	'The file has invalid extension (allowed extensions:' => 'Het Bestand Heeft Een Ongeldig Formaat (Toegestane Formaten zijn:',
+	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Het Bestand Is Niet Geupload. De upload Is AfgebrokenOf Er Is Een Serverfout Opgetreden.',
+	'Server error. The upload destination folder isn\'t writable.' => 'Serverfout. De Doeldirectory Is Niet Schrijfbaar.',
+	'Plugins' => 'Invoegtoepassingen',
+	'plugin installed' => 'Invoegtoepassing Geinstalleerd',
+	'plugins installed' => 'Invoegtoepassingen Geinstalleerd',
+	'Cannot include another plugins config file.' => 'Er kunnen geen Invoegtoepassing Configuratiebestanden Ingesloten Worden.',
+	'Variable "$PLUGINS" not found.' => 'Variabele "$PLUGINS" Niet Gevonden.',
+	'Plugins are extensions to add features to Adminserv.' => 'Invoegtoepassingen zijn Extenties die Functionaliteit aan AdminServ Toevoegen.',
+	'Install a plugin' => 'Invoegtoepassing Installeren',
+	'See all plugins:' => 'Bekijk Alle Invoegtoepassingen:',
+	'Click here' => 'Klik Hier',
+	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Entpacken sie das Plugin und verschieben Sie den Inhalt in den &laquo; plugins &raquo; Ordner von AdminServ.',
+	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'Fügen Sie den Namen des Plugin Ordners in der Konfiguratiosdatei der Erweiterungen ein(extension.cfg.php).',
+	'Create a new plugin' => 'Nieuwe Invoegtoepassing Aanmaken',
+	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>Um ein Plugin zu erstellen, gehe in de Plugin Orner und kopiere den Ordner _newplugin. Ersetze die Werte in der config.ini Datei und bennene den Order um.<br />Dort befinden sich zwei PHP Dateien:</p><ul><li>script.php : Diese Datei wird vor dem Header der Seite ausgeführt. Hier werden alle Plugin Scripte plaziert.</li><li>view.php : Diese Datei ist für die Anzeige des Plugins verantworlich und wird nach dem Header der seite ausgeführt. Hier wird der ganze HTML Code plaziert.</li></ul><p>Die benötigten Recourcen (classes, js, css) können Sie in die Dateien einbinden.</p>',
+	'Unable to delete the playlist' => 'Kan De Speellijst Niet Wissen',
+	'Player login' => 'Speler Login',
+	'Clean the list' => 'Lijst Legen',
+	'The list is already empty.' => 'De Lijst Is Al Leeg.',
+	'No player' => 'Geen Speler(s) Op De Server',
+	'IP address' => 'IP Adres',
+	'Client' => 'Client',
+	'Blacklist' => 'Zwarte Lijst',
+	'Remove from the list' => 'Verwijder Van De Lijst',
+	'Select a player' => 'Selecteer Een Speler',
+	'Enter another login' => 'Voer Een Andere Login In',
+	'Add in the' => 'Voeg Toe Aan',
+	'Playlists' => 'Speellijsten',
+	'Playlist' => 'Speellijst',
+	'Type' => 'Type',
+	'Playlist name' => 'Naam Speellijst',
+	'New playlist' => 'Nieuwe Speellijst',
+	'players' => 'Spelers',
+	'player' => 'Speler',
+	'No playlist' => 'Geen Speellijst',
+	'You are not allowed to configure the servers' => 'Je Bent Niet Bevoegd Om Servers Te Configureren.',
+	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Geen Server Beschikbaar. Om Servers Toe Te Voegen, Configureer "config/servers.cfg.php"',
+	'The servers configuration file isn\'t recognized by AdminServ.' => 'Het Server Configuratiebestand Wordt Niet Door AdminServ Herkend.',
+	'This server has been duplicated.' => 'Deze Server Is Met Succes Gedupliceerd.',
+	'Unable to duplicate server.' => 'Kan De Server Niet Dupliceren.',
+	'copy' => 'Kopie',
+	'Servers list' => 'Serverlijst',
+	'Address' => 'Adres',
+	'Port' => 'Poort',
+	'SuperAdmin level' => 'SuperAdmin Rang',
+	'User level' => 'Gebruiker Rang',
+	'Manage' => 'Beheren',
+	'None' => 'Geen',
+	'Local network' => 'Lokaal Netwerk',
+	'All' => 'Alle',
+	'Removed' => 'Verwijderd',
+	'Missing' => 'Ontbreekt',
+	'No server' => 'Geen Server',
+	'servers' => 'Servers',
+	'server' => 'Server',
+	'Duplicate' => 'Dupliceer',
+	'Modify' => 'Wijzig',
+	'The "!serverName" server has been deleted.' => 'De server "!serverName" Werd Verwijderd.',
+	'This server has been modified.' => 'Deze Server werd Aangepast.',
+	'Unable to modify the server.' => 'Kan De Server Niet Aanpassen.',
+	'This server has been added.' => 'Deze Server Is Met Succes Toegevoegd.',
+	'Unable to add the server.' => 'Kan De Server Niet Toevoegen.',
+	'Add server' => 'Server Toevoegen',
+	'Edit server' => 'Server Aanpassen',
+	'Back' => 'Terug',
+	'Connection information' => 'Informatie Verbinding',
+	'Server name without color' => 'Servernaam Zonder Kleur',
+	'IP address or domain name' => 'IP Adres of Domeinnaam',
+	'XMLRPC port' => 'XMLRPC Poort',
+	'Port for remote control' => 'Poort voor Externe Toegang',
+	'Optionnal information' => 'Optionele Informatie',
+	'Server MatchSettings' => 'Server MatchSettings',
+	'Current server MatchSettings name' => 'Server\'s huidige MatchSettings Naam',
+	'Possible values for the admin level:' => 'Mogelijke Waarden voor de Admin rang:',
+	'all => all access' => 'all => Alle toegang',
+	'local => local network access' => 'local => Lokaal Netwerk Toegang',
+	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => Toegang Vanaf 1 of meerdere IP Adressen',
+	'none => removed from the access list' => 'none => Uit de Toegangslijst Verwijderd',
+	'No server available' => 'Geen Server(s) Beschikbaar',
+	'No game mode available' => 'Geen Speelmode Beschikbaar',
+	'Map end time' => 'Map Einde Tijd',
+	'Round/lap end time' => 'Ronde Einde Tijd',
+	'Respawn' => 'Respawn',
+	'Default' => 'Standaard',
+	'Auto (based on map)' => 'Automatisch (Afhankelijk Van De Map)',
+	'Choose time' => 'Tijd Selecteren',
+	'Return to the default value' => 'Terug Naar De Standaard Waarde',
+	'All WarmUp duration' => 'Tijd Voor Opwarming',
+	'Enable' => 'Activieren',
+	'Disable' => 'Deactivieren',
+	'Force show of all opponents' => 'Forceer Alle Spelers Zichtbaar',
+	'Let player choose' => 'Laat De Speler Kiezen',
+	'All opponents' => 'Alle Tegenstanders',
+	'minimal opponents' => 'Minimale Tegenstanders',
+	'Choose opponents number' => 'Kies Aantal Tegenstanders',
+	'Script name' => 'Script Naam',
+	'Use new rules' => 'Nieuwe Regels Gebruiken',
+	'Points limit' => 'Puntenlimiet',
+	'Custom points limit' => 'Aangepaste Puntenlimiet',
+	'Force laps' => 'Forceer Ronden',
+	'Start synchronization period' => 'Synchronisatietijd Bij Start',
+	'Maximal points' => 'Maximaal Aantal Punten',
+	'Number of laps' => 'Aantal Ronden',
+	'Rounds per map' => 'Ronden Per Map',
+	'Number of winners' => 'Gewinner Nummer',
+	'No player available' => 'Geen Speler Beschikbaar',
+	'New' => 'Nieuw',
+	'Parent folder' => 'Huidige Directory',
+	'Folder options' => 'Directory Opties',
+	'Do you really want to remove this folder !currentDir?' => 'Wil Je Echt Deze Directory Verwijderen: !currentDir?',
+	'Rename folder' => 'Directory Hernoemen',
+	'Move folder' => 'Directory Verplaatsen',
+	'Move folder <b>!currentDir</b> in:' => 'Verplaats Directory <b>!currentDir</b> naar:',
+	'The server is not accessible.' => 'De Server Is Niet Bereikbaar.',
+	'You are not allowed at this admin level' => 'Je bent Niet Bevoegd met je Rang.',
+	'The password doesn\'t match to the server.' => 'Het Opgegegven WachtWoord Komt Niet Overeen Met Die Van De Server.',
+	'Client not initialized' => 'client nicht initialisiert',
+	'Unknown command' => 'Onbekende Opdracht',
+	'$99FThis round is a draw.' => '$99FDeze Ronde Is Gelijk Spel.',
+	'$99FThe $<$00FBlue team$> wins this round.' => '$99FHet $00Fblauwe Team Wint Deze Ronde.',
+	'$99FThe $<$F00Red team$> wins this round.' => '$99FHet $F00Rode Team Wint Deze Ronde.',
+	'maps' => 'Maps',
+	'map' => 'Map',
+	'No map' => 'Geen Map',
+	'matchsettings' => 'Matchsettings',
+	'matchsetting' => 'Matchsetting',
+	'No matchsetting' => 'Geen Matchsetting',
+	'text->XML conversion error' => 'text->XML conversiefout',
+	'Saving XML file error' => 'Fout Bij Opslaan XML File',
+	'The folder "logs" is not writable.' => 'De Directory "logs" Kan Niet Beschreven Worden.',
+	'The folder "logs" does not exist.' => 'De Directory "logs" Bestaat Niet.',
+	'Unable to create log file:' => 'Kan het Logbestand Niet Aanmaken:',
+	'Unable to add log in file:' => 'Kan Niets Toevoegen Aan Het Logbestand:',
+	'This server does not exist' => 'Deze Server Bestaat Niet',
+	'Change password' => 'Verander Wachtwoord',
+	'Current' => 'Huidig',
+	'The current password doesn\'t match.' => 'Het Huidige Wachtwoord Komt Niet Overeen.',
+	'The password has been changed.' => 'Het Wachtwoor is Aangepast.',
+	'Not rated' => 'Niet Beoordeeld',
+	'Unable to delete server.' => 'Kan De Server Niet Verwijderen',
+	'Guest-Ban' => 'Gasten-Bannen',
+	'Access as player' => 'Verbinden Als Speler',
+	'Access as spectator' => 'verbinden als Toeschouwer',
+	'Disable horns' => 'Toeters Deactiveren',
+	'Current vote' => 'Huidige Beoordeling',
+	'Cancel vote' => 'Beoordeling Afbre3ken',
+	'Change order' => 'Verander Rangschikking',
+	'Servers order' => 'Rangschikking Servers',
+	'This path was not required rights:' => 'Dir Pad Had Geen Vereiste Rechten:',
+	'needs' => 'Afhankelijkheden',
+	'Plugin error: script.php or view.php file is missing.' => 'Fout Invoegtoepassing: script.php of view.php Ontbreekt.',
+	'No server admin levels configured.' => 'Geen Server Rangen Geconfigureerd.',
+	'Gold time' => 'Gouden Tijd',
+	'Cost' => 'Kosten',
+	'Team infos' => 'Team Informatie',
+	'Script settings' => 'Script Instellingen',
+	'Script settings updated.' => 'Script Instellingen Bijgewerkt.',
+	'Change authentication password' => 'Verander authenticatie wachtwoord',
+	'You changed the password "!authLevel", remember it at the next connection!' => 'Het Wachtwoor Is Aangepast "!authLevel", Onthoud Dit Voor De Volgende Keer!',
+	'Automatic' => 'Automatisch',
+	'Choose number' => 'Kies Aantal',
+	'Client inputs max latency' => 'Maximale vertraging Client (Ping)',
+	'Script info' => 'Script Informatie',
+	'Compatible map types' => 'Overeenkomende Map Typen',
+	'Script parameters' => 'Script Waarden',
+	'Value' => 'Waarde',
+	'The server already exist! Change the name.' => 'De Server Bestaat Al! Verander De Naam.',
+);
+?>
\ No newline at end of file
diff --git a/resources/lang/no.php b/resources/lang/no.php
new file mode 100644
index 0000000..df3ba89
--- /dev/null
+++ b/resources/lang/no.php
@@ -0,0 +1,364 @@
+﻿<?php
+/**
+* Norsk translation
+*
+* @author   W00p 
+* @version  1.0
+*/
+$translate = array(
+	'Access server' => 'Tilgang server',
+	'Access relay' => 'Tilgang relay',
+	'Disconnect' => 'Koble fra',
+	'Servers' => 'Servere',
+	'Server' => 'Server',
+	'Password' => 'Passord',
+	'Admin level' => 'Administrasjonsnivå',
+	'Connection' => 'Koble til',
+	'Please put a password.' => 'Vennligst skriv inn et passord.',
+	'Connection error' => 'Tilkoblings feil',
+	'Connection error: invalid session.' => 'Tilkoblings feil: ugyldig økt.',
+	'Servers configuration' => 'Server konfigurasjon',
+	'Online configuration' => 'Online konfigurasjon',
+	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'Dette er din første tilkobling og ingen servere er konfigurert. Velg et passord for å konfigere dine servere.',
+	'Unable to save password.' => 'Feil ved lagring av passord.',
+	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Online konfigurering er deaktivert. Bruk "./config/servers.cfg.php".',
+	'Offline server.' => 'Frakoblet server.',
+	'Authentication error.' => 'Autentiseringsfeil.',
+	'Add to favourite' => 'Legg til som favoritt',
+	'Current map' => 'Gjeldende bane',
+	'Name' => 'Navn',
+	'Author' => 'Laget av',
+	'Environment' => 'Miljø',
+	'Map UId' => 'Bane UId',
+	'Game mode' => 'Spillmodus',
+	'No thumbnail' => 'Ingen miniatyrbilde',
+	'Server name' => 'Server navn',
+	'Status' => 'Status',
+	'Server login' => 'Server logginn',
+	'Connected on' => 'Tilkoblet på',
+	'Dedicated version' => 'Dedicated versjon',
+	'Statistics' => 'Statistikk',
+	'Uptime' => 'Oppetid',
+	'Number of connections' => 'Antall tilkoblinger',
+	'Average connection time' => 'Gjennomsnittlig tilkoblingstiden',
+	'Average number of players' => 'Gjennomsnittlig antall spillere',
+	'Recv net rate' => 'Recv net rate',
+	'Send net rate' => 'Send net rate',
+	'Total receiving size' => 'Totalt størrelse mottat',
+	'Total sending size' => 'Totalt størrelse sendt',
+	'Players' => 'Spillere',
+	'Detailed mode' => 'Detaljert modus',
+	'Simple mode' => 'Enkel modus',
+	'Nickname' => 'Kallenavn',
+	'Login' => 'Logginn',
+	'For the selection' => 'Valg',
+	'Ban' => 'Utesteng',
+	'Kick' => 'Sparke',
+	'Spectator' => 'Tilskuer',
+	'Player' => 'Spiller',
+	'Team' => 'Lag',
+	'Guest' => 'Gjest',
+	'Ignore' => 'Ignorer',
+	'Red team' => 'Rødt lag',
+	'Blue team' => 'Blått lag',
+	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Resultatet har blitt endret: $00fblått lag $fffhar !scoreTeamBlue og $f00rødt lag $fffhar !scoreTeamRed',
+	'Server options' => 'Serverinnstillinger',
+	'General' => 'Generelt',
+	'Comment' => 'Kommentar',
+	'Player password' => 'Spiller passord',
+	'Spectator password' => 'Tilskuer passord',
+	'Nb max of players' => 'Maks antall spillere',
+	'Next value' => 'Neste valg',
+	'Nb max of spectators' => 'Maks antall tilskuere',
+	'Advanced' => 'Avansert',
+	'P2P Upload' => 'P2P Opplasting',
+	'P2P Download' => 'P2P Nedlasting',
+	'Ladder mode' => 'Ladder modus',
+	'Vehicles quality' => 'Kvalitet på kjøretøy',
+	'Vote expiration' => 'Stemme utløpsdato',
+	'sec' => 'sek', // Second
+	'Vote ratio' => 'Stemme forhold',
+	'Hidden server' => 'Skjul server',
+	'Map download' => 'Bane nedlasting',
+	'Replays auto save' => 'autolagring av repriser',
+	'Buddy notification' => 'Kompis varsling',
+	'Save' => 'Lagre',
+	'Inactive' => 'Inaktiv',
+	'Forced' => 'Tvunget',
+	'Fast' => 'Rask',
+	'High' => 'Høy',
+	'Game infos' => 'Spillinnstillinger',
+	'Game information' => 'Spillinnstillinger',
+	'Color' => 'Farge',
+	'Black' => 'Sort',
+	'Red' => 'Rødt',
+	'Green' => 'Grønt',
+	'Blue' => 'Blå',
+	'Orange' => 'Orange',
+	'Pink' => 'Rosa',
+	'Purple' => 'Violett',
+	'Grey' => 'Grå',
+	'White' => 'Hvit',
+	'Message destination' => 'Meldings destinasjon',
+	'Chat' => 'Prate',
+	'Show server lines' => 'Se server linjer',
+	'Hide server lines' => 'Skjul server linjer',
+	'Default color: yellow' => 'Standard farge: gul',
+	'Message' => 'Melding',
+	'Destination' => 'Destinasjon',
+	'Send' => 'Last opp',
+	'Unable to create the folder' => 'Kan ikke opprettet mappen',
+	'Unable to rename the folder' => 'Kan ikke endre navn på mappen',
+	'Unable to move the folder' => 'Kan ikke flytte mappen',
+	'Unable to delete the folder' => 'Kan ikke slettet mappen',
+	'List' => 'Liste',
+	'Go to the current map' => 'Gå til gjeldende bane',
+	'Map' => 'Bane',
+	'Delete' => 'Slett',
+	'Move after the current map' => 'Flytt etter gjeldende bane',
+	'Unable to rename the map' => 'Kan ikke endre navnet på banen',
+	'Unable to move the map' => 'Kan ikke flytte banen',
+	'Unable to delete the map' => 'Kan ikke slette banen',
+	'Local' => 'Lokal',
+	'Do you really want to remove this selection?' => 'Vil du virkelig fjerne dette valget?',
+	'Move' => 'Flytt',
+	'Rename' => 'Endre navn',
+	'Download' => 'Last ned',
+	'Insert' => 'Sett inn',
+	'Add' => 'Legg til',
+	'Cancel' => 'Avbryt',
+	'Replace the special characters' => 'Erstatte spesialtegn',
+	'in the folder:' => 'i mappen:',
+	'Root' => 'Roten',
+	'The map,is currently used by the server.' => 'Banen er i bruk av serveren.',
+	'MatchSettings' => 'MatchSettings',
+	'Contains' => 'Inneholder',
+	'Modified' => 'Endret',
+	'Edit' => 'Rediger',
+	'Load' => 'Last',
+	'Save ' => 'Lagre',
+	'Create' => 'Opprett',
+	'Unable to save the MatchSettings' => 'Kan ikke lagre MatchSettings',
+	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'MatchSettings "!matchSettingName" var vellykket opprettet i mappen',
+	'a MatchSettings' => 'en MatchSettings',
+	'Create a MatchSettings' => 'Opprett en MatchSettings',
+	'MatchSettings name' => 'MatchSettings navn',
+	'Maps' => 'Baner',
+	'Make selection' => 'Opprett valgene',
+	'Import all folder' => 'Importer alle mappene',
+	'Select' => 'Velg',
+	'MatchSettings selected maps:' => 'MatchSettings valgte baner:',
+	'View the MatchSettings selection' => 'Se MatchSettings valgene',
+	'MatchSettings selection' => 'MatchSettings valg',
+	'Remove map from the selection' => 'Fjern baner fra valget',
+	'Close' => 'Lukk',
+	'HotSeat' => 'HotSeat',
+	'Time limit' => 'Tidsfrit',
+	'Rounds count' => 'Runde teller',
+	'Filter' => 'Filter',
+	'Lan' => 'Lan',
+	'Internet' => 'Internet',
+	'Solo' => 'Solo',
+	'Sort index' => 'Indeks sortering',
+	'Random map order' => 'Tilfeldig bane rekkefølge',
+	'Default game mode' => 'Standard spillmodus',
+	'No map selected for the MatchSettings.' => 'Ingen baner valgt for MatchSettings.',
+	'The MatchSettings name already exists! It will be overwritten.' => 'MatchSettings navnet finnes allerede! Det vil bli overskrevet.',
+	'Order' => 'Rekkefølge',
+	'Automatic sort' => 'Automatisk sortering',
+	'Random' => 'Tilfeldig',
+	'Manual sort' => 'Manuell sortering',
+	'Save the current MatchSettings' => 'Lagre gjeldende MatchSettings',
+	'Reset' => 'Tilbakestill',
+	'Transfer mode' => 'Transfer modus',
+	'at the end of list' => 'til slutten av listen',
+	'after current map' => 'etter gjeldende bane',
+	'only in the folder' => 'kun i mappen',
+	'Options' => 'Alternativer',
+	'Go to the maps list when upload is complete' => 'Gå til banelisten når opplastingen er ferdig',
+	'Upload' => 'Last opp',
+	'Failed' => 'Mislyktes',
+	'Upload a file' => 'Last opp en fil',
+	'Drop files here to upload' => 'Slipp filer her for å laste opp',
+	'Upload not finished' => 'Opplasting ikke ferdig',
+	'from' => 'fra',
+	'Kb' => 'Kb',
+	'Mb' => 'Mb',
+	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} har ugyldig utvidelse. Bare {extensions} er tillatt.',
+	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} er for stor, maks tillatt størrelse er {sizeLimit}.',
+	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} er for liten, minste filstørrelse er {minSizeLimit}.',
+	'{file} is empty, please select files again without it.' => '{file} er tom, vennligst velg filen igjen.',
+	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Filer blir nå lastet opp, forlater du siden nå vil opplasting bli kasellert.',
+	'No file was uploaded' => 'Ingen filer ble lastet opp',
+	'The file is empty.' => 'Filer er tom.',
+	'The file size is too large.' => 'Størrelsen på filen er for stor.',
+	'The file has invalid extension (allowed extensions:' => 'Filen har ugyldig utvidelse (tillatt utvidelser:',
+	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Filen ble ikke lastet opp. Opplasting har blitt kansellert, eller en server feil har oppstått.',
+	'Server error. The upload destination folder isn\'t writable.' => 'Server feil. Opplastings mappe er ikke skrivbar.',
+	'Plugins' => 'Programtillegg',
+	'plugin installed' => 'programtillegg installert',
+	'plugins installed' => 'Programtillegg installert',
+	'Cannot include another plugins config file.' => 'Kan ikke inkludere en annen konfigurasjons fil til programtillegg.',
+	'Variable "$PLUGINS" not found.' => 'Variabel "$PLUGINS" ikke funnet.',
+	'Plugins are extensions to add features to Adminserv.' => 'Programtillegg er utvidelser for ekstra funksjoner til Adminserv.',
+	'Install a plugin' => 'Installer er programtillegg',
+	'See all plugins:' => 'Zeige alle Plugins:',
+	'Click here' => 'Klikk her',
+	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Pakk ut filene til programtillegget og legg det i &laquo; plugins &raquo; mappen til Adminserv.',
+	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'I konfigurasjons utvidelsen, legg til navnet på programtillegg mappen du nylagt pakket ut.',
+	'Create a new plugin' => 'Opprett et nytt programtillegg',
+	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>Um ein Plugin zu erstellen, gehe in de Plugin Orner und kopiere den Ordner _newplugin. Ersetze die Werte in der config.ini Datei und bennene den Order um.<br />Dort befinden sich zwei PHP Dateien:</p><ul><li>script.php : Diese Datei wird vor dem Header der Seite ausgeführt. Hier werden alle Plugin Scripte plaziert.</li><li>view.php : Diese Datei ist für die Anzeige des Plugins verantworlich und wird nach dem Header der seite ausgeführt. Hier wird der ganze HTML Code plaziert.</li></ul><p>Die benötigten Recourcen (classes, js, css) können Sie in die Dateien einbinden.</p>',
+	'Unable to delete the playlist' => 'Kan ikke slette spillelisten',
+	'Player login' => 'Spiller logginn',
+	'Clean the list' => 'Tøm listen',
+	'The list is already empty.' => 'Listen er allerede tom.',
+	'No player' => 'Ingen spillere',
+	'IP address' => 'IP adresse',
+	'Client' => 'Klient',
+	'Blacklist' => 'Svartelistet',
+	'Remove from the list' => 'Fjern fra listen',
+	'Select a player' => 'Velg en spiller',
+	'Enter another login' => 'Skriv et annet logginn',
+	'Add in the' => 'Legg til i',
+	'Playlists' => 'Spillelister',
+	'Playlist' => 'Spilleliste',
+	'Type' => 'Type',
+	'Playlist name' => 'Spillelistens navn',
+	'New playlist' => 'Ny spilleliste',
+	'players' => 'Spillere',
+	'player' => 'Spiller',
+	'No playlist' => 'Ingen spilleliste',
+	'You are not allowed to configure the servers' => 'Du har ikke rettigheter til konfigurering av serverene.',
+	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Ingen servere tilgjengelig. For å legge til ny, konfigurer "config/servers.cfg.php"',
+	'The servers configuration file isn\'t recognized by AdminServ.' => 'Server konfigurasjonsfilen kan ikke gjenkjennes av Adminserv.',
+	'This server has been duplicated.' => 'Denne servere har blitt duplisert.',
+	'Unable to duplicate server.' => 'Kan ikke duplisere serveren.',
+	'copy' => 'Kopier',
+	'Servers list' => 'Serverliste',
+	'Address' => 'Adresse',
+	'Port' => 'Port',
+	'SuperAdmin level' => 'SuperAdmin level',
+	'User level' => 'User level',
+	'Manage' => 'Administrere',
+	'None' => 'Ingen',
+	'Local network' => 'Lokalt nettverk',
+	'All' => 'Alle',
+	'Removed' => 'Fjernet',
+	'Missing' => 'Mangler',
+	'No server' => 'Ingen server',
+	'servers' => 'Servere',
+	'server' => 'Server',
+	'Duplicate' => 'Duplisere',
+	'Modify' => 'Endre',
+	'The "!serverName" server has been deleted.' => 'Serveren "!serverName" har blitt slettet.',
+	'This server has been modified.' => 'Denne serveren har blitt endret.',
+	'Unable to modify the server.' => 'Kan ikke endre serveren.',
+	'This server has been added.' => 'Denne serveren har blitt lagt til.',
+	'Unable to add the server.' => 'Kan ikke legge til serveren.',
+	'Add server' => 'Legg til server',
+	'Edit server' => 'Rediger server',
+	'Back' => 'Tilbake',
+	'Connection information' => 'Tilkoblings informasjon',
+	'Server name without color' => 'Server navn uten farger',
+	'IP address or domain name' => 'IP adresse eller domene navn',
+	'XMLRPC port' => 'XMLRPC Port',
+	'Port for remote control' => 'Port for fjernstyring',
+	'Optionnal information' => 'Valgfri informasjon',
+	'Server MatchSettings' => 'Server MatchSettings',
+	'Current server MatchSettings name' => 'Gjeldende server MatchSettings navn',
+	'Possible values for the admin level:' => 'Mulige verdier for admin nivå:',
+	'all => all access' => 'alle => alle rettigheter',
+	'local => local network access' => 'lokale => lokale nettverks rettigheter',
+	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => Tilgang til en eller flere IP adresser',
+	'none => removed from the access list' => 'ingen => fjernet fra rettighets listen',
+	'No server available' => 'Ingen server tilgjengelig',
+	'No game mode available' => 'Ingen spillmodus tilgjengelig',
+	'Map end time' => 'Bane slutt tid',
+	'Round/lap end time' => 'Round/Bane slutt tid',
+	'Respawn' => 'Respawn',
+	'Default' => 'Standard',
+	'Auto (based on map)' => 'Auto (Basert på banen)',
+	'Choose time' => 'Velg tid',
+	'Return to the default value' => 'Returner til standardverdien',
+	'All WarmUp duration' => 'Varighet på oppvarmingstid',
+	'Enable' => 'Aktiver',
+	'Disable' => 'Deaktiver',
+	'Force show of all opponents' => 'Tving visning av alle motstandere',
+	'Let player choose' => 'La spillere velge',
+	'All opponents' => 'Alle motstandere',
+	'minimal opponents' => 'minimalt med motstandere',
+	'Choose opponents number' => 'Velg motstander nummer',
+	'Script name' => 'Skript navn',
+	'Use new rules' => 'Bruk nye regler',
+	'Points limit' => 'Poeng grense',
+	'Custom points limit' => 'Egendefinert poeng grense',
+	'Force laps' => 'Tving runder',
+	'Start synchronization period' => 'Starte synkronisering periode',
+	'Maximal points' => 'Maksimalt med poeng',
+	'Number of laps' => 'Antall runder',
+	'Rounds per map' => 'Runder per bane',
+	'Number of winners' => 'Antall vinnere',
+	'No player available' => 'Ingen spillere tilgjengelig',
+	'New' => 'Ny',
+	'Parent folder' => 'Forrige mappe',
+	'Folder options' => 'Mappe innstillinger',
+	'Do you really want to remove this folder !currentDir?' => 'Vil du virkelig slette mappen !currentDir?',
+	'Rename folder' => 'Endre mappe navn',
+	'Move folder' => 'Flytt mappe',
+	'Move folder <b>!currentDir</b> in:' => 'Flytt mappen <b>!currentDir</b> til:',
+	'The server is not accessible.' => 'Denne server er ikke tilgjengelig.',
+	'You are not allowed at this admin level' => 'Du er ikke tillatt på dette admin nivå.',
+	'The password doesn\'t match to the server.' => 'Feil passord, vennligst skriv inn rett passord.',
+	'Client not initialized' => 'Klienten er ikke initialisert',
+	'Unknown command' => 'Ugyldig kommando',
+	'$99FThis round is a draw.' => '$99FDenne runder ble uavgjort.',
+	'$99FThe $<$00FBlue team$> wins this round.' => '$00Fblått lag vant denne runden.',
+	'$99FThe $<$F00Red team$> wins this round.' => '$F00rødt lag vant denne runden.',
+	'maps' => 'Baner',
+	'map' => 'Bane',
+	'No map' => 'Ingen bane',
+	'matchsettings' => 'Matchsettings',
+	'matchsetting' => 'Matchsetting',
+	'No matchsetting' => 'Ingen Matchsetting',
+	'text->XML conversion error' => 'text->XML konverterings feil',
+	'Saving XML file error' => 'XML lagringsfeil',
+	'The folder "logs" is not writable.' => 'Mappen "logs" er ikke skrivbar.',
+	'The folder "logs" does not exist.' => 'Mappen "logs" eksisterer ikke.',
+	'Unable to create log file:' => 'Kan ikke opprette log fil:',
+	'Unable to add log in file:' => 'Kan ikke legge til log fil:',
+	'This server does not exist' => 'Denne serveren eksisterer ikke',
+	'Change password' => 'Endre passord',
+	'Current' => 'Gjeldende',
+	'The current password doesn\'t match.' => 'Gjeldende passord samvarer ikke.',
+	'The password has been changed.' => 'Passordet har blitt endret.',
+	'Not rated' => 'Ikke vurdert',
+	'Unable to delete server.' => 'Kan ikke slette server',
+	'Guest-Ban' => 'Gjeste banning',
+	'Access as player' => 'Koble til som spiller',
+	'Access as spectator' => 'Koble til som tilskuer',
+	'Disable horns' => 'Deaktiver horn',
+	'Current vote' => 'Gjeldende stemme',
+	'Cancel vote' => 'Kanseller stemme',
+	'Change order' => 'Endre rekkefølge',
+	'Servers order' => 'Server rekkefølge',
+	'This path was not required rights:' => 'Denne banen var ikke påkrevd rettigheter:',
+	'needs' => 'behov',
+	'Plugin error: script.php or view.php file is missing.' => 'Feil med programtillegg: script.php eller view.php mangler.',
+	'No server admin levels configured.' => 'Ingen admin nivå konfigurert.',
+	'Gold time' => 'Gold tid',
+	'Cost' => 'Kost',
+	'Team infos' => 'Lag informasjon',
+	'Script settings' => 'Skript innstillinger',
+	'Script settings updated.' => 'Skript innstillinger oppdatert.',
+	'Change authentication password' => 'Endre autentiserings passord',
+	'You changed the password "!authLevel", remember it at the next connection!' => 'Du endre passord "!authLevel", husk dette neste gang til kobler til!',
+	'Automatic' => 'Automatisk',
+	'Choose number' => 'Velg nummer',
+	'Client inputs max latency' => 'Maks ventetid klient innganger',
+	'Script info' => 'Skript info',
+	'Compatible map types' => 'Kompatible banetyper',
+	'Script parameters' => 'Skript parametre',
+	'Value' => 'Verdi',
+	'The server already exist! Change the name.' => 'Serveren eksisterer allerede! Skift navn.',
+);
+?>
\ No newline at end of file
diff --git a/resources/lang/pl.php b/resources/lang/pl.php
new file mode 100644
index 0000000..1350f45
--- /dev/null
+++ b/resources/lang/pl.php
@@ -0,0 +1,364 @@
+<?php
+/**
+* Polish translation
+*
+* @author   Djhubertus 
+* @version  1.0
+*/
+$translate = array(
+	'Access server' => 'Dostęp do serwera',
+	'Access relay' => 'Dostęp do transmisji',
+	'Disconnect' => 'Rozłącz',
+	'Servers' => 'Serwery',
+	'Server' => 'Serwer',
+	'Password' => 'Hasło',
+	'Admin level' => 'Poziom zarządzania',
+	'Connection' => 'Połączenie',
+	'Please put a password.' => 'Proszę wpisać hasło.',
+	'Connection error' => 'Błąd połączenia',
+	'Connection error: invalid session.' => 'Błąd połączenia: nieprawidłowa sesja',
+	'Servers configuration' => 'Konfiguracja serwera',
+	'Online configuration' => 'Konfiguracja Online',
+	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'To twoje pierwsze połączenie i nie posiadasz żadnych skonfigurowanych serwerów. Wpisz hasło którym zabezpieczysz dostęp do konfiguracji AdminServ',
+	'Unable to save password.' => 'Problem z zapisem hasła, spróbuj ponownie.',
+	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Konfiguracja Online jest zablokowana. Użyj pliku ".config/servers.cfg.php"',
+	'Offline server.' => 'Serwer niedostępny.',
+	'Authentication error.' => 'Błąd uwierzytelnienia.',
+	'Add to favourite' => 'Dodaj do ulubionych',
+	'Current map' => 'Aktualna mapa na serwerze',
+	'Name' => 'Nazwa',
+	'Author' => 'Autor',
+	'Environment' => 'Środowisko',
+	'Map UId' => 'UId mapy',
+	'Game mode' => 'Tryb gry',
+	'No thumbnail' => 'Brak miniatury',
+	'Server name' => 'Nazwa serwera',
+	'Status' => 'Status',
+	'Server login' => 'Login serwera',
+	'Connected on' => 'Połączony na',
+	'Dedicated version' => 'Wersja serwera',
+	'Statistics' => 'Statystyki',
+	'Uptime' => 'Załadowanie',
+	'Number of connections' => 'Liczba połączeń',
+	'Average connection time' => 'Średni czas graczy',
+	'Average number of players' => 'Średnia liczba graczy',
+	'Recv net rate' => 'Tempo otrzymanych pakietów danych',
+	'Send net rate' => 'Tempo wysłanych pakietów danych',
+	'Total receiving size' => 'Wielkość otrzymanych',
+	'Total sending size' => 'Wielkość wysłanych',
+	'Players' => 'Graczy',
+	'Detailed mode' => 'Tryb szczegółowy',
+	'Simple mode' => 'Tryb prosty',
+	'Nickname' => 'Nick',
+	'Login' => 'Login',
+	'For the selection' => 'Z zaznaczonych',
+	'Ban' => 'Ban',
+	'Kick' => 'Kick',
+	'Spectator' => 'Widz',
+	'Player' => 'Gracz',
+	'Team' => 'Zespół',
+	'Guest' => 'Gość',
+	'Ignore' => 'Ignoruj',
+	'Red team' => 'Czerwoni',
+	'Blue team' => 'Niebiescy',
+	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Wyniki uległy zmianie: $00fNiebiescy $fff!scoreTeamBlue - !scoreTeamRed $f00Czerwoni',
+	'Server options' => 'Opcje serwera',
+	'General' => 'Główne',
+	'Comment' => 'Komentarz',
+	'Player password' => 'Hasło do gry',
+	'Spectator password' => 'Hasło dla widzów',
+	'Nb max of players' => 'Max. liczba graczy',
+	'Next value' => 'Nowa wartość',
+	'Nb max of spectators' => 'Max. liczba widzów',
+	'Advanced' => 'Zaawansowane',
+	'P2P Upload' => 'P2P - Wysyłanie',
+	'P2P Download' => 'P2P - Pobieranie',
+	'Ladder mode' => 'Tryb rankingowy',
+	'Vehicles quality' => 'Jakość pojazdów',
+	'Vote expiration' => 'Długość głosowań',
+	'sec' => 'sek', // Second
+	'Vote ratio' => 'Współczynnik udanego głosowania',
+	'Hidden server' => 'Serwer prywatny',
+	'Map download' => 'Pobieranie map',
+	'Replays auto save' => 'Auto zapis powtórek',
+	'Buddy notification' => 'Powiadomienia o znajomych',
+	'Save' => 'Zapisz',
+	'Inactive' => 'Nieaktywny',
+	'Forced' => 'Wymuszony',
+	'Fast' => 'Szybko',
+	'High' => 'Ładny',
+	'Game infos' => 'Info o grze',
+	'Game information' => 'Informacje o grze',
+	'Color' => 'Kolor',
+	'Black' => 'Czarny',
+	'Red' => 'Czerwony',
+	'Green' => 'Zielony',
+	'Blue' => 'Niebieski',
+	'Orange' => 'Pomarańczowy',
+	'Pink' => 'Różowy',
+	'Purple' => 'Fioletowy',
+	'Grey' => 'Szary',
+	'White' => 'Biały',
+	'Message destination' => 'Przeznaczenie wiadomości',
+	'Chat' => 'Chat',
+	'Show server lines' => 'Pokaż wiadomości serwera',
+	'Hide server lines' => 'Ukryj wiadomości serwera',
+	'Default color: yellow' => 'Domyślny kolor: żółty',
+	'Message' => 'Wiadomość',
+	'Destination' => 'Przeznaczenie',
+	'Send' => 'Wyślij',
+	'Unable to create the folder' => 'Niemożliwe stworzenie folderu',
+	'Unable to rename the folder' => 'Niemożliwa zmiana nazwy folderu',
+	'Unable to move the folder' => 'Niemożliwe przeniesienie folderu',
+	'Unable to delete the folder' => 'Niemożliwe usunięcie folderu',
+	'List' => 'Lista',
+	'Go to the current map' => 'Idź do aktualnej mapy',
+	'Map' => 'Mapa',
+	'Delete' => 'Usuń',
+	'Move after the current map' => 'Umieść pod aktualną mapą',
+	'Unable to rename the map' => 'Niemożliwe zmiana nazwy mapy',
+	'Unable to move the map' => 'Niemożliwe przeniesienie mapy',
+	'Unable to delete the map' => 'Niemożliwe usunięcie mapy',
+	'Local' => 'Lokalnie',
+	'Do you really want to remove this selection?' => 'Jesteś pewny że chcesz usunąć zaznaczenie ?',
+	'Move' => 'Przesuń',
+	'Rename' => 'Zmień nazwę',
+	'Download' => 'Pobierz',
+	'Insert' => 'Włóż',
+	'Add' => 'Dodaj',
+	'Cancel' => 'Anuluj',
+	'Replace the special characters' => 'Zamień znaki specjalne',
+	'in the folder:' => 'w folderze:',
+	'Root' => 'Root',
+	'The map,is currently used by the server.' => 'Mapa jest aktualnie używana przez serwer.',
+	'MatchSettings' => 'Ustawienia skryptu',
+	'Contains' => 'Zawiera',
+	'Modified' => 'Modyfikowana',
+	'Edit' => 'Edytuj',
+	'Load' => 'Wczytaj',
+	'Save ' => 'Zapisz',
+	'Create' => 'Stwórz',
+	'Unable to save the MatchSettings' => 'Niemożliwy zapis ustawień skryptu',
+	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'Ustawienia "!matchSettingName" zostały pomyślnie stworzone w folderze',
+	'a MatchSettings' => 'Ustawienia skryptu',
+	'Create a MatchSettings' => 'Stwórz plik z ustawieniami skryptu',
+	'MatchSettings name' => 'Nazwa',
+	'Maps' => 'Mapy',
+	'Make selection' => 'Zrób zaznaczenie',
+	'Import all folder' => 'Importuj wszystkie foldery',
+	'Select' => 'Wybierz',
+	'MatchSettings selected maps:' => 'Wybrane mapy:',
+	'View the MatchSettings selection' => 'Zobacz zaznaczenie',
+	'MatchSettings selection' => 'Zaznaczenie',
+	'Remove map from the selection' => 'Wyrzuć mapę z zaznaczenia',
+	'Close' => 'Zamknij',
+	'HotSeat' => 'Gorące krzesło',
+	'Time limit' => 'Limit Czasowy',
+	'Rounds count' => 'Liczba rund',
+	'Filter' => 'Filtr',
+	'Lan' => 'Lokalna',
+	'Internet' => 'Sieciowa',
+	'Solo' => 'Solo',
+	'Sort index' => 'Index sortowania',
+	'Random map order' => 'Losowa kolejność map',
+	'Default game mode' => 'Domyślny tryb gry',
+	'No map selected for the MatchSettings.' => 'Brak wybranych map dla skryptu.',
+	'The MatchSettings name already exists! It will be overwritten.' => 'Taka nazwa jest już używana! Zostanie ona nadpisana.',
+	'Order' => 'Kolejność',
+	'Automatic sort' => 'Automatyczne sortowanie',
+	'Random' => 'Losowo',
+	'Manual sort' => 'Ręczne sortowanie',
+	'Save the current MatchSettings' => 'Zapisz aktualne ustawienia skryptu',
+	'Reset' => 'Reset',
+	'Transfer mode' => 'Tryb Transferu',
+	'at the end of list' => 'Na końcu listy',
+	'after current map' => 'Po aktualnej mapie',
+	'only in the folder' => 'Tylko w folderze',
+	'Options' => 'Opcje',
+	'Go to the maps list when upload is complete' => 'Idź do listy map kiedy wysyłanie dobiegnie końca',
+	'Upload' => 'Wysyłanie',
+	'Failed' => 'Niepowodzenie',
+	'Upload a file' => 'Wyślij plik',
+	'Drop files here to upload' => 'Umieść pliki tutaj by wysłać',
+	'Upload not finished' => 'Wysyłanie nie dobiegło końca',
+	'from' => 'z',
+	'Kb' => 'Kb',
+	'Mb' => 'Mb',
+	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} ma nieznane rozszerzenie. Tylko {extensions} są dopuszczalne',
+	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} jest zbyt duży. Max. rozmiar to {sizeLimit}',
+	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} jest zbyt mały. Min. rozmiar to {minSizeLimit}.',
+	'{file} is empty, please select files again without it.' => '{file} jest pusty. Wybierz pliki pomijając ten.',
+	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Pliki są wysyłane. jeżeli opuścisz stronę, wysyłanie zostanie anulowane.',
+	'No file was uploaded' => 'Żaden plik nie jest wysyłany',
+	'The file is empty.' => 'Plik jest pusty.',
+	'The file size is too large.' => 'Wielkość piku jest zbyt duża.',
+	'The file has invalid extension (allowed extensions:' => 'Plik ma nieznane rozszerzenie (Dozwolone:',
+	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Plik nie został wysłany. Wysyłanie zostało anulowane lub wystąpił błąd',
+	'Server error. The upload destination folder isn\'t writable.' => 'Błąd serwera. Przeznaczenie wysyłanego pliku jest nienadpisywalne, sprawdź CHMOD\'y ',
+	'Plugins' => 'Pluginy',
+	'plugin installed' => 'Zainstalowany',
+	'plugins installed' => 'Zainstalowane',
+	'Cannot include another plugins config file.' => 'Nie można dołączyć plików konfiguracyjnych innych pluginów.',
+	'Variable "$PLUGINS" not found.' => 'Zmienna "$PLUGINS" nie znaleziona.',
+	'Plugins are extensions to add features to Adminserv.' => 'Pluginy to rozszerzenie umożliwiające zwiększenie zawartości AdminServ.',
+	'Install a plugin' => 'Zainstaluj plugin',
+	'See all plugins:' => 'Zobacz wszystkie pluginy:',
+	'Click here' => 'Kliknij tutaj',
+	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Rozpakuj plugin i umieść jego zawartość w folderze &laquo; plugins &raquo; AdminServ\'a.',
+	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'W pliku extension.cfg.php dodaj nazwę folderu pluginu dodanego wcześniej.',
+	'Create a new plugin' => 'Stwórz nowy plugin',
+	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>By stworzyć plugin, idź do folderu plugins i zduplikuj plik _newplugin. Podmień wartości w config.ini i nazwę folderu.<br />Potem sprawdź 2 pliki PHP:</p><ul><li>script.php : Ten plik jest używany przed headerem strony. To miejsce gdzie wszystkie pluginy są umieszczane.</li><li>view.php : Ten plik jest wywoływane po headerze. To miejsce gdzie umieszczany jest kod HTML.</li></ul><p>Potrzebujesz stworzyć zawartość (klasy, js, css), potem załącz te pliki.</p>',
+	'Unable to delete the playlist' => 'Niemożliwe by usunąć playlistę',
+	'Player login' => 'Login gracza',
+	'Clean the list' => 'Wyczyść listę',
+	'The list is already empty.' => 'Lista jest pusta.',
+	'No player' => 'Brak graczy',
+	'IP address' => 'Adres IP',
+	'Client' => 'Klient',
+	'Blacklist' => 'Czarna lista',
+	'Remove from the list' => 'Usuń z listy',
+	'Select a player' => 'Wybierz gracza',
+	'Enter another login' => 'Wpisz inny login',
+	'Add in the' => 'Dodaj do',
+	'Playlists' => 'Playlisty',
+	'Playlist' => 'Playlista',
+	'Type' => 'Rodzaj',
+	'Playlist name' => 'Nazwa playlisty',
+	'New playlist' => 'Nowa playlista',
+	'players' => 'graczy',
+	'player' => 'gracz',
+	'No playlist' => 'Brak playlisty',
+	'You are not allowed to configure the servers' => 'Nie jesteś upoważniony do konfiguracji serwerów.',
+	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Brak dostępnych serwerów. By dodać, skonfiguruj plik "config/servers.cfg.php"',
+	'The servers configuration file isn\'t recognized by AdminServ.' => 'Konfiguracja serwerów nie jest rozpoznawalna przez AdminServ.',
+	'This server has been duplicated.' => 'Ten serwer jest zduplikowany.',
+	'Unable to duplicate server.' => 'Niemożliwa duplikacja serwera.',
+	'copy' => 'kopiuj',
+	'Servers list' => 'Lista serwerów',
+	'Address' => 'Adres',
+	'Port' => 'Port',
+	'SuperAdmin level' => 'Poziom SuperAdmina',
+	'User level' => 'Poziom Gracza',
+	'Manage' => 'Zarządzaj',
+	'None' => 'Żaden',
+	'Local network' => 'Sieć lokalna',
+	'All' => 'Wszystkie',
+	'Removed' => 'Usunięty',
+	'Missing' => 'Pominięty',
+	'No server' => 'Brak serwera',
+	'servers' => 'serwery',
+	'server' => 'serwer',
+	'Duplicate' => 'Duplikuj',
+	'Modify' => 'Modyfikuj',
+	'The "!serverName" server has been deleted.' => 'Serwer "!serverName" został usunięty.',
+	'This server has been modified.' => 'Serwer został zmodyfikowany.',
+	'Unable to modify the server.' => 'Niemożliwa modyfikacja serwera.',
+	'This server has been added.' => 'Serwer został dodany.',
+	'Unable to add the server.' => 'Niemożliwe dodanie serwera.',
+	'Add server' => 'Dodaj serwer',
+	'Edit server' => 'Edytuj serwer',
+	'Back' => 'Wróć',
+	'Connection information' => 'Informacje o połączeniu',
+	'Server name without color' => 'Nazwa serwera bez formatowania',
+	'IP address or domain name' => 'Adres IP lub domena',
+	'XMLRPC port' => 'Port XMLRPC',
+	'Port for remote control' => 'Port dostępu',
+	'Optionnal information' => 'Informacje opcjonalne',
+	'Server MatchSettings' => 'Ustawienia skryptu',
+	'Current server MatchSettings name' => 'Aktualna nazwa ustawień skryptu',
+	'Possible values for the admin level:' => 'Możliwe wartości dla poziomu Admina :',
+	'all => all access' => 'all => Dostęp dla wszystkich',
+	'local => local network access' => 'local => Dostęp tylko przez sieć lokalną',
+	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => Dostęp tylko przez adres IP',
+	'none => removed from the access list' => 'none => Usunięty z listy dostępu',
+	'No server available' => 'Brak dostępnych serwerów',
+	'No game mode available' => 'Brak dostępnych trybów gry',
+	'Map end time' => 'Czas po końcu trasy (tylko TM)',
+	'Round/lap end time' => 'Czas na zakończenie Rundy/Okrążenia',
+	'Respawn' => 'Respawn',
+	'Default' => 'Domyślny',
+	'Auto (based on map)' => 'Auto (Bazując na mapie)',
+	'Choose time' => 'Wybierz czas',
+	'Return to the default value' => 'Wróć do domyślnej wartości',
+	'All WarmUp duration' => 'Długość rozgrzewki (tylko TM)',
+	'Enable' => 'Włączone',
+	'Disable' => 'Wyłączone',
+	'Force show of all opponents' => 'Wymuś oglądanie wszystkich przeciwników',
+	'Let player choose' => 'Daj wybrać graczowi',
+	'All opponents' => 'Wszyscy przeciwnicy',
+	'minimal opponents' => 'minimum przeciwników',
+	'Choose opponents number' => 'Wybierz liczbę przeciwników',
+	'Script name' => 'Nazwa skryptu',
+	'Use new rules' => 'Użyj nowych reguł',
+	'Points limit' => 'Limit punktów',
+	'Custom points limit' => 'Własny limit punktów',
+	'Force laps' => 'Wymuś okrążenia',
+	'Start synchronization period' => 'Uruchom okres synchronizacji',
+	'Maximal points' => 'Max. punktów',
+	'Number of laps' => 'Liczba okrążeń',
+	'Rounds per map' => 'Liczba rund na mapę',
+	'Number of winners' => 'Liczba zwycięzców',
+	'No player available' => 'Brak dostępnych graczy',
+	'New' => 'Nowy',
+	'Parent folder' => 'Folder nadrzędny',
+	'Folder options' => 'Opcje folderu',
+	'Do you really want to remove this folder !currentDir?' => 'Jesteś pewny że chcesz usunąć !currentDir ?',
+	'Rename folder' => 'Zmień nazwę folderu',
+	'Move folder' => 'Przesuń folder',
+	'Move folder <b>!currentDir</b> in:' => 'Przesuń <b>!currentDir</b> w:',
+	'The server is not accessible.' => 'Serwer zabronił dostępu.',
+	'You are not allowed at this admin level' => 'Nie masz dostępu do poziomu Admina.',
+	'The password doesn\'t match to the server.' => 'Nieprawidłowe hasło.',
+	'Client not initialized' => 'Klient nie zainicjowany',
+	'Unknown command' => 'Nieznana komenda',
+	'$99FThis round is a draw.' => '$99FTa runda to remis.',
+	'$99FThe $<$00FBlue team$> wins this round.' => '$00FNiebiescy $99fwygrali rundę.',
+	'$99FThe $<$F00Red team$> wins this round.' => '$F00Czerwoni $99fwygrali rundę.',
+	'maps' => 'mapy',
+	'map' => 'mapa',
+	'No map' => 'brak mapy',
+	'matchsettings' => 'Ustawienia skryptu',
+	'matchsetting' => 'Ustawienia skryptu',
+	'No matchsetting' => 'Brak ustawień skryptu',
+	'text->XML conversion error' => 'Błąd przy konwersji text->XML',
+	'Saving XML file error' => 'Błąd w zapisie pliku XML',
+	'The folder "logs" is not writable.' => 'Folder "logs" jest nie zapisywalny, sprawdź CHMOD\'y.',
+	'The folder "logs" does not exist.' => 'Folder "logs" nie istnieje.',
+	'Unable to create log file:' => 'Niemożliwe stworzenie logu:',
+	'Unable to add log in file:' => 'Niemożliwe dodanie logu do pliku:',
+	'This server does not exist' => 'Serwer nie istnieje',
+	'Change password' => 'Zmień hasło',
+	'Current' => 'Aktualne',
+	'The current password doesn\'t match.' => 'Aktualne hasło nie pasuje.',
+	'The password has been changed.' => 'Hasło zostało zmienione.',
+	'Not rated' => 'Nie oceniane',
+	'Unable to delete server.' => 'Niemożliwe usunięcie serwera',
+	'Guest-Ban' => 'Ban dla gości',
+	'Access as player' => 'Wejdź jako gracz',
+	'Access as spectator' => 'Wejdź jako widz',
+	'Disable horns' => 'Zablokuj klaksony',
+	'Current vote' => 'Aktualne głosowanie',
+	'Cancel vote' => 'Anuluj głosowanie',
+	'Change order' => 'Zmień kolejność',
+	'Servers order' => 'Kolejność serwerów',
+	'This path was not required rights:' => 'Ta ścieżka nie zyskała wymaganych praw:',
+	'needs' => 'potrzebuje',
+	'Plugin error: script.php or view.php file is missing.' => 'Błąd pluginu: script.php lub view.php jest nieprawidłowy.',
+	'No server admin levels configured.' => 'Brak skonfigurowanych poziomów Admina.',
+	'Gold time' => 'Złoty czas',
+	'Cost' => 'Koszt',
+	'Team infos' => 'Informacje o drużynach',
+	'Script settings' => 'Ustawienia skryptu',
+	'Script settings updated.' => 'Ustawienia skryptu zaktualizowane.',
+	'Change authentication password' => 'Zmień hasło uwierzytelniające',
+	'You changed the password "!authLevel", remember it at the next connection!' => 'Zmieniłeś hasło na "!authLevel", zapamiętaj je!',
+	'Automatic' => 'Automatycznie',
+	'Choose number' => 'Wybierz liczbę',
+	'Client inputs max latency' => 'Max. opóźnienie klienta',
+	'Script info' => 'Informacje',
+	'Compatible map types' => 'Rodzaj map',
+	'Script parameters' => 'Parametry skryptu',
+	'Value' => 'Wartość',
+	'The server already exist! Change the name.' => 'Taki serwer już jest ! Zmień nazwę.',
+);
+?>
\ No newline at end of file
diff --git a/resources/process/chat.php b/resources/process/chat.php
new file mode 100644
index 0000000..1387672
--- /dev/null
+++ b/resources/process/chat.php
@@ -0,0 +1,33 @@
+<?php
+	// LECTURE
+	$data['serverLines'] = AdminServ::getChatServerLines();
+	
+	$lastNicknameUsed = Utils::readCookieData('adminserv_user', 2);
+	$data['nickname'] = ($lastNicknameUsed != null) ? $lastNicknameUsed : Utils::t('Nickname');
+	
+	$colorList = array(
+		'$ff0' => Utils::t('Color'),
+		'$000' => Utils::t('Black'),
+		'$f00' => Utils::t('Red'),
+		'$0f0' => Utils::t('Green'),
+		'$00f' => Utils::t('Blue'),
+		'$f80' => Utils::t('Orange'),
+		'$f0f' => Utils::t('Pink'),
+		'$888' => Utils::t('Grey'),
+		'$fff' => Utils::t('White')
+	);
+	$data['colorOptions'] = null;
+	$lastColorUsed = Utils::readCookieData('adminserv_user', 3);
+	foreach($colorList as $colorCode => $colorName){
+		$selected = ($colorCode == $lastColorUsed) ? ' selected="selected"' : null;
+		$data['colorOptions'] .= '<option value="'.$colorCode.'"'.$selected.'>'.$colorName.'</option>';
+	}
+	
+	$lastDestination = null;
+	$lastDestinationTitle = Utils::t('server');
+	if( isset($_SESSION['adminserv']['chat_dst']) ){
+		$lastDestination = $lastDestinationTitle = $_SESSION['adminserv']['chat_dst'];
+	}
+	$data['destination']['list'] = AdminServUI::getPlayerList($lastDestination);
+	$data['destination']['title'] = Utils::t('Message destination').' : '.$lastDestinationTitle;
+?>
\ No newline at end of file
diff --git a/resources/process/config-addlevel.php b/resources/process/config-addlevel.php
new file mode 100644
index 0000000..5e70355
--- /dev/null
+++ b/resources/process/config-addlevel.php
@@ -0,0 +1,88 @@
+<?php
+	// ENREGISTREMENT
+	if (isset($_POST['savelevel'])) {
+		// Variables
+		$levelName = Str::replaceSpecialChars( htmlspecialchars(addslashes($_POST['addLevelName'])), false);
+		$levelType = $_POST['addLevelType'];
+		$levelAccess = array();
+		if ($_POST['selectedAccessSortList']) {
+			$levelAccess = explode(',', $_POST['selectedAccessSortList']);
+		}
+		$levelPermission = array();
+		if ($_POST['selectedPermissionSortList']) {
+			$levelPermission = explode(',', $_POST['selectedPermissionSortList']);
+		}
+		$levelData = array(
+			'name' => $levelName,
+			'adminlevel' => array(
+				'type' => $levelType
+			),
+			'access' => $levelAccess,
+			'permission' => $levelPermission,
+		);
+		
+		// Édition
+		if($args['id'] !== -1){
+			if( ($result = AdminServAdminLevel::saveConfig($levelData, $args['id'])) !== true ){
+				AdminServ::error( Utils::t('Unable to modify the admin level.').' ('.$result.')');
+			}
+			else{
+				$action = Utils::t('This admin level has been modified.');
+				AdminServ::info($action);
+				AdminServLogs::add('action', $action);
+				Utils::redirection(false, '?p=config-adminlevel');
+			}
+		}
+		// Ajout
+		else{
+			if( ($result = AdminServAdminLevel::saveConfig($levelData)) !== true ){
+				AdminServ::error( Utils::t('Unable to add the admin level.').' ('.$result.')');
+			}
+			else{
+				$action = Utils::t('This admin level has been added.');
+				AdminServ::info($action);
+				AdminServLogs::add('action', $action);
+				Utils::redirection(false, '?p='.USER_PAGE);
+			}
+		}
+	}
+	
+	
+	// LECTURE
+	$defaultAccess = AdminServAdminLevel::getDefaultAccess();
+	$defaultPermission = AdminServAdminLevel::getDefaultPermission();
+	$data = array(
+		'name' => null,
+		'types' => AdminServAdminLevel::getDefaultType(),
+		'adminlevel' => array(
+			'type' => null,
+		),
+		'access' => array(
+			'default' => array(),
+			'selected' => $defaultAccess,
+		),
+		'permission' => array(
+			'default' => array(),
+			'selected' => $defaultPermission,
+		)
+	);
+	if($args['id'] !== -1){
+		define('IS_LEVEL_EDITION', true);
+		$data['name'] = AdminServAdminLevel::getName($args['id']);
+		if($data['name']){
+			$levelData = AdminServAdminLevel::getData($data['name']);
+			
+			$data['adminlevel'] = array(
+				'type' => $levelData['adminlevel']['type'],
+			);
+			$data['access'] = array(
+				'default' => array_diff($defaultAccess, $levelData['access']),
+				'selected' => $levelData['access'],
+			);
+			$data['permission'] = array(
+				'default' => array_diff($defaultPermission, $levelData['permission']),
+				'selected' => $levelData['permission'],
+			);
+		}
+	}
+?>
\ No newline at end of file
diff --git a/resources/process/config-addserver.php b/resources/process/config-addserver.php
new file mode 100644
index 0000000..fe57aca
--- /dev/null
+++ b/resources/process/config-addserver.php
@@ -0,0 +1,99 @@
+<?php
+	// ENREGISTREMENT
+	if( isset($_POST['saveserver']) ){
+		// Variables
+        $displayServPassword = trim($_POST['addDisplayServPassword']);
+		$serverName = Str::replaceSpecialChars( htmlspecialchars(addslashes($_POST['addServerName'])), false);
+		$serverAddress = trim($_POST['addServerAddress']);
+		$serverPort = intval($_POST['addServerPort']);
+		$serverMapsBasePath = trim($_POST['addServerMapsBasePath']);
+		$serverMatchSet = trim($_POST['addServerMatchSet']);
+		$serverAdmLvl = array(
+			'SuperAdmin' => $_POST['addServerAdmLvlSA'],
+			'Admin' => $_POST['addServerAdmLvlADM'],
+			'User' => $_POST['addServerAdmLvlUSR']
+		);
+		$isNotAnArray = array('all', 'local', 'none');
+		foreach($serverAdmLvl as $admLvlId => $admLvlValue){
+			if( !in_array($admLvlValue, $isNotAnArray) ){
+				$serverAdmLvl[$admLvlId] = explode(',', $admLvlValue);
+			}
+			else{
+				$serverAdmLvl[$admLvlId] = trim($admLvlValue);
+			}
+		}
+		$serverData = array(
+			'name' => $serverName,
+			'address' => $serverAddress,
+			'port' => $serverPort,
+			'mapsbasepath' => $serverMapsBasePath,
+			'matchsettings' => $serverMatchSet,
+			'adminlevel' => array(),
+            'ds_pw' => $displayServPassword
+		);
+		foreach($serverAdmLvl as $admLvlId => $admLvlValue){
+			$serverData['adminlevel'][$admLvlId] = $admLvlValue;
+		}
+		
+		// Édition
+		if($args['id'] !== -1){
+			if( ($result = AdminServServerConfig::saveServerConfig($serverData, $args['id'])) !== true ){
+				AdminServ::error( Utils::t('Unable to modify the server.').' ('.$result.')');
+			}
+			else{
+				$action = Utils::t('This server has been modified.');
+				AdminServ::info($action);
+				AdminServLogs::add('action', $action);
+				Utils::redirection(false, '?p=config-servers');
+			}
+		}
+		// Ajout
+		else{
+			if( ($result = AdminServServerConfig::saveServerConfig($serverData)) !== true ){
+				AdminServ::error( Utils::t('Unable to add the server.').' ('.$result.')');
+			}
+			else{
+				$action = Utils::t('This server has been added.');
+				AdminServ::info($action);
+				AdminServLogs::add('action', $action);
+				Utils::redirection(false, '?p='.USER_PAGE);
+			}
+		}
+	}
+	
+	
+	// LECTURE
+	$data = array(
+		'name' => null,
+		'address' => 'localhost',
+		'port' => 5000,
+		'mapsbasepath' => null,
+		'matchsettings' => 'MatchSettings/',
+		'adminlevel' => array(
+			'SuperAdmin' => 'all',
+			'Admin' => 'all',
+			'User' => 'all'
+		),
+        'ds_pw' => 'User'
+	);
+	if($args['id'] !== -1){
+		define('IS_SERVER_EDITION', true);
+		$data['name'] = AdminServServerConfig::getServerName($args['id']);
+		if($data['name']){
+			$serverData = AdminServServerConfig::getServer($data['name']);
+			$data['address'] = $serverData['address'];
+			$data['port'] = $serverData['port'];
+            $data['ds_pw'] = $serverData['ds_pw'];
+			$data['mapsbasepath'] = (isset($serverData['mapsbasepath'])) ? $serverData['mapsbasepath'] : '';
+			$data['matchsettings'] = $serverData['matchsettings'];
+			foreach($serverData['adminlevel'] as $admLvlId => $admLvlValue){
+				if( is_array($admLvlValue) ){
+					$data['adminlevel'][$admLvlId] = implode(', ', $admLvlValue);
+				}
+				else{
+					$data['adminlevel'][$admLvlId] = $admLvlValue;
+				}
+			}
+		}
+	}
+?>
\ No newline at end of file
diff --git a/resources/process/config-adminlevel.php b/resources/process/config-adminlevel.php
new file mode 100644
index 0000000..8bd85a9
--- /dev/null
+++ b/resources/process/config-adminlevel.php
@@ -0,0 +1,59 @@
+<?php
+	// EDITION
+	if (isset($_POST['editlevel'])) {
+		$levelId = AdminServAdminLevel::getId($_POST['level'][0]);
+		Utils::redirection(false, '?p=config-addlevel&id='.$levelId);
+	}
+	
+	// DUPLIQUER
+	if (isset($_POST['duplicatelevel'])) {
+		// GET
+		$getLevelData = AdminServAdminLevel::getData($_POST['level'][0]);
+		
+		// SET
+		$setLevelData = array(
+			'name' => trim( htmlspecialchars( addslashes($_POST['level'][0] . ' - '.Utils::t('copy') ) ) ),
+			'adminlevel' => $getLevelData['adminlevel'],
+			'access' => $getLevelData['access'],
+			'permission' => $getLevelData['permission'],
+		);
+		if (AdminServAdminLevel::saveConfig($setLevelData)) {
+			$action = Utils::t('This admin level has been duplicated.');
+			AdminServ::info($action);
+			AdminServLogs::add('action', $action);
+			Utils::redirection(false, '?p='.USER_PAGE);
+		}
+		else {
+			AdminServ::error( Utils::t('Unable to duplicate admin level.') );
+		}
+	}
+	
+	// SUPPRESSION
+	if (isset($_POST['deletelevel'])) {
+		$levels = AdminLevelConfig::$ADMINLEVELS;
+		unset($levels[$_POST['level'][0]]);
+		if (($result = AdminServAdminLevel::saveConfig(array(), -1, $levels)) !== true) {
+			AdminServ::error( Utils::t('Unable to delete admin level.').' ('.$result.')');
+		}
+		else {
+			$action = Utils::t('The "!levelName" admin level has been deleted.', array('!levelName' => $_POST['level'][0]));
+			AdminServ::info($action);
+			AdminServLogs::add('action', $action);
+			Utils::redirection(false, '?p='.USER_PAGE);
+		}
+	}
+	
+	// LEVELLIST
+	$data['levels'] = array();
+	if (AdminServAdminLevel::hasLevel()) {
+		foreach (AdminLevelConfig::$ADMINLEVELS as $levelName => $levelData) {
+			$data['levels'][] = array(
+				'name' => $levelName,
+				'type' => $levelData['adminlevel']['type'],
+				'allowed_access' =>  count($levelData['access']).' '.Utils::t('authorized access'),
+				'allowed_permissions' => count($levelData['permission']).' '.Utils::t('authorized permissions'),
+			);
+		}
+	}
+	$data['count'] = count($data['levels']);
+?>
\ No newline at end of file
diff --git a/resources/process/config-levelsorder.php b/resources/process/config-levelsorder.php
new file mode 100644
index 0000000..334135d
--- /dev/null
+++ b/resources/process/config-levelsorder.php
@@ -0,0 +1,27 @@
+<?php
+	// ACTIONS
+	if( isset($_POST['save']) && isset($_POST['list']) && $_POST['list'] != null ){
+		$adminLevelList = AdminLevelConfig::$ADMINLEVELS;
+		$list = explode(',', $_POST['list']);
+		
+		$newAdminLevelList = array();
+		foreach($list as $listLevelName){
+			$newAdminLevelList[$listLevelName] = array(
+				'adminlevel' => $adminLevelList[$listLevelName]['adminlevel'],
+				'access' => $adminLevelList[$listLevelName]['access'],
+				'permission' => $adminLevelList[$listLevelName]['permission'],
+			);
+		}
+		
+		AdminServAdminLevel::saveConfig(array(), -1, $newAdminLevelList);
+		AdminServLogs::add('action', 'Order admin level list');
+		Utils::redirection(false, '?p='.USER_PAGE);
+	}
+	
+	
+	// LEVELLIST
+	$data['levels'] = array();
+	if (AdminServAdminLevel::hasLevel()) {
+		$data['levels'] = AdminLevelConfig::$ADMINLEVELS;
+	}
+?>
\ No newline at end of file
diff --git a/resources/process/config-password.php b/resources/process/config-password.php
new file mode 100644
index 0000000..6a232f0
--- /dev/null
+++ b/resources/process/config-password.php
@@ -0,0 +1,25 @@
+<?php
+	// ENREGISTREMENT
+	if( isset($_POST['savepassword']) ){
+		$current = md5($_POST['changePasswordCurrent']);
+		$new = md5($_POST['changePasswordNew']);
+		if( isset($_SESSION['adminserv']['path']) ){ $adminservPath = $_SESSION['adminserv']['path']; }else{ $adminservPath = null; }
+		$pathConfig = $adminservPath.'config/';
+		
+		if(OnlineConfig::PASSWORD !== $current){
+			AdminServ::error( Utils::t('The current password doesn\'t match.') );
+		}
+		else{
+			if( ($result = AdminServServerConfig::savePasswordConfig($pathConfig.'adminserv.cfg.php', $new)) !== true ){
+				AdminServ::error( Utils::t('Unable to save password.').' ('.$result.')');
+			}
+			else{
+				$info = Utils::t('The password has been changed.');
+				AdminServ::info($info);
+				AdminServLogs::add('action', $info);
+			}
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE);
+	}
+?>
\ No newline at end of file
diff --git a/resources/process/config-servers.php b/resources/process/config-servers.php
new file mode 100644
index 0000000..220fbe4
--- /dev/null
+++ b/resources/process/config-servers.php
@@ -0,0 +1,59 @@
+<?php
+	// EDITION
+	if( isset($_POST['editserver']) ){
+		$serverId = AdminServServerConfig::getServerId($_POST['server'][0]);
+		Utils::redirection(false, '?p=config-addserver&id='.$serverId);
+	}
+	
+	// DUPLIQUER
+	if( isset($_POST['duplicateserver']) ){
+		// GET
+		$getServerData = AdminServServerConfig::getServer($_POST['server'][0]);
+		
+		// SET
+		$setServerData = array(
+			'name' => trim( htmlspecialchars( addslashes($_POST['server'][0] . ' - '.Utils::t('copy') ) ) ),
+			'address' => trim($getServerData['address']),
+			'port' => intval($getServerData['port']),
+			'matchsettings' => trim($getServerData['matchsettings']),
+			'adminlevel' => array(
+				'SuperAdmin' => $getServerData['adminlevel']['SuperAdmin'],
+				'Admin' => $getServerData['adminlevel']['Admin'],
+				'User' => $getServerData['adminlevel']['User'],
+			),
+			'ds_pw' => trim($getServerData['ds_pw'])
+		);
+		if( AdminServServerConfig::saveServerConfig($setServerData) ){
+			$action = Utils::t('This server has been duplicated.');
+			AdminServ::info($action);
+			AdminServLogs::add('action', $action);
+			Utils::redirection(false, '?p='.USER_PAGE);
+		}
+		else{
+			AdminServ::error( Utils::t('Unable to duplicate server.') );
+		}
+	}
+	
+	// SUPPRESSION
+	if( isset($_POST['deleteserver']) ){
+		$servers = ServerConfig::$SERVERS;
+		unset($servers[$_POST['server'][0]]);
+		if( ($result = AdminServServerConfig::saveServerConfig(array(), -1, $servers)) !== true ){
+			AdminServ::error( Utils::t('Unable to delete server.').' ('.$result.')');
+		}
+		else{
+			$action = Utils::t('The "!serverName" server has been deleted.', array('!serverName' => $_POST['server'][0]));
+			AdminServ::info($action);
+			AdminServLogs::add('action', $action);
+			Utils::redirection(false, '?p='.USER_PAGE);
+		}
+	}
+	
+	// SERVERLIST
+	$data['servers'] = array();
+	if (is_array(ServerConfig::$SERVERS) && !empty(ServerConfig::$SERVERS)) {
+		$data['servers'] = ServerConfig::$SERVERS;
+	}
+	$data['count'] = count($data['servers']);
+	$data['adminLevelsType'] = AdminServAdminLevel::getDefaultType();
+?>
diff --git a/resources/process/config-serversorder.php b/resources/process/config-serversorder.php
new file mode 100644
index 0000000..08a7f8d
--- /dev/null
+++ b/resources/process/config-serversorder.php
@@ -0,0 +1,29 @@
+<?php
+	// ACTIONS
+	if( isset($_POST['save']) && isset($_POST['list']) && $_POST['list'] != null ){
+		$serverList = ServerConfig::$SERVERS;
+		$list = explode(',', $_POST['list']);
+		
+		$newServerList = array();
+		foreach($list as $listServerName){
+			$newServerList[$listServerName] = array(
+				'address' => $serverList[$listServerName]['address'],
+				'port' => $serverList[$listServerName]['port'],
+				'mapsbasepath' => (isset($serverList[$listServerName]['mapsbasepath'])) ? $serverList[$listServerName]['mapsbasepath'] : '',
+				'matchsettings' => $serverList[$listServerName]['matchsettings'],
+				'adminlevel' => $serverList[$listServerName]['adminlevel']
+			);
+		}
+		
+		AdminServServerConfig::saveServerConfig(array(), -1, $newServerList);
+		AdminServLogs::add('action', 'Order server list');
+		Utils::redirection(false, '?p='.USER_PAGE);
+	}
+	
+	
+	// SERVERLIST
+	$data['servers'] = array();
+	if (is_array(ServerConfig::$SERVERS) && !empty(ServerConfig::$SERVERS)) {
+		$data['servers'] = ServerConfig::$SERVERS;
+	}
+?>
\ No newline at end of file
diff --git a/resources/process/config.preprocess.php b/resources/process/config.preprocess.php
new file mode 100644
index 0000000..0c19fc8
--- /dev/null
+++ b/resources/process/config.preprocess.php
@@ -0,0 +1,25 @@
+<?php
+	// SESSION
+	if( !isset($_SESSION['adminserv']['allow_config_servers']) ){
+		AdminServ::error( Utils::t('You are not allowed to configure the servers') );
+		Utils::redirection();
+	}
+	
+	// VERIFICATION
+	if( class_exists('ServerConfig') ){
+		// Si on n'autorise pas la configuration en ligne
+		if( OnlineConfig::ACTIVATE !== true ){
+			AdminServ::info( Utils::t('No server available. To add one, configure "config/servers.cfg.php" file.') );
+			Utils::redirection();
+		}
+		elseif (USER_PAGE != 'config-addserver') {
+			if( OnlineConfig::ADD_ONLY === true ){
+				Utils::redirection(false, './?p=addserver');
+			}
+		}
+	}
+	else{
+		AdminServ::error( Utils::t('The servers configuration file isn\'t recognized by AdminServ.') );
+		Utils::redirection();
+	}
+?>
\ No newline at end of file
diff --git a/resources/process/connection.php b/resources/process/connection.php
new file mode 100644
index 0000000..f659251
--- /dev/null
+++ b/resources/process/connection.php
@@ -0,0 +1,69 @@
+<?php
+	// Si on demande le mot de passe pour la config en ligne
+	if( !isset($_SESSION['adminserv']['check_password']) && !isset($_SESSION['adminserv']['get_password']) ){
+		// On vérifie qu'une configuration existe, sinon on la créer
+		if( class_exists('ServerConfig') ){
+			// Si la configuration contient au moins 1 serveur et qu'il n'est pas l'exemple
+			if( AdminServServerConfig::hasServer() ){
+				// Connexion
+				if( isset($_POST['as_server']) && isset($_POST['as_password']) && isset($_POST['as_adminlevel']) ){
+					// Récupération des valeurs
+					$serverName = $_POST['as_server'];
+					$password = addslashes( htmlspecialchars( trim($_POST['as_password']) ) );
+					if(AdminServConfig::MD5_PASSWORD){
+						$password = md5($password);
+					}
+					$adminLevel = addslashes( htmlspecialchars($_POST['as_adminlevel']) );
+					
+					// Vérification des valeurs
+					if($password == null){
+						AdminServ::error( Utils::t('Please put a password.') );
+					}
+					else{
+						// Sessions & Cookies
+						$_SESSION['adminserv']['sid'] = AdminServServerConfig::getServerId($serverName);
+						$_SESSION['adminserv']['name'] = $serverName;
+						$_SESSION['adminserv']['password'] = $password;
+						$_SESSION['adminserv']['adminlevel'] = $adminLevel;
+						Utils::addCookieData('adminserv', array($_SESSION['adminserv']['sid'], $adminLevel), AdminServConfig::COOKIE_EXPIRE);
+						
+						// Redirection
+						if($_SESSION['adminserv']['sid'] != -1 && $_SESSION['adminserv']['name'] != null && $_SESSION['adminserv']['password'] != null && $_SESSION['adminserv']['adminlevel'] != null){
+							Utils::redirection();
+						}
+						else{
+							AdminServ::error( Utils::t('Connection error: invalid session.') );
+						}
+					}
+				}
+			}
+			else{
+				if(OnlineConfig::ACTIVATE === true){
+					Utils::redirection(false, './config/');
+				}
+				else{
+					AdminServ::info( Utils::t('No server available. To add one, configure "config/servers.cfg.php" file.') );
+				}
+			}
+		}
+		else{
+			if(OnlineConfig::ACTIVATE === true && !isset($_GET['error']) ){
+				Utils::redirection(false, './config/');
+			}
+			else{
+				AdminServ::error( Utils::t('The servers configuration file isn\'t recognized by AdminServ.') );
+			}
+		}
+	}
+	else if( isset($_SESSION['adminserv']['get_password']) ){
+		AdminServ::info( Utils::t('It\'s your first connection and no server configured. Choose a password to configure your servers.') );
+	}
+	
+	// HTML
+	if( isset($_GET['error']) ){
+		AdminServ::error($_GET['error']);
+	}
+	else if( isset($_GET['info']) ){
+		AdminServ::info($_GET['info']);
+	}
+?>
\ No newline at end of file
diff --git a/resources/process/gameinfos.php b/resources/process/gameinfos.php
new file mode 100644
index 0000000..763d76a
--- /dev/null
+++ b/resources/process/gameinfos.php
@@ -0,0 +1,88 @@
+<?php
+	// ENREGISTREMENT
+	if( isset($_POST['savegameinfos']) ){
+		// Variables
+		$struct = AdminServ::getGameInfosStructFromPOST();
+		
+		// Requêtes
+		if(!$client->query('SetGameInfos', $struct) && $client->getErrorMessage() != 'Script not allowed for this title.'){
+			AdminServ::error();
+		}
+		else{
+			// Team info
+			if(SERVER_VERSION_NAME == 'ManiaPlanet' && isset($_POST['teamInfo1Name']) ){
+				$team1 = array(
+					'name' => $_POST['teamInfo1Name'],
+					'color' => $_POST['teamInfo1Color'],
+					'colorhex' => $_POST['teamInfo1ColorHex'],
+					'country' => $_POST['teamInfo1Country']
+				);
+				$team2 =  array(
+					'name' => $_POST['teamInfo2Name'],
+					'color' => $_POST['teamInfo2Color'],
+					'colorhex' => $_POST['teamInfo2ColorHex'],
+					'country' => $_POST['teamInfo2Country']
+				);
+				
+				AdminServ::setTeamInfo($team1, $team2);
+			}
+			
+			// RoundCustomPoints
+			if( isset($_POST['NextRoundCustomPoints']) && $_POST['NextRoundCustomPoints'] != null){
+				$NextRoundCustomPoints = explode(',', $_POST['NextRoundCustomPoints']);
+				$NextRoundCustomPointsArray = array();
+				if( count($NextRoundCustomPoints) > 0 ){
+					foreach($NextRoundCustomPoints as $point){
+						$NextRoundCustomPointsArray[] = intval( trim($point) );
+					}
+				}
+				if( !$client->query('SetRoundCustomPoints', $NextRoundCustomPointsArray) ){
+					AdminServ::error();
+				}
+			}
+			
+			// MatchSettings
+			if(SERVER_MATCHSET){
+				$mapsDirectory = AdminServ::getMapsDirectoryPath();
+				if( array_key_exists('SaveCurrentMatchSettings', $_POST) ){
+					if( !$client->query('SaveMatchSettings', $mapsDirectory . SERVER_MATCHSET) ){
+						AdminServ::error();
+					}
+				}
+			}
+			
+			AdminServLogs::add('action', 'Save game infos');
+			Utils::redirection(false, '?p='.USER_PAGE);
+		}
+	}
+	
+	
+	// LECTURE
+	$gameInfos = AdminServ::getGameInfos();
+	$data['gameInfos'] = array(
+		'curr' => $gameInfos['curr'],
+		'next' => $gameInfos['next']
+	);
+	$data['teamInfo'] = array(
+		'team1' => array(
+			'name' => Utils::t('Blue'),
+			'color' => '0.667',
+			'colorhex' => '#0000ff',
+			'country' => 'World|France'
+		),
+		'team2' => array(
+			'name' => Utils::t('Red'),
+			'color' => '0',
+			'colorhex' => '#ff0000',
+			'country' => 'World|France'
+		)
+	);
+	if( isset($_SESSION['adminserv']['teaminfo']) && count($_SESSION['adminserv']['teaminfo']) > 0 ){
+		$data['teamInfo'] = array(
+			'team1' => $_SESSION['adminserv']['teaminfo']['team1'],
+			'team2' => $_SESSION['adminserv']['teaminfo']['team2']
+		);
+	}
+	
+	unset($gameInfos);
+?>
\ No newline at end of file
diff --git a/resources/process/general.php b/resources/process/general.php
new file mode 100644
index 0000000..644eeec
--- /dev/null
+++ b/resources/process/general.php
@@ -0,0 +1,154 @@
+<?php
+	// ACTIONS
+	if( isset($_GET['stop']) ){
+		if( !$client->query('StopServer') ){
+			AdminServ::error();
+		}
+		else{
+			$client->Terminate();
+			Utils::redirection(false, '?logout');
+		}
+	}
+	else if( isset($_POST['BanLoginList']) && count($_POST['player']) > 0 ){
+		foreach($_POST['player'] as $player){
+			if( !$client->query('Ban', $player) ){
+				AdminServ::error();
+				break;
+			}
+			else{
+				AdminServLogs::add('action', 'Ban player: '.$player);
+			}
+		}
+	}
+	else if( isset($_POST['KickLoginList']) && count($_POST['player']) > 0 ){
+		foreach($_POST['player'] as $player){
+			if( !$client->query('Kick', $player) ){
+				AdminServ::error();
+				break;
+			}
+			else{
+				AdminServLogs::add('action', 'Kick player: '.$player);
+			}
+		}
+	}
+	else if( isset($_POST['IgnoreLoginList']) && count($_POST['player']) > 0 ){
+		foreach($_POST['player'] as $player){
+			if( !$client->query('Ignore', $player) ){
+				AdminServ::error();
+				break;
+			}
+			else{
+				AdminServLogs::add('action', 'Ignore player: '.$player);
+			}
+		}
+	}
+	else if( isset($_POST['GuestLoginList']) && count($_POST['player']) > 0 ){
+		foreach($_POST['player'] as $player){
+			if( !$client->query('AddGuest', $player) ){
+				AdminServ::error();
+				break;
+			}
+			else{
+				AdminServLogs::add('action', 'Add Guest player: '.$player);
+			}
+		}
+	}
+	else if( isset($_POST['ForcePlayerList']) && count($_POST['player']) > 0 ){
+		foreach($_POST['player'] as $player){
+			if( !$client->query('ForceSpectator', $player, 2) ){
+				AdminServ::error();
+				break;
+			}
+			else{
+				if( !$client->query('ForceSpectator', $player, 0) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Force player mode: '.$player);
+				}
+			}
+		}
+	}
+	else if( isset($_POST['ForceSpectatorList']) && count($_POST['player']) > 0 ){
+		foreach($_POST['player'] as $player){
+			if( !$client->query('ForceSpectator', $player, 1) ){
+				AdminServ::error();
+				break;
+			}
+			else{
+				if(!$client->query('ForceSpectator', $player, 0) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Force spectator mode: '.$player);
+				}
+			}
+		}
+	}
+	else if( (isset($_POST['ForceBlueTeam']) || isset($_POST['ForceRedTeam'])) && count($_POST['player']) > 0 ){
+		if( isset($_POST['ForceBlueTeam']) ){
+			$teamId = 0;
+		}else{
+			$teamId = 1;
+		}
+		
+		foreach($_POST['player'] as $player){
+			if( !$client->query('ForcePlayerTeam', $player, $teamId) ){
+				AdminServ::error();
+				break;
+			}
+			else{
+				if($teamId == 0){ $color = 'blue'; }else{ $color = 'red'; }
+				AdminServLogs::add('action', 'Force player in '.$color.' team: '.$player);
+			}
+		}
+	}
+	else if( isset($_POST['ForceScores']) && isset($_POST['ScoreTeamBlue']) && isset($_POST['ScoreTeamRed']) ){
+		$scoreTeamBlue = intval($_POST['ScoreTeamBlue']);
+		$scoreTeamRed = intval($_POST['ScoreTeamRed']);
+		$scores = array(
+			array(
+				'PlayerId' => 0,
+				'Score' => $scoreTeamBlue
+			),
+			array(
+				'PlayerId' => 1,
+				'Score' => $scoreTeamRed
+			)
+		);
+		if( !$client->query('ForceScores', $scores, true) ){
+			AdminServ::error();
+		}else{
+			$action = '[Admin] '.Utils::t('The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed', array('!scoreTeamBlue' => $scoreTeamBlue, '!scoreTeamRed' => $scoreTeamRed));
+			if( !$client->query('ChatSendServerMessage', $action) ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', $action);
+			}
+		}
+	}
+	else if( isset($_POST['CancelVote']) ){
+		if( !$client->query('CancelVote') ){
+			AdminServ::error();
+		}
+		else{
+			Utils::redirection();
+		}
+	}
+	
+	
+	// Info serveur
+	$data['serverInfo'] = AdminServ::getCurrentServerInfo();
+	$data['isTeamGameMode'] = AdminServ::checkDisplayTeamMode($data['serverInfo']['srv']['gameModeId'], $data['serverInfo']['srv']['gameModeScriptName']);
+	// Si on est en mode équipe, on force l'affichage en mode détail
+	if($data['isTeamGameMode']){
+		$_SESSION['adminserv']['mode']['general'] = 'detail';
+	}
+	if( defined('IS_RELAY') && IS_RELAY ){
+		// @deprecated $mainServerLogin = AdminServ::getMainServerLoginFromRelay();
+		$data['mainServerLogin'] = null;
+	}
+?>
\ No newline at end of file
diff --git a/resources/process/guestban.php b/resources/process/guestban.php
new file mode 100644
index 0000000..cc5da2f
--- /dev/null
+++ b/resources/process/guestban.php
@@ -0,0 +1,297 @@
+<?php
+	// GAMEDATA
+	if( AdminServAdminLevel::isType('Admin') ){
+		if( !$client->query('GameDataDirectory') ){
+			AdminServ::error();
+		}
+		else{
+			$data['gameDataDirectory'] = $client->getResponse();
+			$data['playlistDirectory'] = Folder::read($data['gameDataDirectory'].'Config', array(), array(), intval(AdminServConfig::RECENT_STATUS_PERIOD * 3600) );
+		}
+	}
+	
+	// ACTIONS
+	// Vider la liste
+	if( isset($_GET['clean']) ){
+		$clean = strtolower($_GET['clean']);
+		if($clean == 'banlist'){
+			if( !$client->query('CleanBanList') ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', 'Clean banlist');
+			}
+		}
+		else if($clean == 'ignorelist'){
+			if( !$client->query('CleanIgnoreList') ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', 'Clean ignorelist');
+			}
+		}
+		else if($clean == 'guestlist'){
+			if( !$client->query('CleanGuestList') ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', 'Clean guestlist');
+			}
+		}
+		else if($clean == 'blacklist'){
+			if( !$client->query('CleanBlackList') ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', 'Clean blacklist');
+			}
+		}
+	}
+	// Blacklister
+	else if( isset($_POST['blackListPlayer']) ){
+		// Création du tableau de joueurs à blacklister
+		$blackListPlayer = array();
+		if( isset($_POST['banlist']) && count($_POST['banlist']) > 0 ){
+			$blackListPlayer = array_merge($blackListPlayer, $_POST['banlist']);
+		}
+		if( isset($_POST['guestlist']) && count($_POST['guestlist']) > 0 ){
+			$blackListPlayer = array_merge($blackListPlayer, $_POST['guestlist']);
+		}
+		if( isset($_POST['ignorelist']) && count($_POST['ignorelist']) > 0 ){
+			$blackListPlayer = array_merge($blackListPlayer, $_POST['ignorelist']);
+		}
+		$blackListPlayer = array_unique($blackListPlayer);
+		
+		// BlackList de toutes les listes
+		if( count($blackListPlayer) > 0 ){
+			foreach($blackListPlayer as $player){
+				if( !$client->query('BlackList', $player) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Blacklist player: '.$player);
+				}
+			}
+		}
+	}
+	// Retirer un joueur d'une ou plusieurs listes
+	else if( isset($_POST['removeList']) ){
+		if( isset($_POST['banlist']) && count($_POST['banlist']) > 0 ){
+			foreach($_POST['banlist'] as $player){
+				if( !$client->query('UnBan', $player) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Unban player: '.$player);
+				}
+			}
+		}
+		else if( isset($_POST['blacklist']) && count($_POST['blacklist']) > 0 ){
+			foreach($_POST['blacklist'] as $player){
+				if( !$client->query('UnBlackList', $player) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Unblacklist player: '.$player);
+				}
+			}
+		}
+		else if( isset($_POST['guestlist']) && count($_POST['guestlist']) > 0 ){
+			foreach($_POST['guestlist'] as $player){
+				if( !$client->query('RemoveGuest', $player) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Remove guest player: '.$player);
+				}
+			}
+		}
+		else if( isset($_POST['ignorelist']) && count($_POST['ignorelist']) > 0 ){
+			foreach($_POST['ignorelist'] as $player){
+				if( !$client->query('UnIgnore', $player) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Unignore player: '.$player);
+				}
+			}
+		}
+	}
+	
+	
+	// AJOUTER
+	else if( isset($_POST['addPlayer']) ){
+		// Variables
+		$addPlayerList = $_POST['addPlayerList'];
+		$addPlayerLogin = strtolower( trim($_POST['addPlayerLogin']) );
+		$addPlayerTypeList = $_POST['addPlayerTypeList'];
+		
+		// PlayerLogin
+		if($addPlayerList != 'none' && $addPlayerList != 'more'){
+			$playerlogin = $addPlayerList;
+		}else{
+			$playerlogin = $addPlayerLogin;
+		}
+		
+		// Requête
+		if($playerlogin != Utils::t('Player login') ){
+			// Inviter
+			if($addPlayerTypeList == 'guestlist'){
+				if( !$client->query('AddGuest', $playerlogin) ){
+					AdminServ::error();
+				}
+				else{
+					AdminServLogs::add('action', 'Add guest player: '.$playerlogin);
+				}
+			}
+			// Blacklister
+			else if($addPlayerTypeList == 'blacklist'){
+				if( !$client->query('BlackList', $playerlogin) ){
+					AdminServ::error();
+				}
+				else{
+					AdminServLogs::add('action', 'Add blacklist player: '.$playerlogin);
+				}
+			}
+		}
+	}
+	
+	
+	// PLAYLISTS LOCAL
+	else if( isset($_POST['savePlaylist']) && isset($_POST['playlist']) && count($_POST['playlist'] > 0) ){
+		$i = 0;
+		foreach($_POST['playlist'] as $playlist){
+			$playlistEx = explode('|', $playlist);
+			$type = $playlistEx[0];
+			$filename = $playlistEx[1];
+			
+			// Guestlist
+			if($type == 'guestlist'){
+				if( !$client->query('SaveGuestList', $filename) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Save guestlist');
+				}
+			}
+			// BlackList
+			elseif($type == 'blacklist'){
+				if( !$client->query('SaveBlackList', $filename) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Save blacklist');
+				}
+			}
+			$i++;
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE);
+	}
+	else if( isset($_POST['loadPlaylist']) && isset($_POST['playlist']) && count($_POST['playlist'] > 0) ){
+		$i = 0;
+		foreach($_POST['playlist'] as $playlist){
+			$playlistEx = explode('|', $playlist);
+			$type = $playlistEx[0];
+			$filename = $playlistEx[1];
+			
+			// Guestlist
+			if($type == 'guestlist'){
+				if( !$client->query('LoadGuestList', $filename) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Load guestlist');
+				}
+			}
+			// BlackList
+			elseif($type == 'blacklist'){
+				if( !$client->query('LoadBlackList', $filename) ){
+					AdminServ::error();
+					break;
+				}
+				else{
+					AdminServLogs::add('action', 'Load blacklist');
+				}
+			}
+			$i++;
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE);
+	}
+	else if( isset($_POST['deletePlaylist']) && isset($_POST['playlist']) && count($_POST['playlist'] > 0) ){
+		foreach($_POST['playlist'] as $playlist){
+			$playlistEx = explode('|', $playlist);
+			$filename = $playlistEx[1];
+			
+			if( !File::delete($data['gameDataDirectory'].'Config/'.$filename) ){
+				AdminServ::error(Utils::t('Unable to delete the playlist').' : '.$filename);
+				break;
+			}
+			else{
+				AdminServLogs::add('action', 'Delete playlist: '.$filename);
+			}
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE);
+	}
+	else if( isset($_POST['createPlaylistValid']) && isset($_POST['createPlaylistName']) && $_POST['createPlaylistName'] != null ){
+		// Fichier
+		$filename = Str::replaceChars($_POST['createPlaylistName']);
+		
+		// Guestlist
+		if( $filename != Str::replaceChars(Utils::t('Playlist name')) ){
+			if($_POST['createPlaylistType'] == 'guestlist'){
+				if( !$client->query('SaveGuestList', $filename) ){
+					AdminServ::error();
+				}
+				else{
+					AdminServLogs::add('action', 'Create playlist (guestlist): '.$filename);
+				}
+			}
+			// Blacklist
+			elseif($_POST['createPlaylistType'] == 'blacklist'){
+				if( !$client->query('SaveBlackList', $filename) ){
+					AdminServ::error();
+				}
+				else{
+					AdminServLogs::add('action', 'Create playlist (blacklist): '.$filename);
+				}
+			}
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE);
+	}
+	
+	// LECTURE
+	$client->addCall('GetBanList', array(AdminServConfig::LIMIT_PLAYERS_LIST, 0) );
+	$client->addCall('GetBlackList', array(AdminServConfig::LIMIT_PLAYERS_LIST, 0) );
+	$client->addCall('GetGuestList', array(AdminServConfig::LIMIT_PLAYERS_LIST, 0) );
+	$client->addCall('GetIgnoreList', array(AdminServConfig::LIMIT_PLAYERS_LIST, 0) );
+	if( !$client->multiquery() ){
+		AdminServ::error();
+	}
+	else{
+		$queriesData = $client->getMultiqueryResponse();
+		$data['banlist']['list'] = $queriesData['GetBanList'];
+		$data['blacklist']['list'] = $queriesData['GetBlackList'];
+		$data['guestlist']['list'] = $queriesData['GetGuestList'];
+		$data['ignorelist']['list'] = $queriesData['GetIgnoreList'];
+		$data['banlist']['count'] = count($data['banlist']['list']);
+		$data['blacklist']['count'] = count($data['blacklist']['list']);
+		$data['guestlist']['count'] = count($data['guestlist']['list']);
+		$data['ignorelist']['count'] = count($data['ignorelist']['list']);
+	}
+	
+	// Liste des joueurs présent sur le serveur
+	$data['players']['listOptions'] = AdminServUI::getPlayerList();
+	$data['players']['count'] = AdminServ::getNbPlayers();
+?>
\ No newline at end of file
diff --git a/resources/process/maps-creatematchset.php b/resources/process/maps-creatematchset.php
new file mode 100644
index 0000000..a223880
--- /dev/null
+++ b/resources/process/maps-creatematchset.php
@@ -0,0 +1,157 @@
+<?php
+	// ENREGISTREMENT
+	if( isset($_POST['savematchsetting']) && isset($_SESSION['adminserv']['matchset_maps_selected']) ){
+		// Filename
+		$matchSettingName = Str::replaceChars($_POST['matchSettingName']);
+		$filename = $data['mapsDirectoryPath'].$args['directory'].$matchSettingName;
+		if(File::getExtension($matchSettingName) != 'txt'){
+			$filename .= '.txt';
+		}
+		
+		$struct = array();
+		
+		// Gameinfos
+		$gameinfos = AdminServ::getGameInfosStructFromPOST();
+		$struct['gameinfos'] = array(
+			'game_mode' => $gameinfos['GameMode'],
+			'chat_time' => $gameinfos['ChatTime'],
+			'finishtimeout' => $gameinfos['FinishTimeout'],
+			'allwarmupduration' => $gameinfos['AllWarmUpDuration'],
+			'disablerespawn' => $gameinfos['DisableRespawn'],
+			'forceshowallopponents' => $gameinfos['ForceShowAllOpponents'],
+			'rounds_pointslimit' => $gameinfos['RoundsPointsLimit'],
+			'rounds_custom_points' => $gameinfos['RoundCustomPoints'],
+			'rounds_usenewrules' => $gameinfos['RoundsUseNewRules'],
+			'rounds_forcedlaps' => $gameinfos['RoundsForcedLaps'],
+			'rounds_pointslimitnewrules' => $gameinfos['RoundsPointsLimitNewRules'],
+			'team_pointslimit' => $gameinfos['TeamPointsLimit'],
+			'team_maxpoints' => $gameinfos['TeamMaxPoints'],
+			'team_usenewrules' => $gameinfos['TeamUseNewRules'],
+			'team_pointslimitnewrules' => $gameinfos['TeamPointsLimitNewRules'],
+			'timeattack_limit' => $gameinfos['TimeAttackLimit'],
+			'timeattack_synchstartperiod' => $gameinfos['TimeAttackSynchStartPeriod'],
+			'laps_nblaps' => $gameinfos['LapsNbLaps'],
+			'laps_timelimit' => $gameinfos['LapsTimeLimit'],
+			'cup_pointslimit' => $gameinfos['CupPointsLimit'],
+			'cup_roundsperchallenge' => $gameinfos['CupRoundsPerMap'],
+			'cup_nbwinners' => $gameinfos['CupNbWinners'],
+			'cup_warmupduration' => $gameinfos['CupWarmUpDuration']
+		);
+		if(SERVER_VERSION_NAME != 'TmForever'){
+			$struct['gameinfos']['script_name'] = $gameinfos['ScriptName'];
+		}
+		
+		// HotSeat
+		$struct['hotseat'] = array(
+			'game_mode' => intval($_POST['hotSeatGameMode']),
+			'time_limit' => TimeDate::secToMillisec( intval($_POST['hotSeatTimeLimit']) ),
+			'rounds_count' => intval($_POST['hotSeatCountRound'])
+		);
+		
+		// Filter
+		$struct['filter'] = array(
+			'is_lan' => array_key_exists('filterIsLan', $_POST),
+			'is_internet' => array_key_exists('filterIsInternet', $_POST),
+			'is_solo' => array_key_exists('filterIsSolo', $_POST),
+			'is_hotseat' => array_key_exists('filterIsHotSeat', $_POST),
+			'sort_index' => intval($_POST['filterSortIndex']),
+			'random_map_order' => array_key_exists('filterRandomMaps', $_POST),
+			'force_default_gamemode' => intval($_POST['filterDefaultGameMode']),
+		);
+		
+		// ScriptSettings
+		if( !$client->query('GetModeScriptInfo') ){
+			AdminServ::error();
+		}
+		else{
+			$scriptsettings = $client->getResponse();
+			
+			if( !empty($scriptsettings['ParamDescs']) ){
+				foreach($scriptsettings['ParamDescs'] as $param){
+					$struct['scriptsettings'][] = array(
+						'name' => $param['Name'],
+						'type' => $param['Type'],
+						'value' => $param['Default']
+					);
+				}
+			}
+		}
+		
+		// Maps
+		$struct['startindex'] = 1;
+		$maps = $_SESSION['adminserv']['matchset_maps_selected']['lst'];
+		if( isset($maps) && is_array($maps) && !empty($maps) ){
+			$mapsField = (SERVER_VERSION_NAME == 'TmForever') ? 'challenge' : 'map';
+			foreach($maps as $id => $values){
+				$struct[$mapsField][$values['UId']] = $values['FileName'];
+			}
+		}
+		
+		
+		// Enregistrement
+		if( ($result = AdminServ::saveMatchSettings($filename, $struct)) !== true ){
+			AdminServ::error(Utils::t('Unable to save the MatchSettings').' : '.$matchSettingName.' ('.$result.')');
+		}
+		else{
+			$action = Utils::t('The MatchSettings "!matchSettingName" was successfully created in the folder', array('!matchSettingName' => $matchSettingName)).' : '.$data['mapsDirectoryPath'].$args['directory'];
+			AdminServ::info($action);
+			AdminServLogs::add('action', $action);
+			Utils::redirection(false, '?p='.USER_PAGE .$hasDirectory);
+		}
+	}
+	else{
+		if( !isset($_GET['f']) ){
+			unset($_SESSION['adminserv']['matchset_maps_selected']);
+		}
+	}
+	
+	
+	// LECTURE
+	$data['directoryList'] = Folder::getArborescence($data['mapsDirectoryPath'], AdminServConfig::$MAPS_HIDDEN_FOLDERS, substr_count($data['mapsDirectoryPath'], '/'));
+	$data['matchSettings'] = array();
+	// Édition
+	if( isset($_GET['f']) && $_GET['f'] != null ){
+		$data['pageTitle'] = Utils::t('Edit');
+		$data['matchSettings']['name'] = $_GET['f'];
+		$matchSettingsData = AdminServ::getMatchSettingsData($data['mapsDirectoryPath'].$args['directory'].$data['matchSettings']['name']);
+		$data['gameInfos'] = array(
+			'curr' => null,
+			'next' => $matchSettingsData['gameinfos']
+		);
+		unset($matchSettingsData['gameinfos']);
+		$data['matchSettings'] += $matchSettingsData;
+		if( isset($data['matchSettings']['maps']) ){
+			$maps = AdminServ::getMapListFromMatchSetting($data['matchSettings']['maps']);
+			$data['matchSettings']['nbm'] = $maps['nbm']['count'];
+			$_SESSION['adminserv']['matchset_maps_selected'] = $maps;
+		}
+		else{
+			$data['matchSettings']['nbm'] = 0;
+		}
+	}
+	else{
+		$data['pageTitle'] = Utils::t('Create');
+		$data['matchSettings']['name'] = 'match_settings';
+		$gameInfos = AdminServ::getGameInfos();
+		$data['gameInfos'] = array(
+			'curr' => null,
+			'next' => $gameInfos['next']
+		);
+		$data['matchSettings']['hotseat'] = array(
+			'GameMode' => 1,
+			'TimeLimit' => 300000,
+			'RoundsCount' => 5
+		);
+		$data['matchSettings']['filter'] = array(
+			'IsLan' => 1,
+			'IsInternet' => 1,
+			'IsSolo' => 0,
+			'IsHotseat' => 1,
+			'SortIndex' => 1000,
+			'RandomMapOrder' => 0,
+			'ForceDefaultGameMode' => 1
+		);
+		$data['matchSettings']['StartIndex'] = 0;
+		$data['matchSettings']['nbm'] = 0;
+	}
+?>
\ No newline at end of file
diff --git a/resources/process/maps-list.php b/resources/process/maps-list.php
new file mode 100644
index 0000000..a589e4a
--- /dev/null
+++ b/resources/process/maps-list.php
@@ -0,0 +1,38 @@
+<?php
+	// GAME
+	if(SERVER_VERSION_NAME == 'TmForever'){
+		$queries = array(
+			'removeMap' => 'RemoveChallengeList',
+			'chooseNextMap' => 'ChooseNextChallengeList'
+		);
+	}
+	else{
+		$queries = array(
+			'removeMap' => 'RemoveMapList',
+			'chooseNextMap' => 'ChooseNextMapList'
+		);
+	}
+	
+	// ACTIONS
+	if( isset($_POST['removeMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
+		if( !$client->query($queries['removeMap'], $_POST['map']) ){
+			AdminServ::error();
+		}
+		else{
+			AdminServLogs::add('action', 'Remove map ('.count($_POST['map']).')');
+			Utils::redirection(false, '?p='.USER_PAGE);
+		}
+	}
+	else if( isset($_POST['chooseNextMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
+		if( !$client->query($queries['chooseNextMap'], $_POST['map']) ){
+			AdminServ::error();
+		}
+		else{
+			AdminServLogs::add('action', 'Choose next map ('.count($_POST['map']).')');
+			Utils::redirection(false, '?p='.USER_PAGE);
+		}
+	}
+	
+	// MAPLIST
+	$data['maps'] = AdminServ::getMapList();
+?>
\ No newline at end of file
diff --git a/resources/process/maps-local.php b/resources/process/maps-local.php
new file mode 100644
index 0000000..af8d28f
--- /dev/null
+++ b/resources/process/maps-local.php
@@ -0,0 +1,149 @@
+<?php
+	// GAME VERSION
+	if(SERVER_VERSION_NAME == 'TmForever'){
+		$queries = array(
+			'insert' => 'InsertChallenge',
+			'add' => 'AddChallenge'
+		);
+	}
+	else{
+		$queries = array(
+			'insert' => 'InsertMap',
+			'add' => 'AddMap'
+		);
+	}
+	
+	// ACTIONS
+	if( isset($_POST['addMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
+		foreach($_POST['map'] as $map){
+			if( !$client->query($queries['add'], $data['mapsDirectoryPath'].$map) ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', 'Add map: '.$map);
+			}
+		}
+	}
+	else if( isset($_POST['insertMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
+		foreach($_POST['map'] as $map){
+			if( !$client->query($queries['insert'], $data['mapsDirectoryPath'].$map) ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', 'Insert map: '.$map);
+			}
+		}
+	}
+	else if( isset($_POST['downloadMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
+		// Si on télécharge plusieurs fichiers, on envoi un zip
+		$countMaps = count($_POST['map']);
+		if($countMaps > 1){
+			$struct = array();
+			foreach($_POST['map'] as $map){
+				$struct[] = $data['mapsDirectoryPath'].$map;
+			}
+			$zipError = null;
+			$zipFileName = 'maps.zip';
+			if( !Zip::create($zipFileName, $struct, $zipError) ){
+				AdminServ::error($zipError);
+			}
+			else{
+				File::download($zipFileName);
+				AdminServLogs::add('action', 'Download packmap ('.$countMaps.' maps)');
+				if( $result = File::delete($zipFileName) !== true ){
+					AdminServ::error($result);
+				}
+			}
+		}
+		// Sinon on envoi le fichier seul
+		else{
+			File::download($data['mapsDirectoryPath'].$_POST['map'][0]);
+			AdminServLogs::add('action', 'Download map: '.$_POST['map'][0]);
+		}
+	}
+	else if( isset($_POST['renameMapValid']) && isset($_POST['map']) && count($_POST['map']) > 0 && isset($_POST['renameMapList']) && count($_POST['renameMapList']) > 0 ){
+		$i = 0;
+		foreach($_POST['renameMapList'] as $newMapName){
+			$result = File::rename($data['mapsDirectoryPath'].$_POST['map'][$i], $data['mapsDirectoryPath'].$args['directory'].$newMapName);
+			if($result !== true ){
+				AdminServ::error(Utils::t('Unable to rename the map').' : '.$newMapName.' ('.$result.')');
+				break;
+			}
+			else{
+				AdminServLogs::add('action', 'Rename map: '.$_POST['map'][$i].' to '.$newMapName);
+			}
+			$i++;
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE .$hasDirectory);
+	}
+	else if( isset($_POST['renameAutoValid']) && isset($_POST['map']) && count($_POST['map']) > 0 && isset($_POST['renameMapList']) && count($_POST['renameMapList']) > 0 ){
+		$i = 0;
+		foreach($_POST['renameMapList'] as $newMapName){
+			$result = File::rename($data['mapsDirectoryPath'].$_POST['map'][$i], $data['mapsDirectoryPath'].$args['directory'].Str::replaceChars($newMapName));
+			if($result !== true){
+				AdminServ::error(Utils::t('Unable to rename the map').' : '.$newMapName.' ('.$result.')');
+				break;
+			}
+			else{
+				AdminServLogs::add('action', 'Rename map (auto): '.$_POST['map'][$i].' to '.$newMapName);
+			}
+			$i++;
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE .$hasDirectory);
+	}
+	else if( isset($_POST['moveMapValid']) && isset($_POST['moveDirectoryList']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
+		// Chemin
+		if($_POST['moveDirectoryList'] == '.'){
+			$newPath = $data['mapsDirectoryPath'];
+		}
+		else{
+			$newPath = $_POST['moveDirectoryList'];
+		}
+		
+		// Déplacement
+		foreach($_POST['map'] as $map){
+			$result = File::rename($data['mapsDirectoryPath'].$map, $newPath.basename($map) );
+			if($result !== true ){
+				AdminServ::error(Utils::t('Unable to move the map').' : '.$map.' ('.$result.')');
+				break;
+			}
+			else{
+				AdminServLogs::add('action', 'Move map: '.$map.' to '.$newPath.basename($map) );
+			}
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE .$hasDirectory);
+	}
+	else if( isset($_POST['deleteMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
+		foreach($_POST['map'] as $map){
+			$result = File::delete($data['mapsDirectoryPath'].$map);
+			if($result !== true){
+				AdminServ::error(Utils::t('Unable to delete the map').' : '.$map.' ('.$result.')');
+				break;
+			}
+			else{
+				AdminServLogs::add('action', 'Delete map: '.$map);
+			}
+		}
+		
+		Utils::redirection(false, '?p='.USER_PAGE .$hasDirectory);
+	}
+	// Save MatchSettings
+	if( (isset($_POST['addMap']) || isset($_POST['insertMap'])) && SERVER_MATCHSET ){
+		if( isset($_POST['SaveCurrentMatchSettings']) && array_key_exists('SaveCurrentMatchSettings', $_POST) ){
+			if( !$client->query('SaveMatchSettings', $data['mapsDirectoryPath'] . SERVER_MATCHSET) ){
+				AdminServ::error();
+			}
+		}
+	}
+	
+	
+	// MAPLIST
+	$sort = null;
+	if( isset($_GET['sort']) && $_GET['sort'] != null){
+		$sort = addslashes($_GET['sort']);
+	}
+	$data['maps'] = AdminServ::getLocalMapList($data['currentDir'], $args['directory'], $sort);
+?>
\ No newline at end of file
diff --git a/resources/process/maps-matchset.php b/resources/process/maps-matchset.php
new file mode 100644
index 0000000..777d4ad
--- /dev/null
+++ b/resources/process/maps-matchset.php
@@ -0,0 +1,67 @@
+<?php
+	// ACTIONS
+	if( isset($_POST['saveMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
+		foreach($_POST['matchset'] as $matchset){
+			if( !$client->query('SaveMatchSettings', $data['mapsDirectoryPath'].$matchset) ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', 'Save matchsettings: '.$matchset);
+			}
+		}
+		Utils::redirection(false, '?p='.USER_PAGE.$data['hasDirectory']);
+	}
+	else if( isset($_POST['loadMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
+		foreach($_POST['matchset'] as $matchset){
+			if( !$client->query('LoadMatchSettings', $data['mapsDirectoryPath'].$matchset) ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', 'Load matchsettings: '.$matchset);
+			}
+		}
+		Utils::redirection(false, '?p='.USER_PAGE.$data['hasDirectory']);
+	}
+	else if( isset($_POST['addMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
+		foreach($_POST['matchset'] as $matchset){
+			if( !$client->query('AppendPlaylistFromMatchSettings', $data['mapsDirectoryPath'].$matchset) ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', 'Append playlist from matchsettings: '.$matchset);
+			}
+		}
+	Utils::redirection(false, '?p='.USER_PAGE.$data['hasDirectory']);
+	}
+	else if( isset($_POST['insertMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
+		foreach($_POST['matchset'] as $matchset){
+			if( !$client->query('InsertPlaylistFromMatchSettings', $data['mapsDirectoryPath'].$matchset) ){
+				AdminServ::error();
+			}
+			else{
+				AdminServLogs::add('action', 'Insert playlist from matchsettings: '.$matchset);
+			}
+		}
+		Utils::redirection(false, '?p='.USER_PAGE.$data['hasDirectory']);
+	}
+	else if( isset($_POST['editMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
+		AdminServLogs::add('action', 'Edit matchsettings: '.$_POST['matchset'][0]);
+		// Redirection sur la page de création d'un matchsettings
+		Utils::redirection(false, '?p=maps-creatematchset'.$data['hasDirectory'].'&f='.$_POST['matchset'][0]);
+	}
+	else if( isset($_POST['deleteMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
+		foreach($_POST['matchset'] as $matchset){
+			if( !File::delete($data['mapsDirectoryPath'].$matchset) ){
+				AdminServ::error(Utils::t('Unable to delete the playlist').' : '.$matchset);
+			}
+			else{
+				AdminServLogs::add('action', 'Delete matchsettings: '.$matchset);
+			}
+		}
+		Utils::redirection(false, '?p='.USER_PAGE.$data['hasDirectory']);
+	}
+	
+	
+	// MATCH SETTINGS LIST
+	$data['matchsettingsList'] = AdminServ::getLocalMatchSettingList($data['currentDir'], $args['directory']);
+?>
\ No newline at end of file
diff --git a/resources/process/maps-order.php b/resources/process/maps-order.php
new file mode 100644
index 0000000..6783f6a
--- /dev/null
+++ b/resources/process/maps-order.php
@@ -0,0 +1,31 @@
+<?php
+	// GAME VERSION
+	if(SERVER_VERSION_NAME == 'TmForever'){
+		$queries = array(
+			'chooseNextMap' => 'ChooseNextChallengeList'
+		);
+	}
+	else{
+		$queries = array(
+			'chooseNextMap' => 'ChooseNextMapList'
+		);
+	}
+	
+	// ACTIONS
+	if( isset($_POST['save']) && isset($_POST['list']) && $_POST['list'] != null ){
+		$list = explode(',', $_POST['list']);
+		
+		if( !$client->query($queries['chooseNextMap'], $list) ){
+			AdminServ::error();
+		}
+		else{
+			AdminServLogs::add('action', 'Order map list');
+			Utils::redirection(false, '?p='.USER_PAGE);
+		}
+	}
+	
+	
+	// MAPLIST
+	$data['maps'] = AdminServ::getMapList();
+	unset($data['maps']['lst'][$data['maps']['cid']]);
+?>
\ No newline at end of file
diff --git a/resources/process/maps.preprocess.php b/resources/process/maps.preprocess.php
new file mode 100644
index 0000000..c348232
--- /dev/null
+++ b/resources/process/maps.preprocess.php
@@ -0,0 +1 @@
+<?php	// LOCAL MODE	$localPages = array(		'maps-local',		'maps-upload',		'maps-matchset',		'maps-creatematchset'	);	$data['mapsDirectoryPath'] = AdminServ::getMapsDirectoryPath();	define('IS_LOCAL', file_exists($data['mapsDirectoryPath']));		// LECTURE	if( IS_LOCAL && in_array(USER_PAGE, $localPages) ){		if( !Utils::isWinServer() ){			$checkRightsList[$data['mapsDirectoryPath']] = 755;			$checkRightsList[AdminServConfig::$PATH_RESOURCES . 'cache'] = 777;			AdminServ::checkRights($checkRightsList);		}				// Read current directory		$matchsettingsPages = in_array(USER_PAGE, array('maps-matchset', 'maps-creatematchset'));		$hiddenFolders = ($matchsettingsPages) ? AdminServConfig::$MATCHSET_HIDDEN_FOLDERS : AdminServConfig::$MAPS_HIDDEN_FOLDERS;		$hiddenFiles = ($matchsettingsPages) ? AdminServConfig::$MAP_EXTENSION : AdminServConfig::$MATCHSET_EXTENSION;		$data['currentDir'] = Folder::read($data['mapsDirectoryPath'].$args['directory'], $hiddenFolders, $hiddenFiles, intval(AdminServConfig::RECENT_STATUS_PERIOD * 3600) );	}	else{		$notLocalPages = array(			'maps-local',			'maps-matchset',			'maps-creatematchset'		);		if( in_array(USER_PAGE, $notLocalPages) ){			Utils::redirection(false, '?p=maps-list');		}	}		// ACTIONS	$data['hasDirectory'] = null;	if($args['directory']){		$data['hasDirectory'] = '&d='.$args['directory'];	}		// Nouveau dossier	if( isset($_POST['newFolderValid']) && $_POST['newFolderName'] != null || isset($_POST['newFolderName']) ){		if( Folder::create($data['mapsDirectoryPath'].$args['directory'].Str::replaceChars($_POST['newFolderName'])) !== true ){			AdminServ::error(Utils::t('Unable to create the folder').' : '.$_POST['newFolderName']);		}		else{			AdminServLogs::add('action', 'Create new folder: '.$_POST['newFolderName']);			Utils::redirection(false, '?p='.USER_PAGE .$data['hasDirectory']);		}	}	// Renommer un dossier	else if( isset($_POST['optionFolderHiddenFieldAction']) && $_POST['optionFolderHiddenFieldAction'] == 'rename'){		$newDirectory = addslashes($_POST['optionFolderHiddenFieldValue']);				if( ($result = Folder::rename($data['mapsDirectoryPath'].$args['directory'], $data['mapsDirectoryPath'].$newDirectory)) !== true ){			AdminServ::error(Utils::t('Unable to rename the folder').' : '.$args['directory'].' ('.$result.')');		}		else{			AdminServLogs::add('action', 'Rename folder: '.$args['directory'].' to '.$newDirectory);			Utils::redirection(false, '?p='.USER_PAGE .'&d='.$newDirectory.'/');		}	}	// Déplacer un dossier	else if( isset($_POST['optionFolderHiddenFieldAction']) && $_POST['optionFolderHiddenFieldAction'] == 'move'){		$newPath = addslashes($_POST['optionFolderHiddenFieldValue']);		if($newPath == '.'){			$newPath = $data['mapsDirectoryPath'];		}		$newPath .= basename($args['directory']).'/';		$newPathFromMapsPath = str_replace($data['mapsDirectoryPath'], '', $newPath);		if($newPathFromMapsPath){			$newPathFromMapsPath = '&d='.$newPathFromMapsPath;		}				if( ($result = Folder::rename($data['mapsDirectoryPath'].$args['directory'], $newPath)) !== true ){			AdminServ::error(Utils::t('Unable to move the folder').' : '.$args['directory'].' ('.$result.')');		}		else{			AdminServLogs::add('action', 'Move folder: '.$args['directory'].' to '.$newPathFromMapsPath);			Utils::redirection(false, '?p='.USER_PAGE .$newPathFromMapsPath);		}	}	// Supprimer un dossier	else if( isset($_POST['optionFolderHiddenFieldAction']) && $_POST['optionFolderHiddenFieldAction'] == 'delete'){		if( ($result = Folder::delete($data['mapsDirectoryPath'].$args['directory'])) !== true ){			AdminServ::error(Utils::t('Unable to delete the folder').' : '.$args['directory'].' ('.$result.')');		}		else{			// Clean cache			$cache = new AdminServCache();			$cacheKey = 'mapslist-'.Str::replaceChars($data['mapsDirectoryPath'].$args['directory']);			$cache->delete($cacheKey);						AdminServLogs::add('action', 'Delete folder: '.$args['directory']);			Utils::redirection(false, '?p='.USER_PAGE);		}	}?>
\ No newline at end of file
diff --git a/resources/process/plugins-list.php b/resources/process/plugins-list.php
new file mode 100644
index 0000000..ce38f3a
--- /dev/null
+++ b/resources/process/plugins-list.php
@@ -0,0 +1,7 @@
+<?php
+	// Nombre de plugins
+	$data['nbplugins'] = AdminServPlugin::countPlugins();
+	if($data['nbplugins']['count'] === 0){
+		Utils::redirection();
+	}
+?>
\ No newline at end of file
diff --git a/resources/process/srvopts.php b/resources/process/srvopts.php
new file mode 100644
index 0000000..1277378
--- /dev/null
+++ b/resources/process/srvopts.php
@@ -0,0 +1,79 @@
+<?php
+	// GAMEDATA
+	if( AdminServAdminLevel::isType('Admin') ){
+		if( !$client->query('GameDataDirectory') ){
+			AdminServ::error();
+		}
+		else{
+			$gameDataDirectory = $client->getResponse();
+			define('IS_LOCAL', file_exists($gameDataDirectory));
+			
+			if(IS_LOCAL){
+				$srvConfigDirectory = $gameDataDirectory.'Config/';
+				$srvoptsConfigDirectory = $srvConfigDirectory.'AdminServ/ServerOptions/';
+				if( !Utils::isWinServer() ){
+					AdminServ::checkRights(array($srvConfigDirectory => 777));
+				}
+				
+				if( !file_exists($srvoptsConfigDirectory) ){
+					if( ($result = Folder::create($srvoptsConfigDirectory)) !== true ){
+						AdminServ::error(Utils::t('Unable to create the folder').' : '.$srvoptsConfigDirectory.' ('.$result.')');
+					}
+				}
+				
+				$data['srvoptsConfigFiles'] = Folder::read($srvoptsConfigDirectory, array(), array(), intval(AdminServConfig::RECENT_STATUS_PERIOD * 3600) );
+			}
+		}
+	}
+	
+	
+	// ENREGISTREMENT
+	if( isset($_POST['savesrvopts']) ){
+		// Récupération des données
+		$struct = AdminServ::getServerOptionsStruct();
+		$ChangeAuthPassword = null;
+		if( isset($_POST['ChangeAuthPassword']) && $_POST['ChangeAuthPassword'] != null ){
+			$ChangeAuthLevel = $_POST['ChangeAuthLevel'];
+			$ChangeAuthPassword = trim($_POST['ChangeAuthPassword']);
+		}
+		$srvoptsImportExport = false;
+		if( array_key_exists('srvoptsImportExport', $_POST) ){
+			$srvoptsImportExport = $_POST['srvoptsImportExport'];
+		}
+		
+		// Enregistrement
+		if($ChangeAuthPassword){
+			if(USER_ADMINLEVEL === $ChangeAuthLevel){
+				$_SESSION['adminserv']['password'] = $ChangeAuthPassword;
+			}
+			AdminServ::info( Utils::t('You changed the password "!authLevel", remember it at the next connection!', array('!authLevel' => $ChangeAuthLevel)) );
+			AdminServLogs::add('action', 'Change authentication password for '.$ChangeAuthLevel.' level');
+		}
+		elseif($srvoptsImportExport){
+			// Import
+			if($srvoptsImportExport == 'Import'){
+				$srvoptsImportName = $_POST['srvoptsImportName'];
+				if($srvoptsImportName != 'none'){
+					$struct = AdminServ::importServerOptions($srvoptsConfigDirectory.$srvoptsImportName);
+					if( AdminServ::setServerOptions($struct) ){
+						AdminServLogs::add('action', 'Import server options from '.$srvoptsConfigDirectory.$srvoptsImportName);
+					}
+				}
+			}
+			// Export
+			elseif($srvoptsImportExport == 'Export'){
+				$srvoptsExportName = Str::replaceChars($_POST['srvoptsExportName']);
+				AdminServ::exportServerOptions($srvoptsConfigDirectory.$srvoptsExportName.'.txt', $struct);
+			}
+		}
+		elseif( AdminServ::setServerOptions($struct) ){
+			AdminServLogs::add('action', 'Save server options');
+		}
+		Utils::redirection(false, '?p='.USER_PAGE);
+	}
+	
+	
+	// LECTURE
+	$data['srvOpt'] = AdminServ::getServerOptions();
+	$data['adminLevels'] = AdminServAdminLevel::getServerList();
+?>
\ No newline at end of file
diff --git a/resources/templates/chat.tpl.php b/resources/templates/chat.tpl.php
new file mode 100644
index 0000000..62286e6
--- /dev/null
+++ b/resources/templates/chat.tpl.php
@@ -0,0 +1,25 @@
+<section class="cadre">
+	<h1><?php echo Utils::t('Chat'); ?></h1>
+	<div class="title-detail">
+		<ul>
+			<li class="last"><a id="checkServerLines" href="?p=chat" data-val="0" data-txt="<?php echo Utils::t('Show server lines'); ?>"><?php echo Utils::t('Hide server lines'); ?></a></li>
+		</ul>
+	</div>
+	
+	<div id="chat"><?php echo $data['serverLines']; ?></div>
+	
+	<?php if (AdminServAdminLevel::hasPermission('chat_sendmessage')): ?>
+		<div class="options">
+			<input class="text" type="text" name="chatNickname" id="chatNickname" value="<?php echo $data['nickname']; ?>" data-default-value="<?php echo Utils::t('Nickname'); ?>" />
+			<select name="chatColor" id="chatColor" title="<?php echo Utils::t('Default color: yellow'); ?>">
+				<?php echo $data['colorOptions']; ?>
+			</select>
+			<input class="text" type="text" name="chatMessage" id="chatMessage" value="<?php echo Utils::t('Message'); ?>" data-default-value="<?php echo Utils::t('Message'); ?>" />
+			<select name="chatDestination" id="chatDestination" title="<?php echo $data['destination']['title']; ?>">
+				<option value="server"><?php echo Utils::t('Destination'); ?></option>
+				<?php echo $data['destination']['list']; ?>
+			</select>
+			<input class="button dark" type="submit" name="chatSend" id="chatSend" value="<?php echo Utils::t('Send'); ?>" />
+		</div>
+	<?php endif; ?>
+</section>
\ No newline at end of file
diff --git a/resources/templates/config-addlevel.tpl.php b/resources/templates/config-addlevel.tpl.php
new file mode 100644
index 0000000..4f754fd
--- /dev/null
+++ b/resources/templates/config-addlevel.tpl.php
@@ -0,0 +1,96 @@
+<section class="cadre">
+	<h1><?php echo (defined('IS_LEVEL_EDITION')) ? Utils::t('Edit level') : Utils::t('Add level'); ?></h1>
+	<form method="post" action="?p=<?php echo USER_PAGE; if ($args['id'] !== -1): echo '&id='.$args['id']; endif; ?>">
+		<div class="content">
+			<fieldset>
+				<legend><?php echo Utils::t('Admin level'); ?></legend>
+				<table>
+					<tr>
+						<td class="key"><label for="addLevelName"><?php echo Utils::t('Level name'); ?></label></td>
+						<td class="value">
+							<input class="text width3" type="text" name="addLevelName" id="addLevelName" value="<?php echo $data['name']; ?>" />
+						</td>
+						<td class="info"></td>
+					</tr>
+					<tr>
+						<td class="key"><label for="addLevelType"><?php echo Utils::t('Level type'); ?></label></td>
+						<td class="value">
+							<?php if (!empty($data['types'])): ?>
+								<select name="addLevelType" id="addLevelType">
+									<?php foreach ($data['types'] as $type): ?>
+										<option value="<?php echo $type; ?>"<?php echo (defined('IS_LEVEL_EDITION') && $type == $data['adminlevel']['type']) ? ' selected="selected"' : ''; ?>><?php echo $type; ?></option>
+									<?php endforeach; ?>
+								</select>
+							<?php endif; ?>
+						</td>
+						<td class="info"></td>
+					</tr>
+				</table>
+			</fieldset>
+			
+			<fieldset class="adminlevelSortableList">
+				<legend><?php echo Utils::t('Access'); ?></legend>
+				<table>
+					<tr>
+						<td class="key"><?php echo Utils::t('Add access'); ?></td>
+						<td class="value">
+							<h3><?php echo Utils::t('All access'); ?></h3>
+							<ul id="defaultAccess" class="adminlevelAccessList">
+								<?php if (!empty($data['access']['default'])): ?>
+									<?php foreach ($data['access']['default'] as $accessName): ?>
+										<li class="defaultName"><?php echo $accessName; ?></li>
+									<?php endforeach; ?>
+								<?php endif; ?>
+							</ul>
+						</td>
+						<td class="value">
+							<h3><?php echo Utils::t('Selected access'); ?></h3>
+							<ul id="selectedAccess" class="adminlevelAccessList">
+								<?php if (!empty($data['access']['selected'])): ?>
+									<?php foreach ($data['access']['selected'] as $accessName): ?>
+										<li class="selectedName"><?php echo $accessName; ?></li>
+									<?php endforeach; ?>
+								<?php endif; ?>
+							</ul>
+							<input type="hidden" name="selectedAccessSortList" id="selectedAccessSortList" value="" />
+						</td>
+					</tr>
+				</table>
+			</fieldset>
+			
+			<fieldset class="adminlevelSortableList">
+				<legend><?php echo Utils::t('Permissions'); ?></legend>
+				<table>
+					<tr>
+						<td class="key"><?php echo Utils::t('Add permission'); ?></td>
+						<td class="value">
+							<h3><?php echo Utils::t('All permissions'); ?></h3>
+							<ul id="defaultPermission" class="adminlevelPermissionList">
+								<?php if (!empty($data['permission']['default'])): ?>
+									<?php foreach ($data['permission']['default'] as $permissionName): ?>
+										<li class="defaultName"><?php echo $permissionName; ?></li>
+									<?php endforeach; ?>
+								<?php endif; ?>
+							</ul>
+						</td>
+						<td class="value">
+							<h3><?php echo Utils::t('Selected permissions'); ?></h3>
+							<ul id="selectedPermission" class="adminlevelPermissionList">
+								<?php if (!empty($data['permission']['selected'])): ?>
+									<?php foreach ($data['permission']['selected'] as $permissionName): ?>
+										<li class="selectedName"><?php echo $permissionName; ?></li>
+									<?php endforeach; ?>
+								<?php endif; ?>
+							</ul>
+							<input type="hidden" name="selectedPermissionSortList" id="selectedPermissionSortList" value="" />
+						</td>
+					</tr>
+				</table>
+			</fieldset>
+		</div>
+		
+		<div class="fright save">
+			<input class="button light" type="submit" name="savelevel" id="savelevel" value="<?php echo Utils::t('Save'); ?>" />
+		</div>
+	</form>
+</section>
\ No newline at end of file
diff --git a/resources/templates/config-addserver.tpl.php b/resources/templates/config-addserver.tpl.php
new file mode 100644
index 0000000..ee00e4b
--- /dev/null
+++ b/resources/templates/config-addserver.tpl.php
@@ -0,0 +1,101 @@
+<section class="cadre">
+	<h1><?php echo (defined('IS_SERVER_EDITION')) ? Utils::t('Edit server') : Utils::t('Add server'); ?></h1>
+	<form method="post" action="?p=<?php echo USER_PAGE; if ($args['id'] !== -1): echo '&id='.$args['id']; endif; ?>">
+		<div class="content">
+			<fieldset>
+				<legend><?php echo Utils::t('Connection information'); ?></legend>
+				<table>
+					<tr>
+						<td class="key"><label for="addServerName"><?php echo Utils::t('Server name'); ?></label></td>
+						<td class="value">
+							<input class="text width3" type="text" name="addServerName" id="addServerName" value="<?php echo $data['name']; ?>" />
+						</td>
+						<td class="info">
+							<?php echo Utils::t('Server name without color'); ?>
+						</td>
+					</tr>
+					<tr>
+						<td class="key"><label for="addServerAddress"><?php echo Utils::t('Address'); ?></label></td>
+						<td class="value">
+							<input class="text width3" type="text" name="addServerAddress" id="addServerAddress" value="<?php echo $data['address']; ?>" />
+						</td>
+						<td class="info">
+							<?php echo Utils::t('IP address or domain name'); ?>
+						</td>
+					</tr>
+					<tr>
+						<td class="key"><label for="addServerPort"><?php echo Utils::t('XMLRPC port'); ?></label></td>
+						<td class="value">
+							<input class="text width3" type="number" name="addServerPort" id="addServerPort" value="<?php echo $data['port']; ?>" />
+						</td>
+						<td class="info">
+							<?php echo Utils::t('Port for remote control'); ?>
+						</td>
+					</tr>
+                    <tr>
+                        <td class="key"><label for="addDisplayServPassword"><?php echo Utils::t('DisplayServ Password'); ?></label></td>
+                        <td class="value">
+                            <input class="text width3" type="text" name="addDisplayServPassword" id="addDisplayServPassword" value="<?php echo $data['ds_pw']; ?>" />
+                        </td>
+                        <td class="info">
+                            <?php echo Utils::t('User password from dedicated config'); ?>
+                        </td>
+                    </tr>
+				</table>
+			</fieldset>
+			
+			<fieldset>
+				<legend><?php echo Utils::t('Optionnal information'); ?></legend>
+				<table>
+					<tr>
+						<td class="key"><label for="addServerMapsBasePath"><?php echo Utils::t('Maps base folder'); ?></label></td>
+						<td class="value">
+							<input class="text width3" type="text" name="addServerMapsBasePath" id="addServerMapsBasePath" value="<?php echo $data['mapsbasepath']; ?>" />
+						</td>
+						<td class="info">
+							<?php echo Utils::t('Default path from maps folder for listing maps'); ?>
+						</td>
+					</tr>
+					<tr>
+						<td class="key"><label for="addServerMatchSet"><?php echo Utils::t('Server MatchSettings'); ?></label></td>
+						<td class="value">
+							<input class="text width3" type="text" name="addServerMatchSet" id="addServerMatchSet" value="<?php echo $data['matchsettings']; ?>" />
+						</td>
+						<td class="info">
+							<?php echo Utils::t('Current server MatchSettings name'); ?>
+						</td>
+					</tr>
+					<tr>
+						<td class="key"><label for="addServerAdmLvlSA"><?php echo Utils::t('SuperAdmin level'); ?></label></td>
+						<td class="value">
+							<input class="text width3" type="text" name="addServerAdmLvlSA" id="addServerAdmLvlSA" value="<?php echo $data['adminlevel']['SuperAdmin']; ?>" />
+						</td>
+						<td rowspan="3" class="info">
+							<?php echo Utils::t('Possible values for the admin level:'); ?><br />
+							<?php echo Utils::t('all => all access'); ?><br />
+							<?php echo Utils::t('local => local network access'); ?><br />
+							<?php echo Utils::t('192.168.0.1, 192.168.0.2 => access to one or more IP address'); ?><br />
+							<?php echo Utils::t('none => removed from the access list'); ?>
+						</td>
+					</tr>
+					<tr>
+						<td class="key"><label for="addServerAdmLvlADM"><?php echo ucwords(Utils::t('Admin level')); ?></label></td>
+						<td class="value">
+							<input class="text width3" type="text" name="addServerAdmLvlADM" id="addServerAdmLvlADM" value="<?php echo $data['adminlevel']['Admin']; ?>" />
+						</td>
+					</tr>
+					<tr>
+						<td class="key"><label for="addServerAdmLvlUSR"><?php echo Utils::t('User level'); ?></label></td>
+						<td class="value">
+							<input class="text width3" type="text" name="addServerAdmLvlUSR" id="addServerAdmLvlUSR" value="<?php echo $data['adminlevel']['User']; ?>" />
+						</td>
+					</tr>
+				</table>
+			</fieldset>
+		</div>
+		
+		<div class="fright save">
+			<input class="button light" type="submit" name="saveserver" id="saveserver" value="<?php echo Utils::t('Save'); ?>" />
+		</div>
+	</form>
+</section>
\ No newline at end of file
diff --git a/resources/templates/config-adminlevel.tpl.php b/resources/templates/config-adminlevel.tpl.php
new file mode 100644
index 0000000..6be5a2c
--- /dev/null
+++ b/resources/templates/config-adminlevel.tpl.php
@@ -0,0 +1,54 @@
+<section class="cadre">
+	<h1><?php echo Utils::t('Admin levels list'); ?></h1>
+	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+	<table id="levelList">
+		<thead>
+			<tr>
+				<th class="thleft"><?php echo Utils::t('Name'); ?></th>
+				<th><?php echo Utils::t('Type'); ?></th>
+				<th><?php echo Utils::t('Access'); ?></th>
+				<th><?php echo Utils::t('Permissions'); ?></th>
+				<th class="thright"><?php echo Utils::t('Manage'); ?></th>
+			</tr>
+		</thead>
+		<tbody>
+			<tr class="table-separation"><td colspan="8"></td></tr>
+			<?php if($data['count'] > 0): ?>
+				<?php $i = 0; ?>
+				<?php foreach ($data['levels'] as $levelData): ?>
+					<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
+						<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/players.png" alt="" /><?php echo $levelData['name']; ?></td>
+						<td><?php echo $levelData['type']; ?></td>
+						<td><?php echo $levelData['allowed_access']; ?></td>
+						<td><?php echo $levelData['allowed_permissions']; ?></td>
+						<td class="checkbox"><input type="radio" name="level[]" value="<?php echo $levelData['name']; ?>" /></td>
+					</tr>
+					<?php $i++; ?>
+				<?php endforeach; ?>
+			<?php else: ?>
+				<tr class="no-line">
+					<td class="center" colspan="8"><?php echo Utils::t('No admin level'); ?></td>
+				</tr>
+			<?php endif; ?>
+		</tbody>
+	</table>
+	
+	<div class="options">
+		<div class="fleft">
+			<span class="nb-line">
+				<?php echo $data['count'].' '.(($data['count'] > 1) ? Utils::t('admin levels') : Utils::t('admin level')); ?>
+			</span>
+		</div>
+		<div class="fright">
+			<div class="selected-files-label locked">
+				<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
+				<div class="selected-files-option">
+					<input class="button dark" type="submit" name="deletelevel" id="deletelevel" data-confirm-text="<?php echo Utils::t('Do you really want to remove this selection?'); ?>" value="<?php echo Utils::t('Delete'); ?>" />
+					<input class="button dark" type="submit" name="duplicatelevel" id="duplicatelevel" value="<?php echo Utils::t('Duplicate'); ?>" />
+					<input class="button dark" type="submit" name="editlevel" id="editlevel" value="<?php echo Utils::t('Modify'); ?>" />
+				</div>
+			</div>
+		</div>
+	</div>
+	</form>
+</section>
\ No newline at end of file
diff --git a/resources/templates/config-levelsorder.tpl.php b/resources/templates/config-levelsorder.tpl.php
new file mode 100644
index 0000000..2c43779
--- /dev/null
+++ b/resources/templates/config-levelsorder.tpl.php
@@ -0,0 +1,22 @@
+<section class="cadre">
+	<h1><?php echo Utils::t('Levels order'); ?></h1>
+	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+		<div class="content">
+			<ul id="sortableLevelsList">
+			<?php foreach ($data['levels'] as $levelName => $levelData): ?>
+				<li class="ui-state-default">
+					<div class="ui-icon ui-icon-arrowthick-2-n-s"></div>
+					<div class="order-server-name"><?php echo $levelName; ?></div>
+					<div class="order-server-addr-port"><?php echo $levelData['adminlevel']['type']; ?></div>
+				</li>
+			<?php endforeach; ?>
+			</ul>
+		</div>
+		
+		<div class="fright save">
+			<input class="button light" type="button" id="reset" name="reset" value="<?php echo Utils::t('Reset'); ?>" />
+			<input class="button light" type="submit" id="save" name="save" value="<?php echo Utils::t('Save'); ?>" />
+			<input type="hidden" id="list" name="list" value="" />
+		</div>
+	</form>
+</section>
\ No newline at end of file
diff --git a/resources/templates/config-password.tpl.php b/resources/templates/config-password.tpl.php
new file mode 100644
index 0000000..c4ae271
--- /dev/null
+++ b/resources/templates/config-password.tpl.php
@@ -0,0 +1,24 @@
+<section class="cadre">
+	<h1><?php echo Utils::t('Change password'); ?></h1>
+	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+		<div class="content">
+			<fieldset>
+				<legend><?php echo Utils::t('Password'); ?></legend>
+				<table>
+					<tr>
+						<td class="key"><label for="changePasswordCurrent"><?php echo Utils::t('Current'); ?></label></td>
+						<td class="value"><input class="text width3" type="password" name="changePasswordCurrent" id="changePasswordCurrent" value="" /></td>
+					</tr>
+					<tr>
+						<td class="key"><label for="changePasswordNew"><?php echo Utils::t('New'); ?></label></td>
+						<td class="value"><input class="text width3" type="password" name="changePasswordNew" id="changePasswordNew" value="" /></td>
+					</tr>
+				</table>
+			</fieldset>
+		</div>
+		
+		<div class="fright save">
+			<input class="button light" type="submit" name="savepassword" id="savepassword" value="<?php echo Utils::t('Save'); ?>" />
+		</div>
+	</form>
+</section>
\ No newline at end of file
diff --git a/resources/templates/config-servers.tpl.php b/resources/templates/config-servers.tpl.php
new file mode 100644
index 0000000..c033ed7
--- /dev/null
+++ b/resources/templates/config-servers.tpl.php
@@ -0,0 +1,89 @@
+<section class="cadre">
+	<h1><?php echo Utils::t('Servers list'); ?></h1>
+	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+	<table id="serverList">
+		<thead>
+			<tr>
+				<th class="thleft"><?php echo Utils::t('Server name'); ?></th>
+				<th><?php echo Utils::t('Address'); ?></th>
+				<th><?php echo Utils::t('Port'); ?></th>
+				<th><?php echo Utils::t('MatchSettings'); ?></th>
+				<th><?php echo Utils::t('SuperAdmin level'); ?></th>
+				<th><?php echo ucwords( Utils::t('Admin level') ); ?></th>
+				<th><?php echo Utils::t('User level'); ?></th>
+				<th class="thright"><?php echo Utils::t('Manage'); ?></th>
+			</tr>
+		</thead>
+		<tbody>
+			<tr class="table-separation"><td colspan="8"></td></tr>
+			<?php if($data['count'] > 0): ?>
+				<?php $i = 0; ?>
+				<?php foreach ($data['servers'] as $serverName => $serverData): ?>
+					<?php
+						// MatchSettings
+						$matchSettings = ($serverData['matchsettings']) ? $serverData['matchsettings'] : Utils::t('None');
+						
+						// Niveaux admins
+						$adminLevelsStatus = array();
+						foreach($data['adminLevelsType'] as $level){
+							if( array_key_exists($level, $serverData['adminlevel']) ){
+								if( is_array($serverData['adminlevel'][$level]) ){
+									$adminLevelsStatus[] = Utils::t('IP address');
+								}
+								else if($serverData['adminlevel'][$level] === 'local'){
+									$adminLevelsStatus[] = Utils::t('Local network');
+								}
+								else if($serverData['adminlevel'][$level] === 'all'){
+									$adminLevelsStatus[] = Utils::t('All');
+								}
+								else if($serverData['adminlevel'][$level] === 'none'){
+									$adminLevelsStatus[] = Utils::t('Removed');
+								}
+								else{
+									$adminLevelsStatus[] = Utils::t('Missing');
+								}
+							}
+							else{
+								$adminLevelsStatus[] = Utils::t('Missing');
+							}
+						}
+					?>
+					<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
+						<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/servers.png" alt="" /><?php echo $serverName; ?></td>
+						<td><?php echo $serverData['address']; ?></td>
+						<td><?php echo $serverData['port']; ?></td>
+						<td><?php echo $matchSettings; ?></td>
+						<td><?php echo $adminLevelsStatus[0]; ?></td>
+						<td><?php echo $adminLevelsStatus[1]; ?></td>
+						<td><?php echo $adminLevelsStatus[2]; ?></td>
+						<td class="checkbox"><input type="radio" name="server[]" value="<?php echo $serverName; ?>" /></td>
+					</tr>
+					<?php $i++; ?>
+				<?php endforeach; ?>
+			<?php else: ?>
+				<tr class="no-line">
+					<td class="center" colspan="8"><?php echo Utils::t('No server'); ?></td>
+				</tr>
+			<?php endif; ?>
+		</tbody>
+	</table>
+	
+	<div class="options">
+		<div class="fleft">
+			<span class="nb-line">
+				<?php echo $data['count'].' '.(($data['count'] > 1) ? Utils::t('servers') : Utils::t('server')); ?>
+			</span>
+		</div>
+		<div class="fright">
+			<div class="selected-files-label locked">
+				<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
+				<div class="selected-files-option">
+					<input class="button dark" type="submit" name="deleteserver" id="deleteserver" data-confirm-text="<?php echo Utils::t('Do you really want to remove this selection?'); ?>" value="<?php echo Utils::t('Delete'); ?>" />
+					<input class="button dark" type="submit" name="duplicateserver" id="duplicateserver" value="<?php echo Utils::t('Duplicate'); ?>" />
+					<input class="button dark" type="submit" name="editserver" id="editserver" value="<?php echo Utils::t('Modify'); ?>" />
+				</div>
+			</div>
+		</div>
+	</div>
+	</form>
+</section>
\ No newline at end of file
diff --git a/resources/templates/config-serversorder.tpl.php b/resources/templates/config-serversorder.tpl.php
new file mode 100644
index 0000000..94d031d
--- /dev/null
+++ b/resources/templates/config-serversorder.tpl.php
@@ -0,0 +1,22 @@
+<section class="cadre">
+	<h1><?php echo Utils::t('Servers order'); ?></h1>
+	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+		<div class="content">
+			<ul id="sortableServersList">
+			<?php foreach ($data['servers'] as $serverName => $serverData): ?>
+				<li class="ui-state-default">
+					<div class="ui-icon ui-icon-arrowthick-2-n-s"></div>
+					<div class="order-server-name"><?php echo $serverName; ?></div>
+					<div class="order-server-addr-port"><?php echo $serverData['address'].' / '.$serverData['port']; ?></div>
+				</li>
+			<?php endforeach; ?>
+			</ul>
+		</div>
+		
+		<div class="fright save">
+			<input class="button light" type="button" id="reset" name="reset" value="<?php echo Utils::t('Reset'); ?>" />
+			<input class="button light" type="submit" id="save" name="save" value="<?php echo Utils::t('Save'); ?>" />
+			<input type="hidden" id="list" name="list" value="" />
+		</div>
+	</form>
+</section>
\ No newline at end of file
diff --git a/resources/templates/connection.tpl.php b/resources/templates/connection.tpl.php
new file mode 100644
index 0000000..4e52861
--- /dev/null
+++ b/resources/templates/connection.tpl.php
@@ -0,0 +1,49 @@
+<?php if (isset($_SESSION['adminserv']['check_password']) && $_SESSION['adminserv']['check_password'] === true): // Demande de password ?>
+<section class="config-servers">
+	<form method="post" action="./config/">
+		<fieldset>
+			<legend><?php echo Utils::t('Servers configuration'); ?></legend>
+			<div class="connection-label">
+				<label for="checkPassword"><?php echo Utils::t('Password'); ?> :</label>
+				<input class="text" type="password" name="checkPassword" id="checkPassword" value="" />
+			</div>
+			<div class="connection-login">
+				<input class="button light" type="submit" name="configcheckpassword" id="configcheckpassword" value="<?php echo Utils::t('Connection'); ?>" />
+			</div>
+			<div class="connection-cancel">
+				<a class="button light" href="./?logout"><?php echo Utils::t('Cancel'); ?></a>
+			</div>
+		</fieldset>
+	</form>
+</section>
+<?php elseif (isset($_SESSION['adminserv']['get_password']) && $_SESSION['adminserv']['get_password'] === true): // Demande de création password ?>
+<section class="config-servers no-server">
+	<form method="post" action="./config/">
+		<fieldset>
+			<legend><?php echo Utils::t('Online configuration'); ?></legend>
+			<div class="connection-label">
+				<label for="savePassword"><?php echo Utils::t('Password'); ?> :</label>
+				<input class="text" type="password" name="savePassword" id="savePassword" value="" />
+			</div>
+			<div class="connection-login">
+				<input class="button light" type="submit" name="configsavepassword" id="configsavepassword" value="<?php echo Utils::t('Save'); ?>" />
+			</div>
+		</fieldset>
+	</form>
+</section>
+<?php else: // Affichage de DisplayServ ?>
+<section class="displayserv">
+	<?php if (AdminServConfig::USE_DISPLAYSERV): ?>
+		<link rel="stylesheet" href="<?php echo AdminServConfig::$PATH_RESOURCES; ?>css/displayserv.css" />
+		<script src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>js/displayserv.js"></script>
+		<script>
+			$(document).ready(function(){
+				$('#displayserv').displayServ({
+					color: '<?php echo AdminServUI::getThemeColor(); ?>'
+				});
+			});
+		</script>
+		<div id="displayserv"></div>
+	<?php endif; ?>
+</section>
+<?php endif; ?>
\ No newline at end of file
diff --git a/resources/templates/footer.tpl.php b/resources/templates/footer.tpl.php
new file mode 100644
index 0000000..d874ff5
--- /dev/null
+++ b/resources/templates/footer.tpl.php
@@ -0,0 +1 @@
+					</div><!-- #content-inner -->				</div><!-- #content -->								<footer>					<div id="footer-inner">						© 2006-<?php echo date('Y'); ?> <a href="http://www.zone-kev717.info"><strong>Kev717</strong></a> - updated by <a href="http://forum.maniaplanet.com/memberlist.php?mode=viewprofile&u=282"><strong>Chris92</strong></a> | AdminServ <?php echo ADMINSERV_VERSION; ?>												<span id="path_resources" hidden="hidden"><?php echo AdminServConfig::$PATH_RESOURCES; ?></span>						<?php if (ADMINSERV_TIMER): ?>							<p>Script executé en <?php echo AdminServ::endTimer(); ?> sec</p>						<?php endif; ?>					</div>				</footer>							</div><!-- #page-inner -->		</div><!-- #page -->	</body></html>
\ No newline at end of file
diff --git a/resources/templates/gameinfos-field.tpl.php b/resources/templates/gameinfos-field.tpl.php
new file mode 100644
index 0000000..a8dffbb
--- /dev/null
+++ b/resources/templates/gameinfos-field.tpl.php
@@ -0,0 +1,12 @@
+<tr>
+	<td class="key"><label for="Next<?php echo $data['gameInfosField']['id']; ?>"><?php echo Utils::t($data['gameInfosField']['name']); ?></label></td>
+	<?php if ($data['gameInfosField']['gameInfos']['curr'] != null): ?>
+		<td class="value">
+			<input class="text width2" type="text" name="Curr<?php echo $data['gameInfosField']['id']; ?>" id="Curr<?php echo $data['gameInfosField']['id']; ?>" readonly="readonly" value="<?php if (isset($data['gameInfosField']['gameInfos']['curr'][$data['gameInfosField']['id']])): echo $data['gameInfosField']['gameInfos']['curr'][$data['gameInfosField']['id']]; endif; ?>" />
+		</td>
+	<?php endif; ?>
+	<td class="value">
+		<input class="text width2" type="<?php echo (isset($data['gameInfosField']['gameInfos']['next'][$data['gameInfosField']['id']]) && is_numeric($data['gameInfosField']['gameInfos']['next'][$data['gameInfosField']['id']])) ? 'number" min="0"' : 'text'; ?>" name="Next<?php echo $data['gameInfosField']['id']; ?>" id="Next<?php echo $data['gameInfosField']['id']; ?>" value="<?php if (isset($data['gameInfosField']['gameInfos']['next'][$data['gameInfosField']['id']])): echo $data['gameInfosField']['gameInfos']['next'][$data['gameInfosField']['id']]; endif; ?>" />
+	</td>
+	<td class="preview"></td>
+</tr>
\ No newline at end of file
diff --git a/resources/templates/gameinfos-gamemode.tpl.php b/resources/templates/gameinfos-gamemode.tpl.php
new file mode 100644
index 0000000..31022ec
--- /dev/null
+++ b/resources/templates/gameinfos-gamemode.tpl.php
@@ -0,0 +1,141 @@
+<?php if (SERVER_VERSION_NAME == 'ManiaPlanet'): ?>
+	<fieldset id="gameMode-script" class="gameinfos_script" hidden="hidden">
+		<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/options.png" alt="" /><?php echo AdminServ::getGameModeName(0); ?></legend>
+		<table class="game_infos">
+			<tr>
+				<td class="key"><label for="NextScriptName"><?php echo Utils::t('Script name'); ?></label></td>
+				<?php if ($data['gameInfos']['curr'] != null): ?>
+					<td class="value">
+						<input class="text width2" type="text" name="CurrScriptName" id="CurrScriptName" readonly="readonly" value="<?php echo $data['gameInfos']['curr']['ScriptName']; ?>" />
+					</td>
+				<?php endif; ?>
+				<?php if ($data['gameInfos']['next'] != null): ?>
+					<td class="value">
+						<input class="text width2" type="text" name="NextScriptName" id="NextScriptName" value="<?php echo $data['gameInfos']['next']['ScriptName']; ?>" />
+					</td>
+					<td class="preview">
+					<?php if ($data['gameInfos']['next']['GameMode'] == 0): ?>
+						<a id="getScriptSettings" href="" data-infotext="<?php echo Utils::t('Script settings updated.'); ?>"><?php echo Utils::t('Script settings'); ?></a>
+					<?php endif; ?>
+					</td>
+				<?php endif; ?>
+			</tr>
+		</table>
+	</fieldset>
+	<?php if ($data['gameInfos']['next']['GameMode'] == 0): ?>
+		<div id="getScriptSettingsDialog" data-title="<?php echo Utils::t('Script settings'); ?>" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-save="<?php echo Utils::t('Save'); ?>" hidden="hidden">
+			<div id="dialogScriptInfo">
+				<h2><?php echo Utils::t('Script info'); ?></h2>
+				<div class="content">
+					<table>
+						<tbody>
+							<tr>
+								<td class="key"><?php echo Utils::t('Name'); ?></td>
+								<td class="value" id="dialogScriptInfoName"></td>
+							</tr>
+							<tr>
+								<td class="key"><?php echo Utils::t('Compatible map types'); ?></td>
+								<td class="value" id="dialogScriptInfoCompatibleMapTypes"></td>
+							</tr>
+							<tr class="dialogScriptInfoDesc" hidden="hidden">
+								<td class="key"><?php echo Utils::t('Description'); ?></td>
+								<td class="value" id="dialogScriptInfoDesc"></td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+			</div>
+			<div id="dialogScriptSettings">
+				<h2><?php echo Utils::t('Script parameters'); ?></h2>
+				<table>
+					<thead>
+						<tr>
+							<th class="thleft"><?php echo Utils::t('Name'); ?></th>
+							<th><?php echo Utils::t('Value'); ?></th>
+							<th class="thright"><?php echo Utils::t('Description'); ?></th>
+						</tr>
+					</thead>
+					<tbody></tbody>
+				</table>
+			</div>
+		</div>
+	<?php endif; ?>
+<?php endif; ?>
+
+<fieldset id="gameMode-rounds" class="gameinfos_round" hidden="hidden">
+	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_rounds.png" alt="" /><?php echo AdminServ::getGameModeName(1, true); ?></legend>
+	<table class="game_infos">
+		<tr>
+			<td class="key"><label for="NextRoundsUseNewRules"><?php echo Utils::t('Use new rules'); ?></label></td>
+			<?php if ($data['gameInfos']['curr'] != null): ?>
+				<td class="value">
+					<input class="text width2" type="text" name="CurrRoundsUseNewRules" id="CurrRoundsUseNewRules" readonly="readonly" value="<?php echo ($data['gameInfos']['curr']['RoundsUseNewRules'] != null) ? Utils::t('Enable') : Utils::t('Disable'); ?>" />
+				</td>
+			<?php endif; ?>
+			<td class="value">
+				<input class="text" type="checkbox" name="NextRoundsUseNewRules" id="NextRoundsUseNewRules" value=""<?php if ($data['gameInfos']['next']['RoundsUseNewRules'] != null): echo ' checked="checked"'; endif; ?> />
+			</td>
+			<td class="preview"></td>
+		</tr>
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Points limit', 'RoundsPointsLimit'); ?>
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Custom points limit', 'RoundCustomPoints'); ?>
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Force laps', 'RoundsForcedLaps'); ?>
+	</table>
+</fieldset>
+
+<fieldset id="gameMode-timeattack" class="gameinfos_timeattack" hidden="hidden">
+	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_timeattack.png" alt="" /><?php echo AdminServ::getGameModeName(2, true); ?></legend>
+	<table class="game_infos">
+		<tr>
+			<td class="key"><label for="NextTimeAttackLimit"><?php echo Utils::t('Time limit'); ?> <span>(<?php echo Utils::t('sec'); ?>)</span></label></td>
+			<?php if ($data['gameInfos']['curr'] != null): ?>
+				<td class="value">
+					<input class="text width2" type="text" name="CurrTimeAttackLimit" id="CurrTimeAttackLimit" readonly="readonly" value="<?php echo TimeDate::millisecToSec($data['gameInfos']['curr']['TimeAttackLimit']); ?>" />
+				</td>
+			<?php endif; ?>
+			<td class="value">
+				<input class="text width2" type="number" min="0" name="NextTimeAttackLimit" id="NextTimeAttackLimit" value="<?php echo TimeDate::millisecToSec($data['gameInfos']['next']['TimeAttackLimit']); ?>" />
+			</td>
+			<td class="preview"></td>
+		</tr>
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Start synchronization period', 'TimeAttackSynchStartPeriod'); ?>
+	</table>
+</fieldset>
+
+<fieldset id="gameMode-team" class="gameinfos_team" hidden="hidden">
+	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_team.png" alt="" /><?php echo AdminServ::getGameModeName(3, true); ?></legend>
+	<table class="game_infos">
+		<tr>
+			<td class="key"><label for="NextTeamUseNewRules"><?php echo Utils::t('Use new rules'); ?></label></td>
+			<?php if ($data['gameInfos']['curr'] != null): ?>
+				<td class="value">
+					<input class="text width2" type="text" name="CurrTeamUseNewRules" id="CurrTeamUseNewRules" readonly="readonly" value="<?php echo ($data['gameInfos']['curr']['TeamUseNewRules'] != null) ? Utils::t('Enable') : Utils::t('Disable'); ?>" />
+				</td>
+			<?php endif; ?>
+			<td class="value">
+				<input class="text" type="checkbox" name="NextTeamUseNewRules" id="NextTeamUseNewRules" value=""<?php if ($data['gameInfos']['next']['TeamUseNewRules'] != null): echo ' checked="checked"'; endif; ?> />
+			</td>
+			<td class="preview"></td>
+		</tr>
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Points limit', 'TeamPointsLimit'); ?>
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Maximal points', 'TeamMaxPoints'); ?>
+	</table>
+</fieldset>
+
+<fieldset id="gameMode-laps" class="gameinfos_laps" hidden="hidden">
+	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_laps.png" alt="" /><?php echo AdminServ::getGameModeName(4, true); ?></legend>
+	<table class="game_infos">
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Number of laps', 'LapsNbLaps'); ?>
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], Utils::t('Time limit').' <span>('.Utils::t('sec').')</span>', 'LapsTimeLimit'); ?>
+	</table>
+</fieldset>
+
+<fieldset id="gameMode-cup" class="gameinfos_cup" hidden="hidden">
+	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_cup.png" alt="" /><?php echo AdminServ::getGameModeName(5); ?></legend>
+	<table class="game_infos">
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Points limit', 'CupPointsLimit'); ?>
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Rounds per map', 'CupRoundsPerMap'); ?>
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Number of winners', 'CupNbWinners'); ?>
+		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'All WarmUp duration', 'CupWarmUpDuration'); ?>
+	</table>
+</fieldset>
\ No newline at end of file
diff --git a/resources/templates/gameinfos-general.tpl.php b/resources/templates/gameinfos-general.tpl.php
new file mode 100644
index 0000000..0f47111
--- /dev/null
+++ b/resources/templates/gameinfos-general.tpl.php
@@ -0,0 +1,90 @@
+<fieldset class="gameinfos_general">
+	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/restartrace.png" alt="" /><?php echo Utils::t('General'); ?></legend>
+	<table>
+		<?php if (AdminServAdminLevel::hasPermission('gameinfos_general_gamemode')): ?>
+			<tr>
+				<td class="key"><label for="NextGameMode"><?php echo Utils::t('Game mode'); ?></label></td>
+				<?php if ($data['gameInfos']['curr'] != null): ?>
+					<td class="value">
+						<input class="text width2" type="text" name="CurrGameMode" id="CurrGameMode" readonly="readonly" value="<?php echo AdminServ::getGameModeName($data['gameInfos']['curr']['GameMode']); ?>" />
+					</td>
+				<?php endif; ?>
+				<td class="value">
+					<select class="width2" name="NextGameMode" id="NextGameMode">
+						<?php echo AdminServUI::getGameModeList($data['gameInfos']['next']['GameMode']); ?>
+					</select>
+				</td>
+				<td class="preview"></td>
+			</tr>
+		<?php endif; ?>
+		<?php if (AdminServAdminLevel::hasPermission('gameinfos_general_options')): ?>
+			<tr>
+				<td class="key"><label for="NextChatTime"><?php echo Utils::t('Map end time'); ?> <span>(<?php echo Utils::t('sec'); ?>)</span></label></td>
+				<?php if ($data['gameInfos']['curr'] != null): ?>
+					<td class="value">
+						<input class="text width2" type="text" name="CurrChatTime" id="CurrChatTime" readonly="readonly" value="<?php echo TimeDate::millisecToSec($data['gameInfos']['curr']['ChatTime'] + 8000); ?>" />
+					</td>
+				<?php endif; ?>
+				<td class="value">
+					<input class="text width2" type="number" min="0" name="NextChatTime" id="NextChatTime" value="<?php echo TimeDate::millisecToSec($data['gameInfos']['next']['ChatTime'] + 8000); ?>" />
+				</td>
+				<td class="preview"></td>
+			</tr>
+			<tr>
+				<td class="key"><label for="NextFinishTimeout"><?php echo Utils::t('Round/lap end time'); ?> <span>(<?php echo Utils::t('sec'); ?>)</span></label></td>
+				<?php if ($data['gameInfos']['curr'] != null): ?>
+					<td class="value">
+						<input class="text width2" type="text" name="CurrFinishTimeout" id="CurrFinishTimeout" readonly="readonly" value="<?php if ($data['gameInfos']['curr']['FinishTimeout'] == 0): echo Utils::t('Default').' (15'.Utils::t('sec'); elseif ($data['gameInfos']['curr']['FinishTimeout'] == 1): echo Utils::t('Auto (based on map)'); else: echo TimeDate::millisecToSec($data['gameInfos']['curr']['FinishTimeout']); endif; ?>" />
+					</td>
+				<?php endif; ?>
+				<td class="value next">
+					<select class="width2" name="NextFinishTimeout" id="NextFinishTimeout"<?php if ($data['gameInfos']['next']['FinishTimeout'] > 1): echo ' hidden="hidden"'; endif; ?>>
+						<option value="0"<?php if ($data['gameInfos']['next']['FinishTimeout'] == 0): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Default');?> (15<?php echo Utils::t('sec'); ?>)</option>
+						<option value="1"<?php if ($data['gameInfos']['next']['FinishTimeout'] == 1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Auto (based on map)'); ?></option>
+						<option value="more"><?php echo Utils::t('Choose time'); ?></option>
+					</select>
+					<input class="text width2" type="number" min="0" name="NextFinishTimeoutValue" id="NextFinishTimeoutValue" value="<?php if ($data['gameInfos']['next']['FinishTimeout'] > 1): echo TimeDate::millisecToSec($data['gameInfos']['next']['FinishTimeout']); endif; ?>"<?php if ($data['gameInfos']['next']['FinishTimeout'] < 2): echo ' hidden="hidden"'; endif; ?> />
+				</td>
+				<td class="preview"<?php if ($data['gameInfos']['next']['FinishTimeout'] < 2): echo ' hidden="hidden"'; endif; ?>>
+					<a class="returnDefaultValue" href="?p=<?php echo USER_PAGE; ?>"><?php echo Utils::t('Return to the default value'); ?></a>
+				</td>
+			</tr>
+		<?php endif; ?>
+			<?php if (AdminServAdminLevel::hasPermission('gameinfos_general_warmup')): ?>
+				<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'All WarmUp duration', 'AllWarmUpDuration'); ?>
+			<?php endif; ?>
+		<?php if (AdminServAdminLevel::hasPermission('gameinfos_general_options')): ?>
+			<tr>
+				<td class="key"><label for="NextDisableRespawn"><?php echo Utils::t('Respawn'); ?></label></td>
+				<?php if ($data['gameInfos']['curr'] != null): ?>
+					<td class="value">
+						<input class="text width2" type="text" name="CurrDisableRespawn" id="CurrDisableRespawn" readonly="readonly" value="<?php echo ($data['gameInfos']['curr']['DisableRespawn'] === false) ? Utils::t('Enable') : Utils::t('Disable'); ?>" />
+					</td>
+				<?php endif; ?>
+				<td class="value">
+					<input class="text" type="checkbox" name="NextDisableRespawn" id="NextDisableRespawn" value=""<?php if ($data['gameInfos']['next']['DisableRespawn'] === false): echo ' checked="checked"'; endif; ?> />
+				</td>
+				<td class="preview"></td>
+			</tr>
+			<tr>
+				<td class="key"><label for="NextForceShowAllOpponents"><?php echo Utils::t('Force show of all opponents'); ?></label></td>
+				<?php if ($data['gameInfos']['curr'] != null): ?>
+					<td class="value">
+						<input class="text width2" type="text" name="CurrForceShowAllOpponents" id="CurrForceShowAllOpponents" readonly="readonly" value="<?php if ($data['gameInfos']['curr']['ForceShowAllOpponents'] == 0): echo Utils::t('Let player choose'); elseif ($data['gameInfos']['curr']['ForceShowAllOpponents'] == 1): echo Utils::t('All opponents'); else: echo $data['gameInfos']['curr']['ForceShowAllOpponents'].' '.Utils::t('minimal opponents'); endif; ?>" />
+					</td>
+				<?php endif; ?>
+				<td class="value next">
+					<select class="width2" name="NextForceShowAllOpponents" id="NextForceShowAllOpponents"<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] > 1): echo ' hidden="hidden"'; endif;?>>
+						<option value="0"<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] == 0): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Let player choose'); ?></option>
+						<option value="1"<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] == 1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('All opponents'); ?></option>
+						<option value="more"><?php echo Utils::t('Choose opponents number'); ?></option>
+					</select>
+					<input class="text width2" type="text" name="NextForceShowAllOpponentsValue" id="NextForceShowAllOpponentsValue" value="<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] > 1): echo $data['gameInfos']['next']['ForceShowAllOpponents']; endif; ?>"<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] < 2): echo ' hidden="hidden"'; endif; ?> />
+				</td>
+				<td class="preview"<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] < 2): echo ' hidden="hidden"'; endif; ?>>
+					<a class="returnDefaultValue" href="?p=<?php echo USER_PAGE; ?>"><?php echo Utils::t('Return to the default value'); ?></a>
+				</td>
+			</tr>
+		<?php endif; ?>
+	</table>
+</fieldset>
\ No newline at end of file
diff --git a/resources/templates/gameinfos.tpl.php b/resources/templates/gameinfos.tpl.php
new file mode 100644
index 0000000..ef760e9
--- /dev/null
+++ b/resources/templates/gameinfos.tpl.php
@@ -0,0 +1,61 @@
+<section class="cadre">
+	<h1><?php echo Utils::t('Game information'); ?></h1>
+	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+		<div class="content gameinfos">
+			<?php if (AdminServAdminLevel::hasPermission(array('gameinfos_general_gamemode', 'gameinfos_general_warmup', 'gameinfos_general_options'))): ?>
+				<?php echo AdminServUI::getTemplate('gameinfos-general'); ?>
+			<?php endif; ?>
+			
+			<?php if (SERVER_VERSION_NAME == 'ManiaPlanet' && AdminServ::checkDisplayTeamMode($data['gameInfos']['next']['GameMode'], $data['gameInfos']['next']['ScriptName']) && AdminServAdminLevel::hasPermission('gameinfos_teams_options')): ?>
+				<fieldset class="gameinfos_teaminfos">
+					<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/players.png" alt="" /><?php echo Utils::t('Team infos'); ?></legend>
+					<table>
+						<tr>
+							<td class="key"><label for="teamInfo1Name"><?php echo Utils::t('Team 1'); ?></label></td>
+							<td class="value">
+								<input class="text width2" type="text" name="teamInfo1Name" id="teamInfo1Name" value="<?php echo $data['teamInfo']['team1']['name']; ?>" />
+								<div class="colorSelectorWrapper">
+									<div id="colorPickerTeam1" class="colorSelector" title="<?php echo Utils::t('Color'); ?>"></div>
+									<input type="hidden" name="teamInfo1Color" id="teamInfo1Color" value="<?php echo $data['teamInfo']['team1']['color']; ?>" />
+									<input type="hidden" name="teamInfo1ColorHex" id="teamInfo1ColorHex" value="<?php echo $data['teamInfo']['team1']['colorhex']; ?>" />
+								</div>
+							</td>
+							<td class="value">
+								<input class="text width2" type="text" name="teamInfo1Country" id="teamInfo1Country" value="<?php echo $data['teamInfo']['team1']['country']; ?>" />
+							</td>
+							<td class="preview"></td>
+						</tr>
+						<tr>
+							<td class="key"><label for="teamInfo2Name"><?php echo Utils::t('Team 2'); ?></label></td>
+							<td class="value">
+								<input class="text width2" type="text" name="teamInfo2Name" id="teamInfo2Name" value="<?php echo $data['teamInfo']['team2']['name']; ?>" />
+								<div class="colorSelectorWrapper">
+									<div id="colorPickerTeam2" class="colorSelector" title="<?php echo Utils::t('Color'); ?>"></div>
+									<input type="hidden" name="teamInfo2Color" id="teamInfo2Color" value="<?php echo $data['teamInfo']['team2']['color']; ?>" />
+									<input type="hidden" name="teamInfo2ColorHex" id="teamInfo2ColorHex" value="<?php echo $data['teamInfo']['team2']['colorhex']; ?>" />
+								</div>
+							</td>
+							<td class="value">
+								<input class="text width2" type="text" name="teamInfo2Country" id="teamInfo2Country" value="<?php echo $data['teamInfo']['team2']['country']; ?>" />
+							</td>
+							<td class="preview"></td>
+						</tr>
+					</table>
+				</fieldset>
+			<?php endif; ?>
+			
+			<?php if (AdminServAdminLevel::hasPermission('gameinfos_gamemode_options')): ?>
+				<?php echo AdminServUI::getTemplate('gameinfos-gamemode'); ?>
+			<?php endif; ?>
+		</div>
+		
+		<?php if (SERVER_MATCHSET && AdminServAdminLevel::hasPermission('maps_matchsettings_save')): ?>
+			<div class="fleft options-checkbox">
+				<input class="text inline" type="checkbox" name="SaveCurrentMatchSettings" id="SaveCurrentMatchSettings"<?php if (AdminServConfig::AUTOSAVE_MATCHSETTINGS === true): echo ' checked="checked"'; endif; ?> value="" /><label for="SaveCurrentMatchSettings" title="<?php echo SERVER_MATCHSET; ?>"><?php echo Utils::t('Save the current MatchSettings'); ?></label>
+			</div>
+		<?php endif; ?>
+		<div class="fright save">
+			<input class="button light" type="submit" name="savegameinfos" id="savegameinfos" value="<?php echo Utils::t('Save'); ?>" />
+		</div>
+	</form>
+</section>
\ No newline at end of file
diff --git a/resources/templates/general.tpl.php b/resources/templates/general.tpl.php
new file mode 100644
index 0000000..82b587a
--- /dev/null
+++ b/resources/templates/general.tpl.php
@@ -0,0 +1,229 @@
+<section class="cadre left<?php if ($data['isTeamGameMode']): echo ' isTeamGameMode'; endif; ?>">
+	<h1><?php echo Utils::t('Current map'); ?></h1>
+	<form method="post" action=".">
+	<div class="content">
+		<table class="current_map">
+			<tr>
+				<td class="key"><?php echo Utils::t('Name'); ?></td>
+				<td class="value" id="map_name"><?php echo $data['serverInfo']['map']['name']; ?></td>
+			</tr>
+			<tr>
+				<td class="key"><?php echo Utils::t('Author'); ?></td>
+				<td class="value" id="map_author"><?php echo $data['serverInfo']['map']['author']; ?></td>
+			</tr>
+			<tr>
+				<td class="key"><?php echo Utils::t('Environment'); ?></td>
+				<td class="value" id="map_enviro"><?php echo $data['serverInfo']['map']['enviro']; ?><img src="<?php echo AdminServConfig::$PATH_RESOURCES .'images/env/'.strtolower($data['serverInfo']['map']['enviro']); ?>.png" alt="" /></td>
+			</tr>
+			<tr>
+				<td class="key"><?php echo Utils::t('Map UId'); ?></td>
+				<td class="value" id="map_uid"><?php echo $data['serverInfo']['map']['uid']; ?></td>
+			</tr>
+			<tr>
+				<td class="key"><?php echo Utils::t('Game mode'); ?></td>
+				<td class="value <?php echo strtolower($data['serverInfo']['srv']['gameModeName']); ?>" id="map_gamemode">
+					<?php if (isset($data['serverInfo']['srv']['gameModeScriptName'])): ?>
+						<?php echo $data['serverInfo']['srv']['gameModeScriptName']; ?> <span class="scriptName">(<?php echo $data['serverInfo']['srv']['gameModeName']; ?>)</span>
+					<?php else: ?>
+						<?php echo $data['serverInfo']['srv']['gameModeName']; ?>
+					<?php endif; ?>
+				</td>
+			</tr>
+			<?php if ($data['serverInfo']['map']['callvote']['login'] && AdminServAdminLevel::hasPermission('cancel_vote')): ?>
+				<tr>
+					<td class="key"><?php echo Utils::t('Current vote'); ?></td>
+					<td class="value" id="map_currentcallvote">
+						<?php echo $data['serverInfo']['map']['callvote']['login'].' : '.$data['serverInfo']['map']['callvote']['cmdname'].' ('.$data['serverInfo']['map']['callvote']['cmdparam'].')'; ?>
+						<input class="button light" type="submit" name="CancelVote" id="CancelVote" value="<?php echo Utils::t('Cancel vote'); ?>" />
+					</td>
+				</tr>
+			<?php endif; ?>
+			<?php if (AdminServ::isGameMode('Team', $data['serverInfo']['srv']['gameModeId']) && AdminServAdminLevel::hasPermission('force_scores')): ?>
+				<tr>
+					<td class="key"><?php echo Utils::t('Scores'); ?></td>
+					<td class="value" id="map_teamscore">
+						<span class="team_0" title="<?php echo Utils::t('Blue team'); ?>"></span>
+						<input class="text" type="number" min="0" name="ScoreTeamBlue" id="ScoreTeamBlue" value="<?php echo $data['serverInfo']['map']['scores']['blue']; ?>" />
+						<span class="team_1" title="<?php echo Utils::t('Red team'); ?>"></span>
+						<input class="text" type="number" min="0" name="ScoreTeamRed" id="ScoreTeamRed" value="<?php echo $data['serverInfo']['map']['scores']['red']; ?>" />
+						<input class="button light" type="submit" name="ForceScores" id="ForceScores" value="<?php echo Utils::t('Force the scores'); ?>" />
+					</td>
+				</tr>
+			<?php endif; ?>
+		</table>
+		<?php if ($data['serverInfo']['map']['thumb'] != null): ?>
+			<div id="map_thumbnail" data-text-thumbnail="<?php echo Utils::t('No thumbnail'); ?>">
+				<img src="data:image/jpeg;base64,<?php echo $data['serverInfo']['map']['thumb']; ?>" alt="<?php echo Utils::t('No thumbnail'); ?>" />
+			</div>
+		<?php endif; ?>
+	</div>
+	</form>
+	
+	<h1><?php echo Utils::t('Server'); ?></h1>
+	<div class="content">
+		<table>
+			<tr>
+				<td class="key"><?php echo Utils::t('Server name'); ?></td>
+				<td class="value" id="server_name"><?php echo $data['serverInfo']['srv']['name']; ?></td>
+			</tr>
+			<tr>
+				<td class="key"><?php echo Utils::t('Status'); ?></td>
+				<td class="value" id="server_status"><?php echo $data['serverInfo']['srv']['status']; ?></td>
+			</tr>
+			<tr>
+				<td class="key"><?php echo Utils::t('Server login'); ?></td>
+				<td class="value"><?php echo SERVER_LOGIN; ?></td>
+			</tr>
+			<tr>
+				<td class="key"><?php echo Utils::t('Connected on'); ?></td>
+				<td class="value" id="srv_version_name">
+					<?php if (defined('IS_RELAY') && IS_RELAY && isset($data['mainServerLogin']) && $data['mainServerLogin'] !== null): ?>
+						<?php echo $data['mainServerLogin']; ?> (<span class="<?php echo strtolower(SERVER_VERSION_NAME); ?>"><?php echo SERVER_VERSION_NAME; ?></span>)
+					<?php else: ?>
+						<span class="<?php echo strtolower(SERVER_VERSION_NAME); ?>"><?php echo SERVER_VERSION_NAME; ?></span>
+					<?php endif; ?>
+				</td>
+			</tr>
+			<tr>
+				<td class="key"><?php echo Utils::t('Dedicated version'); ?></td>
+				<td class="value"><?php echo SERVER_BUILD.' ('. SERVER_VERSION .')'; ?></td>
+			</tr>
+		</table>
+	</div>
+	
+	<?php if (AdminServAdminLevel::isType('SuperAdmin')): ?>
+		<h1><?php echo Utils::t('Statistics'); ?></h1>
+		<div class="content last">
+			<table>
+				<tr>
+					<td class="key"><?php echo Utils::t('Uptime'); ?></td>
+					<td class="value" id="network_uptime"><?php echo $data['serverInfo']['net']['uptime']; ?></td>
+				</tr>
+				<tr>
+					<td class="key"><?php echo Utils::t('Number of connections'); ?></td>
+					<td class="value" id="network_nbrconnection"><?php echo $data['serverInfo']['net']['nbrconnection']; ?></td>
+				</tr>
+				<tr>
+					<td class="key"><?php echo Utils::t('Average connection time'); ?></td>
+					<td class="value" id="network_meanconnectiontime"><?php echo $data['serverInfo']['net']['meanconnectiontime']; ?></td>
+				</tr>
+				<tr>
+					<td class="key"><?php echo Utils::t('Average number of players'); ?></td>
+					<td class="value" id="network_meannbrplayer"><?php echo $data['serverInfo']['net']['meannbrplayer']; ?></td>
+				</tr>
+				<tr>
+					<td class="key"><?php echo Utils::t('Recv net rate'); ?></td>
+					<td class="value" id="network_recvnetrate"><?php echo $data['serverInfo']['net']['recvnetrate']; ?></td>
+				</tr>
+				<tr>
+					<td class="key"><?php echo Utils::t('Send net rate'); ?></td>
+					<td class="value" id="network_sendnetrate"><?php echo $data['serverInfo']['net']['sendnetrate']; ?></td>
+				</tr>
+				<tr>
+					<td class="key"><?php echo Utils::t('Total receiving size'); ?></td>
+					<td class="value" id="network_totalreceivingsize"><?php echo $data['serverInfo']['net']['totalreceivingsize']; ?></td>
+				</tr>
+				<tr>
+					<td class="key"><?php echo Utils::t('Total sending size'); ?></td>
+					<td class="value" id="network_totalsendingsize"><?php echo $data['serverInfo']['net']['totalsendingsize']; ?></td>
+				</tr>
+			</table>
+		</div>
+	<?php endif; ?>
+</section>
+
+<section class="cadre right<?php if ($data['isTeamGameMode']): echo ' isTeamGameMode'; endif; ?>">
+	<h1><?php echo Utils::t('Players'); ?></h1>
+	<div class="title-detail">
+		<ul>
+			<li><a id="detailMode" href="." data-statusmode="<?php echo USER_MODE_GENERAL; ?>" data-textdetail="<?php echo Utils::t('Detailed mode'); ?>" data-textsimple="<?php echo Utils::t('Simple mode'); ?>"><?php echo (USER_MODE_GENERAL == 'detail') ? Utils::t('Simple mode') : Utils::t('Detailed mode'); ?></a></li>
+			<li class="last"><input type="checkbox" name="checkAll" id="checkAll" value=""<?php if (!is_array($data['serverInfo']['ply'])): echo ' disabled="disabled"'; endif; ?> /></li>
+		</ul>
+	</div>
+	
+	<!-- Liste des joueurs -->
+	<form method="post" action=".">
+	<div id="playerlist">
+		<table>
+			<thead>
+				<tr>
+					<?php if ($data['isTeamGameMode']): ?>
+						<th class="detailModeTh thleft"<?php if (USER_MODE_GENERAL == 'simple'): echo ' hidden="hidden"'; endif; ?>><a href="?sort=team"><?php echo Utils::t('Team'); ?></a></th>
+					<?php endif; ?>
+					<th class="firstTh <?php if (USER_MODE_GENERAL == 'simple' || !$data['isTeamGameMode']): echo 'thleft'; endif; ?>"><a href="?sort=nickname"><?php echo Utils::t('Nickname'); ?></a></th>
+					<?php if (!$data['isTeamGameMode']): ?>
+						<th class="detailModeTh"<?php if (USER_MODE_GENERAL == 'simple'): echo ' hidden="hidden"'; endif; ?>><a href="?sort=ladder"><?php echo Utils::t('Ladder'); ?></a></th>
+					<?php endif; ?>
+					<th><a href="?sort=login"><?php echo Utils::t('Login'); ?></a></th>
+					<th><a href="?sort=status"><?php echo Utils::t('Status'); ?></a></th>
+					<th class="thright"></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr class="table-separation"><td colspan="<?php echo ($data['isTeamGameMode']) ? '6' : '5'; ?>"></td></tr>
+				<?php if ($data['serverInfo']['nbp'] > 0): ?>
+					<?php $i = 0; ?>
+					<?php foreach ($data['serverInfo']['ply'] as $player): ?>
+						<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
+							<?php if ($data['isTeamGameMode'] && USER_MODE_GENERAL == 'detail'): ?>
+								<td class="detailModeTd imgleft"><span class="team_<?php echo $player['TeamId']; ?>" title="<?php echo $player['TeamName']; ?>">&nbsp;</span><?php echo $player['TeamName']; ?></td>
+							<?php endif; ?>
+							<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/solo.png" alt="" /><?php echo $player['NickName']; ?></td>
+							<?php if (!$data['isTeamGameMode']): ?>
+								<td class="detailModeTd imgleft"<?php if (USER_MODE_GENERAL == 'simple'): ' hidden="hidden"'; endif; ?>><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/leagueladder.png" alt="" /><?php echo $player['LadderRanking']; ?></td>
+							<?php endif; ?>
+							<td><?php echo $player['Login']; ?></td>
+							<td><?php echo $player['PlayerStatus']; ?></td>
+							<td class="checkbox"><input type="checkbox" name="player[]" value="<?php echo $player['Login']; ?>" /></td>
+						</tr>
+						<?php $i++; ?>
+					<?php endforeach; ?>
+				<?php else: ?>
+					<tr class="no-line">
+						<td class="center" colspan="<?php echo ($data['isTeamGameMode']) ? '6' : '5'; ?>"><?php echo $data['serverInfo']['ply']; ?></td>
+					</tr>
+				<?php endif; ?>
+			</tbody>
+		</table>
+	</div>
+	
+	<div class="options">
+		<div class="fleft">
+			<span class="nb-line"><?php echo $data['serverInfo']['nbp']; ?></span>
+		</div>
+		<div class="fright">
+			<div class="selected-files-label locked">
+				<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
+				<span class="selected-files-count">(0)</span>
+				<div class="selected-files-option">
+					<?php if (AdminServAdminLevel::hasPermission('player_ignore')): ?>
+						<input class="button dark" type="submit" name="IgnoreLoginList" id="IgnoreLoginList" value="<?php echo Utils::t('Ignore'); ?>" />
+					<?php endif; ?>
+					<?php if (AdminServAdminLevel::hasPermission('player_guest')): ?>
+						<input class="button dark" type="submit" name="GuestLoginList" id="GuestLoginList" value="<?php echo Utils::t('Guest'); ?>" />
+					<?php endif; ?>
+					<?php if (AdminServAdminLevel::hasPermission('player_ban')): ?>
+						<input class="button dark" type="submit" name="BanLoginList" id="BanLoginList" value="<?php echo Utils::t('Ban'); ?>" />
+					<?php endif; ?>
+					<?php if (AdminServAdminLevel::hasPermission('player_kick')): ?>
+						<input class="button dark" type="submit" name="KickLoginList" id="KickLoginList" value="<?php echo Utils::t('Kick'); ?>" />
+					<?php endif; ?>
+					<?php if ($data['isTeamGameMode'] && AdminServAdminLevel::hasPermission('player_changeteam')): ?>
+						<input class="button dark" type="submit" name="ForceBlueTeam" id="ForceBlueTeam" value="<?php echo Utils::t('Blue team'); ?>" />
+						<input class="button dark" type="submit" name="ForceRedTeam" id="ForceRedTeam" value="<?php echo Utils::t('Red team'); ?>" />
+					<?php endif; ?>
+					<?php if (AdminServAdminLevel::hasPermission('player_forcetospectator')): ?>
+						<input class="button dark" type="submit" name="ForceSpectatorList" id="ForceSpectatorList" value="<?php echo Utils::t('Spectator'); ?>" />
+					<?php endif; ?>
+					<?php if (AdminServAdminLevel::hasPermission('player_forcetoplayer')): ?>
+						<input class="button dark" type="submit" name="ForcePlayerList" id="ForcePlayerList" value="<?php echo Utils::t('Player'); ?>" />
+					<?php endif; ?>
+				</div>
+			</div>
+		</div>
+	</div>
+	
+	<input type="hidden" id="currentSort" name="currentSort" value="" />
+	<input type="hidden" id="isTeamGameMode" name="isTeamGameMode" value="<?php echo $data['isTeamGameMode']; ?>" />
+	</form>
+</section>
\ No newline at end of file
diff --git a/resources/templates/guestban.tpl.php b/resources/templates/guestban.tpl.php
new file mode 100644
index 0000000..577be4e
--- /dev/null
+++ b/resources/templates/guestban.tpl.php
@@ -0,0 +1,300 @@
+<section class="cadre left">
+	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+	<div id="banlist">
+		<h1>Banlist<?php if ($data['banlist']['count'] > 0): ' ('.$data['banlist']['count'].')'; endif; ?></h1>
+		<div class="title-detail">
+			<ul>
+				<li><a class="cleanList" href="?p=<?php echo USER_PAGE; ?>&amp;clean=banlist" data-empty="<?php echo Utils::t('The list is already empty.'); ?>"><?php echo Utils::t('Clean the list'); ?></a></li>
+				<li class="last"><input type="checkbox" name="checkAllBanlist" id="checkAllBanlist" value=""<?php if ($data['banlist']['count'] == 0): echo ' disabled="disabled"'; endif; ?> /></li>
+			</ul>
+		</div>
+		<table>
+			<thead>
+				<tr>
+					<th class="thleft"><?php echo Utils::t('Login'); ?></th>
+					<th><?php echo Utils::t('IP address'); ?></th>
+					<th><?php echo Utils::t('Client'); ?></th>
+					<th class="thright"></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr class="table-separation"><td colspan="4"></td></tr>
+				<?php if ($data['banlist']['count'] > 0): ?>
+					<?php $i = 0; ?>
+					<?php foreach ($data['banlist']['list'] as $player): ?>
+						<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
+							<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/solo.png" alt="" /><?php echo $player['Login']; ?></td>
+							<td><?php echo $player['IPAddress']; ?></td>
+							<td><?php echo $player['ClientName']; ?></td>
+							<td class="checkbox"><input type="checkbox" name="banlist[]" value="<?php echo $player['Login']; ?>" /></td>
+						</tr>
+						<?php $i++; ?>
+					<?php endforeach; ?>
+				<?php else: ?>
+					<tr class="no-line">
+						<td class="center" colspan="4"><?php echo Utils::t('No player'); ?></td>
+					</tr>
+				<?php endif; ?>
+			</tbody>
+		</table>
+	</div>
+	
+	<div id="blacklist">
+		<h1>Blacklist<?php if ($data['blacklist']['count'] > 0): echo ' ('.$data['blacklist']['count'].')'; endif; ?></h1>
+		<div class="title-detail">
+			<ul>
+				<li><a class="cleanList" href="?p=<?php echo USER_PAGE; ?>&amp;clean=blacklist" data-empty="<?php echo Utils::t('The list is already empty.'); ?>"><?php echo Utils::t('Clean the list'); ?></a></li>
+				<li class="last"><input type="checkbox" name="checkAllBlacklist" id="checkAllBlacklist" value=""<?php if ($data['blacklist']['count'] == 0): echo ' disabled="disabled"'; endif; ?> /></li>
+			</ul>
+		</div>
+		<table>
+			<thead>
+				<tr>
+					<th class="thleft"><?php echo Utils::t('Login'); ?></th>
+					<th class="thright"></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr class="table-separation"><td colspan="2"></td></tr>
+				<?php if ($data['blacklist']['count'] > 0): ?>
+					<?php $i = 0; ?>
+					<?php foreach ($data['blacklist']['list'] as $player): ?>
+						<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
+							<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/solo.png" alt="" /><?php echo $player['Login']; ?></td>
+							<td class="checkbox"><input type="checkbox" name="blacklist[]" value="<?php echo $player['Login']; ?>" /></td>
+						</tr>
+						<?php $i++; ?>
+					<?php endforeach; ?>
+				<?php else: ?>
+					<tr class="no-line">
+						<td class="center" colspan="2"><?php echo Utils::t('No player'); ?></td>
+					</tr>
+				<?php endif; ?>
+			</tbody>
+		</table>
+	</div>
+	
+	<div id="guestlist">
+		<h1>Guestlist<?php if ($data['guestlist']['count'] > 0): echo ' ('.$data['guestlist']['count'].')'; endif; ?></h1>
+		<div class="title-detail">
+			<ul>
+				<li><a class="cleanList" href="?p=<?php echo USER_PAGE; ?>&amp;clean=guestlist" data-empty="<?php echo Utils::t('The list is already empty.'); ?>"><?php echo Utils::t('Clean the list'); ?></a></li>
+				<li class="last"><input type="checkbox" name="checkAllGuestlist" id="checkAllGuestlist" value=""<?php if ($data['guestlist']['count'] == 0): echo ' disabled="disabled"'; endif; ?> /></li>
+			</ul>
+		</div>
+		<table>
+			<thead>
+				<tr>
+					<th class="thleft"><?php echo Utils::t('Login'); ?></th>
+					<th class="thright"></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr class="table-separation"><td colspan="2"></td></tr>
+				<?php if ($data['guestlist']['count'] > 0): ?>
+					<?php $i = 0; ?>
+					<?php foreach ($data['guestlist']['list'] as $player): ?>
+						<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
+							<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/solo.png" alt="" /><?php echo $player['Login']; ?></td>
+							<td class="checkbox"><input type="checkbox" name="guestlist[]" value="<?php echo $player['Login']; ?>" /></td>
+						</tr>
+						<?php $i++; ?>
+					<?php endforeach; ?>
+				<?php else: ?>
+					<tr class="no-line">
+						<td class="center" colspan="2"><?php echo Utils::t('No player'); ?></td>
+					</tr>
+				<?php endif; ?>
+			</tbody>
+		</table>
+	</div>
+	
+	<div id="ignorelist">
+		<h1>Ignorelist<?php if ($data['ignorelist']['count'] > 0): echo ' ('.$data['ignorelist']['count'].')'; endif; ?></h1>
+		<div class="title-detail">
+			<ul>
+				<li><a class="cleanList" href="?p=<?php echo USER_PAGE; ?>&amp;clean=ignorelist" data-empty="<?php echo Utils::t('The list is already empty.'); ?>"><?php echo Utils::t('Clean the list'); ?></a></li>
+				<li class="last"><input type="checkbox" name="checkAllIgnorelist" id="checkAllIgnorelist" value=""<?php if ($data['ignorelist']['count'] == 0): echo ' disabled="disabled"'; endif; ?> /></li>
+			</ul>
+		</div>
+		<table>
+			<thead>
+				<tr>
+					<th class="thleft"><?php echo Utils::t('Login'); ?></th>
+					<th class="thright"></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr class="table-separation"><td colspan="2"></td></tr>
+				<?php if ($data['ignorelist']['count'] > 0): ?>
+					<?php $i = 0; ?>
+					<?php foreach ($data['ignorelist']['list'] as $player): ?>
+						<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
+							<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/solo.png" alt="" /><?php echo $player['Login']; ?></td>
+							<td class="checkbox"><input type="checkbox" name="ignorelist[]" value="<?php echo $player['Login']; ?>" /></td>
+						</tr>
+						<?php $i++; ?>
+					<?php endforeach; ?>
+				<?php else: ?>
+					<tr class="no-line">
+						<td class="center" colspan="2"><?php echo Utils::t('No player'); ?></td>
+					</tr>
+				<?php endif; ?>
+			</tbody>
+		</table>
+	</div>
+	
+	<div class="options">
+		<div class="fright">
+			<div class="selected-files-label locked">
+				<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
+				<span class="selected-files-count">(0)</span>
+				<div class="selected-files-option">
+					<?php if (AdminServAdminLevel::hasPermission('guestban_addplayer')): ?>
+						<input class="button dark" type="submit" name="blackListPlayer" id="blackListPlayer" value="<?php echo Utils::t('Blacklist'); ?>" />
+					<?php endif; ?>
+					<?php if (AdminServAdminLevel::hasPermission('guestban_removeplayer')): ?>
+						<input class="button dark" type="submit" name="removeList" id="removeList" value="<?php echo Utils::t('Remove from the list'); ?>" />
+					<?php endif; ?>
+				</div>
+			</div>
+		</div>
+	</div>
+	</form>
+</section>
+
+<section class="cadre right">
+	<?php if (AdminServAdminLevel::hasPermission('guestban_addplayer')): ?>
+		<h1><?php echo Utils::t('Add'); ?></h1>
+		<div class="content last addPlayer">
+			<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+				<div>
+					<select class="width2" name="addPlayerList" id="addPlayerList"<?php if ($data['players']['count'] == 0): echo ' hidden="hidden"'; endif; ?>>
+						<option value="none"><?php echo Utils::t('Select a player'); ?></option>
+						<?php echo $data['players']['listOptions']; ?>
+						<option value="more"><?php echo Utils::t('Enter another login'); ?></option>
+					</select>
+					<input class="text width2" type="text" name="addPlayerLogin" id="addPlayerLogin" data-default-value="<?php echo Utils::t('Player login'); ?>" value="<?php echo Utils::t('Player login'); ?>"<?php if ($data['players']['count'] != 0): echo ' hidden="hidden"'; endif; ?> />
+					<select class="addPlayerTypeList" name="addPlayerTypeList" id="addPlayerTypeList">
+						<option value="none"><?php echo Utils::t('Add in the'); ?></option>
+						<option value="guestlist">Guestlist</option>
+						<option value="blacklist">Blacklist</option>
+					</select>
+					<input class="button light" type="submit" name="addPlayer" id="addPlayer" value="<?php echo Utils::t('Add'); ?>" />
+				</div>
+			</form>
+		</div>
+	<?php endif; ?>
+	
+	<?php if (isset($data['playlistDirectory']) && $data['playlistDirectory'] != 'Not directory'): ?>
+		<div id="playlists">
+			<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+				<h1>
+					<?php echo Utils::t('Playlists'); ?>
+					<?php if (AdminServAdminLevel::hasPermission('guestban_playlist_new')): ?>
+						<span id="form-new-playlist" hidden="hidden">
+							<select name="createPlaylistType" id="createPlaylistType">
+								<option value="none"><?php echo Utils::t('Type'); ?></option>
+								<option value="guestlist">Guestlist</option>
+								<option value="blacklist">Blacklist</option>
+							</select>
+							<input class="text" type="text" name="createPlaylistName" id="createPlaylistName" data-playlistname="<?php echo Utils::t('Playlist name'); ?>" value="<?php echo Utils::t('Playlist name'); ?>" />
+							<input class="button light" type="submit" name="createPlaylistValid" id="createPlaylistValid" value="<?php echo Utils::t('Create'); ?>" />
+						</span>
+					<?php endif; ?>
+				</h1>
+			</form>
+			<div class="title-detail">
+				<ul>
+					<?php if (AdminServAdminLevel::hasPermission('guestban_playlist_new')): ?>
+						<li><a id="clickNewPlaylist" href="" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-newplaylist="<?php echo Utils::t('New playlist'); ?>"><?php echo Utils::t('New playlist'); ?></a></li>
+					<?php endif; ?>
+					<li class="last"><input type="checkbox" name="checkAllPlaylists" id="checkAllPlaylists" value="" /></li>
+				</ul>
+			</div>
+			
+			<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+			<table>
+				<thead>
+					<tr>
+						<th class="thleft"><?php echo Utils::t('Playlist'); ?></th>
+						<th><?php echo Utils::t('Type'); ?></th>
+						<th><?php echo Utils::t('Contains'); ?></th>
+						<th><?php echo Utils::t('Modified'); ?></th>
+						<th class="thright"></th>
+					</tr>
+				</thead>
+				<tbody>
+					<tr class="table-separation"><td colspan="5"></td></tr>
+					<?php if (isset($data['playlistDirectory']['files']) && !empty($data['playlistDirectory']['files'])): ?>
+						<?php
+							$i = 0;
+							$defaultFilename = array(
+								'guestlist.txt',
+								'blacklist.txt',
+								'guestlist.xml',
+								'blacklist.xml',
+							);
+						?>
+						<?php foreach ($data['playlistDirectory']['files'] as $file): ?>
+							<?php if (in_array($file['filename'], $defaultFilename) || ($isDoubleExt = in_array(File::getDoubleExtension($file['filename']), AdminServConfig::$PLAYLIST_EXTENSION))): ?>
+								<?php
+									// Playlist data
+									$playlistData = AdminServ::getPlaylistData($data['gameDataDirectory'].'Config/'.$file['filename']);
+									if( isset($playlistData['logins']) ){
+										$countDataLogins = count($playlistData['logins']);
+										$nbPlayers = ($countDataLogins > 1) ? $countDataLogins.' '.Utils::t('players') : '1 '.Utils::t('player');
+									}
+									else{
+										$nbPlayers = '0 '.Utils::t('player');
+									}
+									
+									// Filename
+									$parseExtIndex = ($isDoubleExt) ? -13 : -4;
+									$filename = substr($file['filename'], 0, $parseExtIndex);
+								?>
+								<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
+									<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/finishgrey.png" alt="" /><span title="<?php echo $file['filename']; ?>"><?php echo $filename; ?></span></td>
+									<td class="center"><?php echo ucfirst($playlistData['type']); ?></td>
+									<td class="center"><?php echo $nbPlayers; ?></td>
+									<td class="center"><?php echo date('d-m-Y', $file['mtime']); ?></td>
+									<td class="checkbox">
+										<input type="checkbox" name="playlist[]" value="<?php echo $playlistData['type'].'|'.$file['filename']; ?>" />
+									</td>
+								</tr>
+								<?php $i++; ?>
+							<?php endif; ?>
+						<?php endforeach; ?>
+					<?php else: ?>
+						<tr class="no-line">
+							<td class="center" colspan="5"><?php echo Utils::t('No playlist'); ?></td>
+						</tr>
+					<?php endif; ?>
+				</tbody>
+			</table>
+			
+			<?php if (AdminServAdminLevel::hasPermission(array('guestban_playlist_save', 'guestban_playlist_load', 'guestban_playlist_delete'))): ?>
+				<div class="options">
+					<div class="fright">
+						<div class="selected-files-label locked">
+							<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
+							<span class="selected-files-count">(0)</span>
+							<div class="selected-files-option">
+								<?php if (AdminServAdminLevel::hasPermission('guestban_playlist_delete')): ?>
+									<input class="button dark" type="submit" name="deletePlaylist" id="deletePlaylist" value="<?php echo Utils::t('Delete'); ?>" />
+								<?php endif; ?>
+								<?php if (AdminServAdminLevel::hasPermission('guestban_playlist_load')): ?>
+									<input class="button dark" type="submit" name="loadPlaylist" id="loadPlaylist" value="<?php echo Utils::t('Load'); ?>" />
+								<?php endif; ?>
+								<?php if (AdminServAdminLevel::hasPermission('guestban_playlist_save')): ?>
+									<input class="button dark" type="submit" name="savePlaylist" id="savePlaylist" value="<?php echo Utils::t('Save '); ?>" />
+								<?php endif; ?>
+							</div>
+						</div>
+					</div>
+				</div>
+			<?php endif; ?>
+			</form>
+		</div>
+	<?php endif; ?>
+</section>
\ No newline at end of file
diff --git a/resources/templates/header.tpl.php b/resources/templates/header.tpl.php
new file mode 100644
index 0000000..323802d
--- /dev/null
+++ b/resources/templates/header.tpl.php
@@ -0,0 +1 @@
+<!DOCTYPE html><html lang="<?php echo USER_LANG; ?>">	<head>		<meta charset="UTF-8" />		<meta name="robots" content="noindex, nofollow" />		<meta name="viewport" content="width=335, initial-scale=1.0">		<title><?php if (isset($GLOBALS['page_title'])): echo $GLOBALS['page_title'].' | '; endif; echo AdminServUI::getTitle(); ?></title>		<link type="image/png" rel="icon" href="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/32/favicon.png" sizes="32x32" />		<?php echo AdminServUI::getCss(); ?>		<?php echo AdminServUI::getJS(); ?>	</head>	<body<?php if( isset($GLOBALS['body_class']) ){ echo ' class="'.$GLOBALS['body_class'].'"'; } ?>>		<div id="page">			<div id="page-inner">				<header>					<div id="header-inner">						<div class="logo-title">							<a href="./">								<?php if (AdminServConfig::LOGO): ?>									<span id="logo">										<img src="<?php echo AdminServConfig::$PATH_RESOURCES .'images/'. AdminServConfig::LOGO; ?>" alt="" />									</span>								<?php endif; ?>																<span class="title-subtitle">									<span id="title">										#<?php echo AdminServUI::getTitle('html'); ?>									</span>																		<?php if (AdminServConfig::SUBTITLE): ?>										<span id="subtitle">											<?php echo AdminServConfig::SUBTITLE; ?>										</span>									<?php endif; ?>								</span>							</a>						</div>												<div class="theme-lang">							<?php if (!empty(ExtensionConfig::$THEMES)): ?>								<div id="theme">									<?php echo AdminServUI::getThemeList( (isset(ExtensionConfig::$THEMES[USER_THEME])) ? array(USER_THEME => ExtensionConfig::$THEMES[USER_THEME]) : array() ); ?>								</div>							<?php endif; ?>														<?php if (!empty(ExtensionConfig::$LANG)): ?>								<div id="lang">									<?php echo AdminServUI::getLangList( (isset(ExtensionConfig::$LANG[USER_LANG])) ? array(USER_LANG => ExtensionConfig::$LANG[USER_LANG]) : array() ); ?>								</div>							<?php endif; ?>						</div>												<?php if (AdminServEvent::isLoggedIn()): ?>							<?php if (AdminServAdminLevel::hasPermission('speed_admin')): ?>								<div class="speed-admin">									<ul>										<li><a tabindex="-1" class="prev" href=".">PrevMap</a></li>										<li><a tabindex="-1" class="restart" href=".">RestartMap</a></li>										<li><a tabindex="-1" class="next" href=".">NextMap</a></li>										<li><a tabindex="-1" class="endround" href=".">ForceEndRound</a></li>									</ul>								</div>							<?php endif; ?>														<?php if (AdminServAdminLevel::hasPermission('switch_server')): ?>								<div class="switch-server">									<select tabindex="1" id="switchServerList" name="switchServerList">										<?php echo AdminServUI::getServerList(); ?>									</select>								</div>							<?php endif; ?>						<?php endif; ?>												<div id="error"<?php if (!isset($_SESSION['error'])): echo ' hidden="hidden"'; endif; ?>><?php if (isset($_SESSION['error']) && $_SESSION['error'] != null): echo $_SESSION['error']; unset($_SESSION['error']); endif; ?></div>						<div id="info"<?php if (!isset($_SESSION['info'])): echo ' hidden="hidden"'; endif; ?>><?php if (isset($_SESSION['info']) && $_SESSION['info'] != null): echo $_SESSION['info']; unset($_SESSION['info']); endif; ?></div>					</div>					<div id="header-color-line"></div>				</header>								<?php if (AdminServEvent::isLoggedIn()): ?>					<nav class="horizontal-nav">						<div id="nav-inner" class="menu-principal">							<ul class="menu-left">								<li class="accessgeneral"><a tabindex="2" accesskey="1" class="button light<?php if (USER_PAGE == 'index'): echo ' active'; endif; ?>" href="./"><?php echo Utils::t('General'); ?></a></li>								<?php if (AdminServAdminLevel::hasAccess('server_options')): ?>									<li><a tabindex="3" class="button light<?php if (USER_PAGE == 'srvopts'): echo ' active'; endif; ?>" href="?p=srvopts"><?php echo Utils::t('Server options'); ?></a></li>								<?php endif; ?>								<?php if (AdminServAdminLevel::hasAccess('game_infos')): ?>									<li><a tabindex="4" class="button light<?php if (USER_PAGE == 'gameinfos'): echo ' active'; endif; ?>" href="?p=gameinfos"><?php echo Utils::t('Game infos'); ?></a></li>								<?php endif; ?>								<?php if (AdminServAdminLevel::hasAccess('chat')): ?>									<li><a tabindex="5" class="button light<?php if (USER_PAGE == 'chat'): echo ' active'; endif; ?>" href="?p=chat"><?php echo Utils::t('Chat'); ?></a></li>								<?php endif; ?>								<?php if (AdminServAdminLevel::hasAccess('maps_list')): ?>									<li><a tabindex="6" class="button light<?php if (AdminServUI::isPageType('maps')): echo ' active'; endif; ?>" href="?p=maps-list"><?php echo Utils::t('Maps'); ?></a></li>								<?php endif; ?>							</ul>														<ul class="menu-right">								<?php if (AdminServAdminLevel::hasAccess('link_access_server')): ?>									<?php if (defined('IS_RELAY') && IS_RELAY): ?>										<li class="accesslink"><a tabindex="7" class="button light" href="<?php echo AdminServ::getProtocolLink('#spectate='. SERVER_LOGIN); ?>"><?php echo Utils::t('Access relay'); ?></a></li>									<?php else: ?>										<li class="accesslink"><a tabindex="8" class="button light" href="<?php echo AdminServ::getProtocolLink('#join='. SERVER_LOGIN); ?>"><?php echo Utils::t('Access server'); ?></a></li>									<?php endif; ?>								<?php endif; ?>								<?php if (AdminServPlugin::hasPlugin() && AdminServAdminLevel::hasAccess('plugins_list')): ?>									<li><a tabindex="9" class="button light<?php if (USER_PAGE == 'plugins-list' || USER_PLUGIN): echo ' active'; endif; ?>" href="?p=plugins-list"><?php echo Utils::t('Plugins'); ?></a></li>								<?php endif; ?>								<?php if (AdminServAdminLevel::hasAccess('guest_ban')): ?>									<li><a tabindex="10" class="button light<?php if (USER_PAGE == 'guestban'): echo ' active'; endif; ?>" href="?p=guestban"><?php echo Utils::t('Guest-Ban'); ?></a></li>								<?php endif; ?>								<li><a tabindex="11" class="button light" href="?logout"><?php echo Utils::t('Disconnect'); ?></a></li>							</ul>						</div>					</nav>				<?php elseif (AdminServUI::isPageType('config')): ?>					<nav class="horizontal-nav">						<div id="nav-inner" class="menu-principal">							<ul class="menu-left">								<?php if (OnlineConfig::ADD_ONLY !== true): ?>									<li><a class="button light<?php if (USER_PAGE == 'config-servers'): echo ' active'; endif; ?>" href="?p=config-servers"><?php echo Utils::t('Servers'); ?></a></li>								<?php endif; ?>								<li><a class="button light<?php if (USER_PAGE == 'config-addserver'): echo ' active'; endif; ?>" href="?p=config-addserver<?php if (defined('IS_SERVER_EDITION')): echo '&id='.$args['id']; endif; ?>"><?php echo (defined('IS_SERVER_EDITION')) ? Utils::t('Edit server') : Utils::t('Add server'); ?></a></li>								<?php $hasServer = AdminServServerConfig::hasServer(); ?>								<?php if (OnlineConfig::ADD_ONLY !== true && $hasServer): ?>									<li><a class="button light<?php if (USER_PAGE == 'config-serversorder'): echo ' active'; endif; ?>" href="?p=config-serversorder"><?php echo Utils::t('Servers order'); ?></a></li>								<?php endif; ?>								<?php if (OnlineConfig::ADMINLEVEL): ?>									<li><a class="button light<?php if (USER_PAGE == 'config-adminlevel'): echo ' active'; endif; ?>" href="?p=config-adminlevel"><?php echo Utils::t('Admin levels'); ?></a></li>									<li><a class="button light<?php if (USER_PAGE == 'config-addlevel'): echo ' active'; endif; ?>" href="?p=config-addlevel<?php if (defined('IS_LEVEL_EDITION')): echo '&id='.$args['id']; endif; ?>"><?php echo (defined('IS_LEVEL_EDITION')) ? Utils::t('Edit level') : Utils::t('Add level'); ?></a></li>									<li><a class="button light<?php if (USER_PAGE == 'config-levelsorder'): echo ' active'; endif; ?>" href="?p=config-levelsorder"><?php echo Utils::t('Levels order'); ?></a></li>								<?php endif; ?>							</ul>							<ul class="menu-right">								<?php if (OnlineConfig::PASSWORD != null): ?>									<li><a class="button light<?php if (USER_PAGE == 'config-password'): echo ' active'; endif; ?>" href="?p=config-password"><?php echo Utils::t('Change password'); ?></a></li>								<?php endif; ?>								<?php if ($hasServer): ?>									<li><a class="button light" href="./?logout"><?php echo Utils::t('Back'); ?></a></li>								<?php endif; ?>							</ul>						</div>					</nav>				<?php elseif (!isset($_SESSION['adminserv']['check_password']) && !isset($_SESSION['adminserv']['get_password'])): ?>					<nav id="connection">						<div id="connection-inner">							<form method="post" action=".">								<div class="connection-label">									<label for="as_server"><?php echo Utils::t('Server'); ?> :</label>									<select tabindex="1" name="as_server" id="as_server">										<?php echo AdminServUI::getServerList(); ?>									</select>																		<label for="as_password"><?php echo Utils::t('Password'); ?> :</label>									<input tabindex="2" class="text" type="password" name="as_password" id="as_password" value="" />																		<label for="as_adminlevel"><?php echo Utils::t('Admin level'); ?> :</label>									<select tabindex="3" name="as_adminlevel" id="as_adminlevel" data-error="<?php echo Utils::t('No server admin levels configured.'); ?>"></select>								</div>								<div class="connection-login">									<input tabindex="4" class="button light" type="submit" name="as_login" id="as_login" value="<?php echo Utils::t('Connection'); ?>" />								</div>							</form>						</div>					</nav>				<?php endif; ?>								<div id="content">					<div id="content-inner">
\ No newline at end of file
diff --git a/resources/templates/maps-creatematchset.tpl.php b/resources/templates/maps-creatematchset.tpl.php
new file mode 100644
index 0000000..f87c3ce
--- /dev/null
+++ b/resources/templates/maps-creatematchset.tpl.php
@@ -0,0 +1,178 @@
+<section class="maps hasMenu hasFolders">
+	<section class="cadre left menu">
+		<?php echo AdminServUI::getMapsMenuList(); ?>
+	</section>
+	
+	<section class="cadre middle folders">
+		<?php echo AdminServUI::getMapsDirectoryList($data['currentDir'], $args['directory']); ?>
+	</section>
+	
+	<form method="post" action="?p=<?php echo USER_PAGE.$data['hasDirectory']; ?>">
+	<section class="cadre right creatematchset">
+		<h1><?php echo $data['pageTitle'].' '.Utils::t('a MatchSettings'); ?></h1>
+		<div class="title-detail">
+			<ul>
+				<li class="last path"><?php echo $data['mapsDirectoryPath'].$args['directory']; ?></li>
+			</ul>
+		</div>
+		
+		<h2><?php echo Utils::t('MatchSettings name'); ?></h2>
+		<input class="text" type="text" name="matchSettingName" id="matchSettingName" value="<?php echo $data['matchSettings']['name']; ?>" />
+		<p class="ui-state-error" id="matchSettingNameExists" hidden="hidden"><span class="ui-icon ui-icon-alert"></span><?php echo Utils::t('The MatchSettings name already exist! It will be overwritten.'); ?></p>
+		
+		<h2><?php echo Utils::t('Maps'); ?></h2>
+		<div class="content maps">
+			<fieldset>
+				<div class="mapsSelection">
+					<select name="mapsDirectoryList" id="mapsDirectoryList">
+						<option value="currentServerSelection"><?php echo Utils::t('Server selection'); ?></option>
+						<option value="<?php echo $data['mapsDirectoryPath']; ?>"><?php echo Utils::t('Root'); ?></option>
+						<?php if (!empty($data['directoryList'])): ?>
+							<?php foreach ($data['directoryList'] as $dir): ?>
+								<option value="<?php echo $dir['path']; ?>"><?php echo $dir['level'].$dir['name']; ?></option>
+							<?php endforeach; ?>
+						<?php endif; ?>
+					</select>
+					<input class="button light" type="button" name="mapImportSelection" id="mapImportSelection" value="<?php echo Utils::t('Make selection'); ?>" />
+					<input class="button light" type="button" name="mapImport" id="mapImport" value="<?php echo Utils::t('Import all folder'); ?>" />
+					<div id="mapImportSelectionDialog" data-title="<?php echo Utils::t('Make selection'); ?>" data-select="<?php echo Utils::t('Select'); ?>" hidden="hidden">
+						<table>
+							<thead>
+								<tr>
+									<th class="thleft"><?php echo Utils::t('Map'); ?></th>
+									<th><?php echo Utils::t('Environment'); ?></th>
+									<th><?php echo Utils::t('Type'); ?></th>
+									<th><?php echo Utils::t('Author'); ?></th>
+									<th class="thright"><input type="checkbox" name="checkAllMapImport" id="checkAllMapImport" value="" /></th>
+								</tr>
+							</thead>
+							<tbody>
+							</tbody>
+						</table>
+					</div>
+				</div>
+				
+				<div class="mapsSelected">
+					<p><?php echo Utils::t('MatchSettings selected maps:'); ?> <span id="nbMapSelected"><?php echo $data['matchSettings']['nbm']; ?></span></p>
+					<input class="button light" type="button" name="mapSelection" id="mapSelection" value="<?php echo Utils::t('View the MatchSettings selection'); ?>" />
+					<div id="mapSelectionDialog" data-title="<?php echo Utils::t('MatchSettings selection'); ?>" data-remove="<?php echo Utils::t('Remove map from the selection'); ?>" data-close="<?php echo Utils::t('Close'); ?>" hidden="hidden">
+						<table>
+							<thead>
+								<tr>
+									<th class="thleft"><?php echo Utils::t('Map'); ?></th>
+									<th><?php echo Utils::t('Environment'); ?></th>
+									<th><?php echo Utils::t('Type'); ?></th>
+									<th><?php echo Utils::t('Author'); ?></th>
+									<th class="thright"></th>
+								</tr>
+							</thead>
+							<tbody>
+							</tbody>
+						</table>
+					</div>
+				</div>
+			</fieldset>
+		</div>
+		
+		<h2><?php echo Utils::t('Game information'); ?></h2>
+		<div class="content gameinfos">
+			<?php echo AdminServUI::getTemplate('gameinfos-general'); ?>
+			<?php echo AdminServUI::getTemplate('gameinfos-gamemode'); ?>
+		</div>
+		
+		<h2><?php echo Utils::t('HotSeat'); ?></h2>
+		<div class="content">
+			<fieldset>
+				<table>
+					<tr>
+						<td class="key"><label for="hotSeatGameMode"><?php echo Utils::t('Game mode'); ?></label></td>
+						<td class="value">
+							<select class="width2" name="hotSeatGameMode" id="hotSeatGameMode">
+								<?php echo AdminServUI::getGameModeList($data['matchSettings']['hotseat']['GameMode']); ?>
+							</select>
+						</td>
+						<td class="preview"></td>
+					</tr>
+					<tr>
+						<td class="key"><label for="hotSeatTimeLimit"><?php echo Utils::t('Time limit'); ?></label></td>
+						<td class="value">
+							<input class="text width2" type="number" min="0" name="hotSeatTimeLimit" id="hotSeatTimeLimit" value="<?php echo TimeDate::millisecToSec($data['matchSettings']['hotseat']['TimeLimit']); ?>" />
+						</td>
+						<td class="preview"></td>
+					</tr>
+					<tr>
+						<td class="key"><label for="hotSeatCountRound"><?php echo Utils::t('Rounds count'); ?></label></td>
+						<td class="value">
+							<input class="text width2" type="number" min="0" name="hotSeatCountRound" id="hotSeatCountRound" value="<?php echo $data['matchSettings']['hotseat']['RoundsCount']; ?>" />
+						</td>
+						<td class="preview"></td>
+					</tr>
+				</table>
+			</fieldset>
+		</div>
+		
+		<h2><?php echo Utils::t('Filter'); ?></h2>
+		<div class="content">
+			<fieldset>
+				<table>
+					<tr>
+						<td class="key"><label for="filterIsLan"><?php echo Utils::t('Lan'); ?></label></td>
+						<td class="value">
+							<input class="text" type="checkbox" name="filterIsLan" id="filterIsLan"<?php if ($data['matchSettings']['filter']['IsLan']): echo ' checked="checked"'; endif; ?> value="" />
+						</td>
+						<td class="preview"></td>
+					</tr>
+					<tr>
+						<td class="key"><label for="filterIsInternet"><?php echo Utils::t('Internet'); ?></label></td>
+						<td class="value">
+							<input class="text" type="checkbox" name="filterIsInternet" id="filterIsInternet"<?php if ($data['matchSettings']['filter']['IsInternet']): echo ' checked="checked"'; endif; ?> value="" />
+						</td>
+						<td class="preview"></td>
+					</tr>
+					<tr>
+						<td class="key"><label for="filterIsSolo"><?php echo Utils::t('Solo'); ?></label></td>
+						<td class="value">
+							<input class="text" type="checkbox" name="filterIsSolo" id="filterIsSolo"<?php if ($data['matchSettings']['filter']['IsSolo']): echo ' checked="checked"'; endif; ?> value="" />
+						</td>
+						<td class="preview"></td>
+					</tr>
+					<tr>
+						<td class="key"><label for="filterIsHotSeat"><?php echo Utils::t('HotSeat'); ?></label></td>
+						<td class="value">
+							<input class="text" type="checkbox" name="filterIsHotSeat" id="filterIsHotSeat"<?php if ($data['matchSettings']['filter']['IsHotseat']): echo ' checked="checked"'; endif; ?> value="" />
+						</td>
+						<td class="preview"></td>
+					</tr>
+					<tr>
+						<td class="key"><label for="filterSortIndex"><?php echo Utils::t('Sort index'); ?></label></td>
+						<td class="value">
+							<input class="text width2" type="number" min="0" name="filterSortIndex" id="filterSortIndex" value="<?php echo $data['matchSettings']['filter']['SortIndex']; ?>" />
+						</td>
+						<td class="preview"></td>
+					</tr>
+					<tr>
+						<td class="key"><label for="filterRandomMaps"><?php echo Utils::t('Random map order'); ?></label></td>
+						<td class="value">
+							<input class="text" type="checkbox" name="filterRandomMaps" id="filterRandomMaps"<?php if ($data['matchSettings']['filter']['RandomMapOrder']): echo ' checked="checked"'; endif; ?> value="" />
+						</td>
+						<td class="preview"></td>
+					</tr>
+					<tr>
+						<td class="key"><label for="filterDefaultGameMode"><?php echo Utils::t('Default game mode'); ?></label></td>
+						<td class="value">
+							<select class="width2" name="filterDefaultGameMode" id="filterDefaultGameMode">
+								<?php echo AdminServUI::getGameModeList($data['matchSettings']['filter']['ForceDefaultGameMode']); ?>
+							</select>
+						</td>
+						<td class="preview"></td>
+					</tr>
+				</table>
+			</fieldset>
+		</div>
+		
+		<div class="fright save">
+			<input class="button light" type="submit" name="savematchsetting" id="savematchsetting" data-nomap="<?php echo Utils::t('No map selected for the MatchSettings.'); ?>" value="<?php echo Utils::t('Save'); ?>" />
+		</div>
+	</section>
+	</form>
+</section>
\ No newline at end of file
diff --git a/resources/templates/maps-directorylist.tpl.php b/resources/templates/maps-directorylist.tpl.php
new file mode 100644
index 0000000..eb4a68b
--- /dev/null
+++ b/resources/templates/maps-directorylist.tpl.php
@@ -0,0 +1,77 @@
+<!-- Titre + nouveau dossier -->
+<form id="createFolderForm" method="post" action="?p=<?php echo USER_PAGE; ?>&amp;d=<?php echo $data['currentPath']; ?>">
+	<h1>
+		<?php echo Utils::t('Dossiers'); ?>
+		<?php if ($data['showOptions'] && AdminServAdminLevel::hasPermission('folder_new')): ?>
+			<span id="form-new-folder" hidden="hidden">
+				<input class="text" type="text" name="newFolderName" id="newFolderName" value="" />
+				<input class="button light" type="submit" name="newFolderValid" id="newFolderValid" value="ok" />
+			</span>
+		<?php endif; ?>
+	</h1>
+	<?php if ($data['showOptions'] && AdminServAdminLevel::hasPermission('folder_new')): ?>
+		<div class="title-detail"><a href="." id="newfolder" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-new="<?php echo Utils::t('New'); ?>"><?php echo Utils::t('New'); ?></a></div>
+	<?php endif; ?>
+</form>
+
+<!-- Liste des dossiers -->
+<div class="folder-list">
+	<ul>
+		<!-- Dossier parent  -->
+		<?php if ($data['currentPath']): ?>
+			<li>
+				<a href="./?p=<?php echo USER_PAGE.(($data['parentPath']) ? '&amp;d='.$data['parentPath'] : ''); ?>">
+					<img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/back.png" alt="" />
+					<span class="dir-name"><?php echo Utils::t('Parent folder'); ?></span>
+				</a>
+			</li>
+		<?php endif; ?>
+		
+		<!-- Dossiers -->
+		<?php if (!empty($data['folders'])): ?>
+			<?php foreach ($data['folders'] as $dir => $values): ?>
+				<li>
+					<a href="./?p=<?php echo USER_PAGE; ?>&amp;d=<?php echo urlencode($data['currentPath'].$dir); ?>/">
+						<span class="dir-name"><?php echo $dir; ?></span>
+						<span class="dir-info"><?php echo $values['nb_file']; ?></span>
+					</a>
+				</li>
+			<?php endforeach; ?>
+		<?php else: ?>
+			<li class="no-result"><?php echo Utils::t('No folder'); ?></li>
+		<?php endif; ?>
+	</ul>
+</div>
+
+<!-- Options de dossier -->
+<?php if ($data['showOptions'] && $data['currentPath'] && AdminServAdminLevel::hasPermission(array('folder_new', 'folder_rename', 'folder_move', 'folder_delete'))): ?>
+	<?php $currentDir = basename($data['currentPath']); ?>
+	<form id="optionFolderForm" method="post" action="?p=<?php echo USER_PAGE; ?>&amp;d=<?php echo $data['currentPath']; ?>">
+		<div class="option-folder-list">
+			<h3><?php echo Utils::t('Folder options'); ?><span class="arrow-down">&nbsp;</span></h3>
+			<ul hidden="hidden">
+				<?php if (AdminServAdminLevel::hasPermission('folder_rename')): ?>
+					<li><a class="button light rename" id="renameFolder" href="."><?php echo Utils::t('Rename'); ?></a></li>
+				<?php endif; ?>
+				<?php if (AdminServAdminLevel::hasPermission('folder_move')): ?>
+					<li><a class="button light move" id="moveFolder" href="."><?php echo Utils::t('Move'); ?></a></li>
+				<?php endif; ?>
+				<?php if (AdminServAdminLevel::hasPermission('folder_delete')): ?>
+					<li><a class="button light delete" id="deleteFolder" href="." data-confirm-text="<?php echo Utils::t('Do you really want to remove this folder !currentDir?', array('!currentDir' => $currentDir)); ?>>"><?php echo Utils::t('Delete'); ?></a></li>
+				<?php endif; ?>
+			</ul>
+		</div>
+		<input type="hidden" name="optionFolderHiddenFieldAction" id="optionFolderHiddenFieldAction" value="" />
+		<input type="hidden" name="optionFolderHiddenFieldValue" id="optionFolderHiddenFieldValue" value="" />
+		<div id="renameFolderForm" class="option-form" hidden="hidden" data-title="<?php echo Utils::t('Rename folder'); ?>" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-rename="<?php echo Utils::t('Rename'); ?>">
+			<ul>
+				<li>
+					<span class="rename-map-name"><?php echo $currentDir; ?></span>
+					<span class="rename-map-arrow">&nbsp;</span>
+					<input class="text width2" type="text" name="renameFolderNewName" id="renameFolderNewName" value="<?php echo $currentDir; ?>" />
+				</li>
+			</ul>
+		</div>
+		<div id="moveFolderForm" class="option-form" hidden="hidden" data-title="<?php echo Utils::t('Move folder'); ?>" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-move="<?php echo Utils::t('Move'); ?>" data-root="<?php echo Utils::t('Root'); ?>" data-movethefolder="<?php echo Utils::t('Move folder <b>!currentDir</b> in:', array('!currentDir' => $currentDir)); ?>"></div>
+	</form>
+<?php endif; ?>
\ No newline at end of file
diff --git a/resources/templates/maps-list.tpl.php b/resources/templates/maps-list.tpl.php
new file mode 100644
index 0000000..b6cd0e2
--- /dev/null
+++ b/resources/templates/maps-list.tpl.php
@@ -0,0 +1,90 @@
+<section class="maps hasMenu">
+	<section class="cadre left menu">
+		<?php echo AdminServUI::getMapsMenuList(); ?>
+	</section>
+	
+	<section class="cadre right list">
+		<h1><?php echo Utils::t('List'); ?></h1>
+		<div class="title-detail">
+			<ul>
+				<?php if ($data['maps']['nbm']['count'] > 25): ?>
+					<li><a id="scrollToCurrentMap" href="#currentMap"><?php echo Utils::t('Go to the current map'); ?></a></li>
+				<?php endif; ?>
+				<li><a id="detailMode" href="." data-statusmode="<?php echo USER_MODE_MAPS; ?>" data-textdetail="<?php echo Utils::t('Detailed mode'); ?>" data-textsimple="<?php echo Utils::t('Simple mode'); ?>"><?php echo (USER_MODE_MAPS == 'detail') ? Utils::t('Simple mode') : Utils::t('Detailed mode'); ?></a></li>
+				<li class="last"><input type="checkbox" name="checkAll" id="checkAll" value=""<?php if (!is_array($data['maps']['lst'])): echo ' disabled="disabled"'; endif; ?> /></li>
+			</ul>
+		</div>
+		
+		<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+		<div id="maplist">
+			<table>
+				<thead>
+					<tr>
+						<th class="thleft"><?php echo Utils::t('Map'); ?></th>
+						<th><?php echo Utils::t('Environment'); ?></th>
+						<th><?php echo Utils::t('Author'); ?></th>
+						<th class="detailModeTh"<?php if (USER_MODE_MAPS == 'simple'): echo ' hidden="hidden"'; endif; ?>><?php echo Utils::t('Gold time'); ?></th>
+						<th class="detailModeTh"<?php if (USER_MODE_MAPS == 'simple'): echo ' hidden="hidden"'; endif; ?>><?php echo Utils::t('Cost'); ?></th>
+						<th class="thright"></th>
+					</tr>
+				</thead>
+				<tbody>
+					<tr class="table-separation"><td colspan="6"></td></tr>
+					<?php if ($data['maps']['nbm']['count'] > 0 ): ?>
+						<?php $i = 0;  ?>
+						<?php foreach ($data['maps']['lst'] as $id => $map): ?>
+							<tr<?php if ($id == $data['maps']['cid']): echo ' id="currentMap"'; endif; ?> class="<?php echo ($i%2) ? 'even' : 'odd'; if ($id == $data['maps']['cid']): echo ' current'; endif; ?>">
+								<td class="imgleft">
+									<img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/map.png" alt="" />
+									<span title="<?php echo $map['FileName']; ?>"><?php echo $map['Name']; ?></span>
+									<?php if (USER_MODE_MAPS == 'detail'): ?>
+										<span class="detailModeTd"><?php echo $map['UId']; ?></span>
+									<?php endif; ?>
+								</td>
+								<td class="imgcenter"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/env/<?php echo strtolower($map['Environment']); ?>.png" alt="" /><?php echo $map['Environment']; ?></td>
+								<td><?php echo $map['Author']; ?></td>
+								<td<?php if (USER_MODE_MAPS == 'simple'): echo ' hidden="hidden"'; endif; ?>><?php echo $map['GoldTime']; ?></td>
+								<td<?php if (USER_MODE_MAPS == 'simple'): echo ' hidden="hidden"'; endif; ?>><?php echo $map['CopperPrice']; ?></td>
+								<td class="checkbox">
+									<?php if ($id != $data['maps']['cid']): ?>
+										<input type="checkbox" name="map[]" value="<?php echo $map['FileName']; ?>" />
+									<?php endif; ?>
+								</td>
+							</tr>
+							<?php $i++; ?>
+						<?php endforeach; ?>
+					<?php else: ?>
+						<tr class="no-line">
+							<td class="center" colspan="6"><?php echo $data['maps']['lst']; ?></td>
+						</tr>
+					<?php endif; ?>
+				</tbody>
+			</table>
+		</div>
+		
+		<div class="options">
+			<div class="fleft">
+				<span class="nb-line"><?php echo $data['maps']['nbm']['count'].' '.$data['maps']['nbm']['title']; ?></span>
+			</div>
+			<?php if (AdminServAdminLevel::hasPermission(array('maps_list_moveaftercurrent', 'maps_list_removetolist'))): ?>
+				<div class="fright">
+					<div class="selected-files-label locked">
+						<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
+						<span class="selected-files-count">(0)</span>
+						<div class="selected-files-option">
+							<?php if (AdminServAdminLevel::hasPermission('maps_list_removetolist')): ?>
+								<input class="button dark" type="submit" name="removeMap" id="removeMap" value="<?php echo Utils::t('Delete'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_list_moveaftercurrent')): ?>
+								<input class="button dark" type="submit" name="chooseNextMap" id="chooseNextMap" value="<?php echo Utils::t('Move after the current map'); ?>" />
+							<?php endif; ?>
+						</div>
+					</div>
+				</div>
+			<?php endif; ?>
+		</div>
+		
+		<input type="hidden" id="currentSort" name="currentSort" value="" />
+		</form>
+	</section>
+</section>
\ No newline at end of file
diff --git a/resources/templates/maps-local.tpl.php b/resources/templates/maps-local.tpl.php
new file mode 100644
index 0000000..53dfb4c
--- /dev/null
+++ b/resources/templates/maps-local.tpl.php
@@ -0,0 +1,121 @@
+<section class="maps hasMenu hasFolders">
+	<section class="cadre left menu">
+		<?php echo AdminServUI::getMapsMenuList(); ?>
+	</section>
+	
+	<section class="cadre middle folders">
+		<?php echo AdminServUI::getMapsDirectoryList($data['currentDir'], $args['directory']); ?>
+	</section>
+	
+	<section class="cadre right local">
+		<h1><?php echo Utils::t('Local'); ?></h1>
+		<div class="title-detail">
+			<ul>
+				<li><div class="path"><?php echo $data['mapsDirectoryPath'].$args['directory']; ?></div></li>
+				<li class="last"><input type="checkbox" name="checkAll" id="checkAll" value=""<?php if (!is_array($data['maps']['lst'])): echo ' disabled="disabled"'; endif; ?> /></li>
+			</ul>
+		</div>
+		
+		<form method="post" action="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>">
+		<div id="maplist">
+			<table>
+				<thead>
+					<tr>
+						<th class="thleft"><a href="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>&amp;sort=name"><?php echo Utils::t('Map'); ?></a></th>
+						<th><a href="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>&amp;sort=env"><?php echo Utils::t('Environment'); ?></a></th>
+						<th><a href="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>&amp;sort=type"><?php echo Utils::t('Type'); ?></a></th>
+						<th><a href="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>&amp;sort=author"><?php echo Utils::t('Author'); ?></a></th>
+						<th class="thright"></th>
+					</tr>
+				</thead>
+				<tbody>
+					<tr class="table-separation"><td colspan="4"></td></tr>
+					<?php if ($data['maps']['nbm']['count'] > 0): ?>
+						<?php $i = 0; ?>
+						<?php foreach ($data['maps']['lst'] as $id => $map): ?>
+							<?php
+								// Map sur le serveur
+								if($map['OnServer']){
+									$mapImg = 'loadmap';
+									$mapClass = ' onserver';
+								}
+								else{
+									$mapImg = 'map';
+									$mapClass = null;
+								}
+								// Map récente
+								if($map['Recent']){
+									$mapClass .= ' recent';
+								}
+							?>
+							<tr class="<?php echo ($i%2) ? 'even' : 'odd'; echo $mapClass; ?>">
+								<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/<?php echo $mapImg; ?>.png" alt="" /><span title="<?php echo $map['FileName']; ?>"><?php echo $map['Name']; ?></span></td>
+								<td class="imgcenter"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/env/<?php echo strtolower($map['Environment']); ?>.png" alt="" /><?php echo $map['Environment']; ?></td>
+								<td><span title="<?php echo $map['Type']['FullName']; ?>"><?php echo $map['Type']['Name']; ?></span></td>
+								<td><?php echo $map['Author']; ?></td>
+								<td class="checkbox"><input type="checkbox" name="map[]" value="<?php echo $map['FileName']; ?>" /></td>
+							</tr>
+							<?php $i++; ?>
+						<?php endforeach; ?>
+					<?php else: ?>
+						<tr class="no-line">
+							<td class="center" colspan="4">
+								<?php if (is_array($data['maps'])): ?>
+									<?php echo $data['maps']['lst']; ?>
+								<?php else: ?>
+									<?php echo $data['maps']; ?>
+								<?php endif; ?>
+							</td>
+						</tr>
+					<?php endif; ?>
+				</tbody>
+			</table>
+		</div>
+		
+		<div class="options" data-mapisused="<?php echo Utils::t('The map,is currently used by the server.'); ?>">
+			<div class="fleft">
+				<span class="nb-line"><?php if (is_array($data['maps'])): echo $data['maps']['nbm']['count'].' '.$data['maps']['nbm']['title']; endif; ?></span>
+			</div>
+			<?php if (AdminServAdminLevel::hasPermission(array('maps_local_add', 'maps_local_insert', 'maps_local_download', 'maps_local_rename', 'maps_local_move', 'maps_local_delete'))): ?>
+				<div class="fright">
+					<div class="selected-files-label locked">
+						<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
+						<span class="selected-files-count">(0)</span>
+						<div class="selected-files-option">
+							<?php if (AdminServAdminLevel::hasPermission('maps_local_delete')): ?>
+								<input class="button dark" type="submit" name="deleteMap" id="deleteMap" value="<?php echo Utils::t('Delete'); ?>" data-confirm="<?php echo Utils::t('Do you really want to remove this selection?'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_local_move')): ?>
+								<input class="button dark" type="button" name="moveMap" id="moveMap" value="<?php echo Utils::t('Move'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_local_rename')): ?>
+								<input class="button dark" type="button" name="renameMap" id="renameMap" value="<?php echo Utils::t('Rename'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_local_download')): ?>
+								<input class="button dark" type="submit" name="downloadMap" id="downloadMap" value="<?php echo Utils::t('Download'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_local_insert')): ?>
+								<input class="button dark" type="submit" name="insertMap" id="insertMap" value="<?php echo Utils::t('Insert'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_local_add')): ?>
+								<input class="button dark" type="submit" name="addMap" id="addMap" value="<?php echo Utils::t('Add'); ?>" />
+							<?php endif; ?>
+						</div>
+					</div>
+				</div>
+			<?php endif; ?>
+			<?php if (AdminServAdminLevel::hasPermission('maps_local_rename')): ?>
+				<div id="form-rename-map" class="option-form" hidden="hidden" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-rename="<?php echo Utils::t('Rename'); ?>" data-autorename="<?php echo Utils::t('Replace the special characters'); ?>"></div>
+			<?php endif; ?>
+			<?php if (AdminServAdminLevel::hasPermission('maps_local_move')): ?>
+				<div id="form-move-map" class="option-form" hidden="hidden" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-move="<?php echo Utils::t('Move'); ?>" data-inthefolder="<?php echo Utils::t('in the folder:'); ?>" data-root="<?php echo Utils::t('Root'); ?>"></div>
+			<?php endif; ?>
+		</div>
+		<?php if (SERVER_MATCHSET && AdminServAdminLevel::hasPermission('maps_matchsettings_save')): ?>
+			<div class="fleft options-checkbox">
+				<input class="text inline" type="checkbox" name="SaveCurrentMatchSettings" id="SaveCurrentMatchSettings"<?php if (AdminServConfig::AUTOSAVE_MATCHSETTINGS === true): echo ' checked="checked"'; endif; ?> value="" /><label for="SaveCurrentMatchSettings" title="<?php echo SERVER_MATCHSET; ?>"><?php echo Utils::t('Save the current MatchSettings'); ?></label>
+			</div>
+		<?php endif; ?>
+		</form>
+	</section>
+</section>
\ No newline at end of file
diff --git a/resources/templates/maps-matchset.tpl.php b/resources/templates/maps-matchset.tpl.php
new file mode 100644
index 0000000..10584a1
--- /dev/null
+++ b/resources/templates/maps-matchset.tpl.php
@@ -0,0 +1,87 @@
+<section class="maps hasMenu hasFolders">
+	<section class="cadre left menu">
+		<?php echo AdminServUI::getMapsMenuList(); ?>
+	</section>
+	
+	<section class="cadre middle folders">
+		<?php echo AdminServUI::getMapsDirectoryList($data['currentDir'], $args['directory']); ?>
+	</section>
+	
+	<section class="cadre right matchset">
+		<h1><?php echo Utils::t('MatchSettings'); ?></h1>
+		<div class="title-detail">
+			<ul>
+				<li class="path"><?php echo $data['mapsDirectoryPath'].$args['directory']; ?></li>
+				<li class="last"><input type="checkbox" name="checkAll" id="checkAll" value="" /></li>
+			</ul>
+		</div>
+		
+		<form method="post" action="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>">
+		<div id="matchsetlist">
+			<table>
+				<thead>
+					<tr>
+						<th class="thleft"><a href="?sort=name"><?php echo Utils::t('Name'); ?></a></th>
+						<th><a href="?sort=nbm"><?php echo Utils::t('Contains'); ?></a></th>
+						<th><a href="?sort=mtime"><?php echo Utils::t('Modified'); ?></a></th>
+						<th class="thright"></th>
+					</tr>
+				</thead>
+				<tbody>
+					<tr class="table-separation"><td colspan="4"></td></tr>
+					<?php if ($data['matchsettingsList']['nbm']['count'] > 0): ?>
+						<?php $i = 0; ?>
+						<?php foreach ($data['matchsettingsList']['lst'] as $id => $matchset): ?>
+							<tr class="<?php echo ($i%2) ? 'even' : 'odd'; if ($matchset['Recent']): echo ' recent'; endif; ?>">
+								<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/finishgrey.png" alt="" /><span title="<?php echo $matchset['FileName']; ?>"><?php echo $matchset['Name']; ?></span></td>
+								<td><?php echo $matchset['Nbm']; ?></td>
+								<td><?php echo date('d/m/Y', $matchset['Mtime']); ?></td>
+								<td class="checkbox"><input type="checkbox" name="matchset[]" value="<?php echo $matchset['FileName']; ?>" /></td>
+							</tr>
+							<?php $i++; ?>
+						<?php endforeach; ?>
+					<?php else: ?>
+						<tr class="no-line">
+							<td class="center" colspan="4"><?php echo $data['matchsettingsList']['lst']; ?></td>
+						</tr>
+					<?php endif; ?>
+				</tbody>
+			</table>
+		</div>
+		
+		<div class="options">
+			<div class="fleft">
+				<span class="nb-line"><?php if (is_array($data['matchsettingsList']['nbm'])): echo $data['matchsettingsList']['nbm']['count'].' '.$data['matchsettingsList']['nbm']['title']; endif; ?></span>
+			</div>
+			<?php if (AdminServAdminLevel::hasPermission(array('maps_matchsettings_save', 'maps_matchsettings_load', 'maps_matchsettings_add', 'maps_matchsettings_insert', 'maps_matchsettings_edit', 'maps_matchsettings_delete'))): ?>
+				<div class="fright">
+					<div class="selected-files-label locked">
+						<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
+						<span class="selected-files-count">(0)</span>
+						<div class="selected-files-option">
+							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_delete')): ?>
+								<input class="button dark" type="submit" name="deleteMatchset" id="deleteMatchset" value="<?php echo Utils::t('Delete'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_edit')): ?>
+								<input class="button dark" type="submit" name="editMatchset" id="editMatchset" value="<?php echo Utils::t('Edit'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_insert')): ?>
+								<input class="button dark" type="submit" name="insertMatchset" id="insertMatchset" value="<?php echo Utils::t('Insert'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_add')): ?>
+								<input class="button dark" type="submit" name="addMatchset" id="addMatchset" value="<?php echo Utils::t('Add'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_load')): ?>
+								<input class="button dark" type="submit" name="loadMatchset" id="loadMatchset" value="<?php echo Utils::t('Load'); ?>" />
+							<?php endif; ?>
+							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_save')): ?>
+								<input class="button dark" type="submit" name="saveMatchset" id="saveMatchset" value="<?php echo Utils::t('Save '); ?>" />
+							<?php endif; ?>
+						</div>
+					</div>
+				</div>
+			<?php endif; ?>
+		</div>
+		</form>
+	</section>
+</section>
\ No newline at end of file
diff --git a/resources/templates/maps-menu.tpl.php b/resources/templates/maps-menu.tpl.php
new file mode 100644
index 0000000..abc7404
--- /dev/null
+++ b/resources/templates/maps-menu.tpl.php
@@ -0,0 +1,11 @@
+<?php if (!empty($data['menuList'])): ?>
+	<nav class="vertical-nav">
+		<ul>
+			<?php foreach ($data['menuList'] as $page => $title): ?>
+				<?php if (AdminServAdminLevel::hasAccess($page)): ?>
+					<li><a <?php if (USER_PAGE == $page): echo 'class="active"'; endif; ?>href="?p=<?php echo $page; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>"><?php echo Utils::t($title); ?></a></li>
+				<?php endif; ?>
+			<?php endforeach; ?>
+		</ul>
+	</nav>
+<?php endif; ?>
\ No newline at end of file
diff --git a/resources/templates/maps-order.tpl.php b/resources/templates/maps-order.tpl.php
new file mode 100644
index 0000000..ef5d78e
--- /dev/null
+++ b/resources/templates/maps-order.tpl.php
@@ -0,0 +1,72 @@
+<section class="maps hasMenu">
+	<section class="cadre left menu">
+		<?php echo AdminServUI::getMapsMenuList(); ?>
+	</section>
+	
+	<section class="cadre right order">
+		<h1><?php echo Utils::t('Order'); ?></h1>
+		<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+			<h2><?php echo Utils::t('Automatic sort'); ?></h2>
+			<div class="autoSortMode options-radio-inline">
+				<ul>
+					<li class="ui-state-default">
+						<input class="text" type="radio" name="sortMode" id="sortModeName" value="name" />
+						<div class="name"><?php echo Utils::t('Name'); ?></div>
+						<div class="icon">
+							<span class="ui-icon ui-icon-arrowthick-1-n"></span>
+							<span class="ui-icon ui-icon-arrowthick-1-s"></span>
+						</div>
+					</li>
+					<li class="ui-state-default">
+						<input class="text" type="radio" name="sortMode" id="sortModeEnv" value="env" />
+						<div class="name"><?php echo Utils::t('Environment'); ?></div>
+						<div class="icon">
+							<span class="ui-icon ui-icon-arrowthick-1-n"></span>
+							<span class="ui-icon ui-icon-arrowthick-1-s"></span>
+						</div>
+					</li>
+					<li class="ui-state-default">
+						<input class="text" type="radio" name="sortMode" id="sortModeAuthor" value="author" />
+						<div class="name"><?php echo Utils::t('Author'); ?></div>
+						<div class="icon">
+							<span class="ui-icon ui-icon-arrowthick-1-n"></span>
+							<span class="ui-icon ui-icon-arrowthick-1-s"></span>
+						</div>
+					</li>
+					<li class="ui-state-default">
+						<input class="text" type="radio" name="sortMode" id="sortModeRand" value="rand" />
+						<div class="name"><?php echo Utils::t('Random'); ?></div>
+					</li>
+				</ul>
+			</div>
+			
+			<h2><?php echo Utils::t('Manual sort'); ?></h2>
+			<div class="content">
+				<ul id="sortableMapList">
+					<?php if (!empty($data['maps'])): ?>
+						<?php foreach ($data['maps']['lst'] as $id => $map): ?>
+							<li class="ui-state-default">
+								<div class="ui-icon ui-icon-arrowthick-2-n-s"></div>
+								<div class="order-map-name" title="<?php echo $map['FileName']; ?>"><?php echo $map['Name']; ?></div>
+								<div class="order-map-env"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/env/<?php echo strtolower($map['Environment']); ?>.png" alt="" /><?php echo $map['Environment']; ?></div>
+								<div class="order-map-author"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/mapauthor.png" alt="" /><?php echo $map['Author']; ?></div>
+							</li>
+						<?php endforeach; ?>
+					<?php endif; ?>
+				</ul>
+			</div>
+			
+			<?php if (SERVER_MATCHSET && AdminServAdminLevel::hasPermission('maps_matchsettings_save')): ?>
+				<div class="fleft options-checkbox">
+					<input class="text inline" type="checkbox" name="SaveCurrentMatchSettings" id="SaveCurrentMatchSettings"<?php if (AdminServConfig::AUTOSAVE_MATCHSETTINGS === true): echo ' checked="checked"'; endif; ?> value="" /><label for="SaveCurrentMatchSettings" title="<?php echo SERVER_MATCHSET; ?>"><?php echo Utils::t('Save the current MatchSettings'); ?></label>
+				</div>
+			<?php endif; ?>
+			<div class="fright save">
+				<input class="button light" type="button" id="reset" name="reset" value="<?php echo Utils::t('Reset'); ?>" />
+				<input class="button light" type="submit" id="save" name="save" value="<?php echo Utils::t('Save'); ?>" />
+				<input type="hidden" id="list" name="list" value="" />
+				<input type="hidden" id="jsonlist" name="jsonlist" value="<?php echo htmlspecialchars( json_encode($data['maps']) ); ?>" />
+			</div>
+		</form>
+	</section>
+</section>
\ No newline at end of file
diff --git a/resources/templates/maps-upload.tpl.php b/resources/templates/maps-upload.tpl.php
new file mode 100644
index 0000000..22c0fe0
--- /dev/null
+++ b/resources/templates/maps-upload.tpl.php
@@ -0,0 +1,59 @@
+<section class="maps hasMenu<?php if (defined('IS_LOCAL') && IS_LOCAL): echo ' hasFolders'; endif; ?>">
+	<section class="cadre left menu">
+		<?php echo AdminServUI::getMapsMenuList(); ?>
+	</section>
+	
+	<?php if (defined('IS_LOCAL') && IS_LOCAL): ?>
+		<section class="cadre middle folders">
+			<?php echo AdminServUI::getMapsDirectoryList($data['currentDir'], $args['directory']); ?>
+		</section>
+	<?php endif; ?>
+	
+	<section class="cadre right upload">
+		<h1><?php echo Utils::t('Send'); ?></h1>
+		<div class="title-detail path"><?php echo $data['mapsDirectoryPath'].$args['directory']; ?></div>
+		
+		<h2><?php echo Utils::t('Transfer mode'); ?></h2>
+		<div class="transferMode options-radio-inline">
+			<ul>
+				<?php if (AdminServAdminLevel::hasPermission('maps_upload_add')): ?>
+					<li class="selected">
+						<input class="text" type="radio" name="transferMode" id="transferModeAdd" value="add" checked="checked" />
+						<div class="name"><span><?php echo Utils::t('Add'); ?></span> <?php echo Utils::t('at the end of list'); ?></div>
+					</li>
+				<?php endif; ?>
+				<?php if (AdminServAdminLevel::hasPermission('maps_upload_insert')): ?>
+					<li>
+						<input class="text" type="radio" name="transferMode" id="transferModeInsert" value="insert" />
+						<div class="name"><span><?php echo Utils::t('Insert'); ?></span> <?php echo Utils::t('after current map'); ?></div>
+					</li>
+				<?php endif; ?>
+				<?php if (AdminServAdminLevel::hasPermission('maps_upload_folder')): ?>
+					<li>
+						<input class="text" type="radio" name="transferMode" id="transferModeLocal" value="local" />
+						<div class="name"><span><?php echo Utils::t('Send'); ?></span> <?php echo Utils::t('only in the folder'); ?></div>
+					</li>
+				<?php endif; ?>
+			</ul>
+		</div>
+		
+		<h2><?php echo Utils::t('Options'); ?></h2>
+		<div class="options-checkbox">
+			<ul>
+				<?php if (SERVER_MATCHSET && AdminServAdminLevel::hasPermission('maps_matchsettings_save')): ?>
+					<li>
+						<input class="text inline" type="checkbox" name="SaveCurrentMatchSettings" id="SaveCurrentMatchSettings"<?php if (AdminServConfig::AUTOSAVE_MATCHSETTINGS === true): echo ' checked="checked"'; endif; ?> value="" />
+						<label for="SaveCurrentMatchSettings" title="<?php echo SERVER_MATCHSET; ?>"><?php echo Utils::t('Save the current MatchSettings'); ?></label>
+					</li>
+				<?php endif; ?>
+				<li>
+					<input class="text inline" type="checkbox" name="GotoListMaps" id="GotoListMaps" value="maps" checked="checked" />
+					<label for="GotoListMaps"><?php echo Utils::t('Go to the maps list when upload is complete'); ?></label>
+				</li>
+			</ul>
+		</div>
+		
+		<h2><?php echo Utils::t('Upload'); ?></h2>
+		<div id="formUpload" class="loader" data-mapspagename="maps-list" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-failed="<?php echo Utils::t('Failed'); ?>" data-uploadfile="<?php echo Utils::t('Upload a file'); ?>" data-dropfiles="<?php echo Utils::t('Drop files here to upload'); ?>" data-uploadnotfinished="<?php echo Utils::t('Upload not finished'); ?>" data-from="<?php echo Utils::t('from'); ?>" data-kb="<?php echo Utils::t('Kb'); ?>" data-mb="<?php echo Utils::t('Mb'); ?>" data-type-error="<?php echo Utils::t('{file} has invalid extension. Only {extensions} are allowed.'); ?>" data-size-error="<?php echo Utils::t('{file} is too large, maximum file size is {sizeLimit}.'); ?>" data-minsize-error="<?php echo Utils::t('{file} is too small, minimum file size is {minSizeLimit}.'); ?>" data-empty-error="<?php echo Utils::t('{file} is empty, please select files again without it.'); ?>" data-onleave="<?php echo Utils::t('The file was not uploaded. Upload has been cancelled or a server error occurred.'); ?>"></div>
+	</section>
+</section>
\ No newline at end of file
diff --git a/resources/templates/page-error.tpl.php b/resources/templates/page-error.tpl.php
new file mode 100644
index 0000000..0d3963d
--- /dev/null
+++ b/resources/templates/page-error.tpl.php
@@ -0,0 +1,9 @@
+<section class="cadre">
+	<h1><?php echo $data['errorTitle']; ?></h1>
+	
+	<?php if ($data['errorMessage']): ?>
+		<div class="content">
+			<p><?php echo $data['errorMessage']; ?></p>
+		</div>
+	<?php endif; ?>
+</section>
\ No newline at end of file
diff --git a/resources/templates/plugins-list.tpl.php b/resources/templates/plugins-list.tpl.php
new file mode 100644
index 0000000..8644b18
--- /dev/null
+++ b/resources/templates/plugins-list.tpl.php
@@ -0,0 +1,38 @@
+<section class="plugins hasMenu">
+	<section class="cadre left menu">
+		<?php echo AdminServPlugin::getMenuList(); ?>
+	</section>
+	
+	<section class="cadre right">
+		<h1><?php echo Utils::t('Plugins'); ?></h1>
+		<div class="title-detail">
+			<ul>
+				<li class="last">
+					<?php echo $data['nbplugins']['count'].' '.$data['nbplugins']['title']; ?>
+				</li>
+			</ul>
+		</div>
+		<div class="content">
+			<p><?php echo Utils::t('Plugins are extensions to add features to Adminserv.'); ?></p>
+		</div>
+		
+		<h2><?php echo Utils::t('Install a plugin'); ?></h2>
+		<div class="content">
+			<p><?php echo Utils::t('See all plugins:'); ?> <a href="http://dl.zone-kev717.info/adminserv/plugins"><?php echo Utils::t('Click here'); ?></a></p>
+			<p>- <?php echo Utils::t('Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.'); ?><br />
+			- <?php echo Utils::t('In the Configuration Extension, add the name of the plugin folder previously added.'); ?></p>
+			<p>
+				<code>
+					public static $PLUGINS = array(<br />
+					&nbsp;&nbsp;&nbsp;&nbsp;'PluginName',<br />
+					);
+				</code>
+			</p>
+		</div>
+		
+		<h2><?php echo Utils::t('Create a new plugin'); ?></h2>
+		<div class="content">
+			<?php echo Utils::t('<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values ​​in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>'); ?>
+		</div>
+	</section>
+</section>
\ No newline at end of file
diff --git a/resources/templates/srvopts.tpl.php b/resources/templates/srvopts.tpl.php
new file mode 100644
index 0000000..3bade54
--- /dev/null
+++ b/resources/templates/srvopts.tpl.php
@@ -0,0 +1,245 @@
+<section class="cadre">
+	<h1><?php echo Utils::t('Server options'); ?></h1>
+	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
+		<div class="content">
+			<?php if (AdminServAdminLevel::hasPermission(array('srvopts_general_name', 'srvopts_general_comment', 'srvopts_general_serverpassword', 'srvopts_general_spectatorpassword', 'srvopts_general_nbplayers', 'srvopts_general_nbspectators'))): ?>
+				<fieldset class="srvopts_general">
+					<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/servers.png" alt="" /><?php echo Utils::t('General'); ?></legend>
+					<table>
+						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_name')): ?>
+							<tr class="serverName">
+								<td class="key"><label for="ServerName"><?php echo Utils::t('Server name'); ?></label></td>
+								<td class="value" colspan="3">
+									<input class="text width3" type="text" name="Name" id="ServerName" maxlength="75" value="<?php echo $data['srvOpt']['Name']; ?>" />
+								</td>
+								<td class="preview">[<span id="serverNameHtml"><?php echo $data['srvOpt']['NameHtml']; ?></span>]</td>
+							</tr>
+						<?php endif; ?>
+						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_comment')): ?>
+							<tr class="serverComment">
+								<td class="key"><label for="ServerComment"><?php echo Utils::t('Comment'); ?></label></td>
+								<td class="value" colspan="3">
+									<textarea class="width3" name="Comment" id="ServerComment" maxlength="255"><?php echo $data['srvOpt']['Comment']; ?></textarea>
+								</td>
+								<td class="preview">[<span id="serverCommentHtml"><?php echo $data['srvOpt']['CommentHtml']; ?></span>]</td>
+							</tr>
+						<?php endif; ?>
+						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_playerpassword')): ?>
+							<tr>
+								<td class="key"><label for="ServerPassword"><?php echo Utils::t('Player password'); ?></label></td>
+								<td class="value" colspan="3">
+									<input class="text width3" type="text" name="Password" id="ServerPassword" value="<?php echo $data['srvOpt']['Password']; ?>" />
+								</td>
+								<td class="preview"></td>
+							</tr>
+						<?php endif; ?>
+						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_spectatorpassword')): ?>
+							<tr>
+								<td class="key"><label for="SpectatorPassword"><?php echo Utils::t('Spectator password'); ?></label></td>
+								<td class="value" colspan="3">
+									<input class="text width3" type="text" name="PasswordForSpectator" id="SpectatorPassword" value="<?php echo $data['srvOpt']['PasswordForSpectator']; ?>" />
+								</td>
+								<td class="preview"></td>
+							</tr>
+						<?php endif; ?>
+						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_nbplayers')): ?>
+							<tr>
+								<td class="key"><label for="NextMaxPlayers"><?php echo Utils::t('Nb max of players'); ?></label></td>
+								<td class="value col2">
+									<input class="text width1" type="text" name="CurrentMaxPlayers" id="CurrentMaxPlayers" readonly="readonly" value="<?php echo $data['srvOpt']['CurrentMaxPlayers']; ?>" />
+								</td>
+								<td class="key col3"><label for="NextMaxPlayers"><?php echo Utils::t('Next value'); ?></label></td>
+								<td class="value">
+									<input class="text width1" type="number" min="0" name="NextMaxPlayers" id="NextMaxPlayers" value="<?php echo $data['srvOpt']['NextMaxPlayers']; ?>" />
+								</td>
+								<td class="preview"></td>
+							</tr>
+						<?php endif; ?>
+						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_nbspectators')): ?>
+							<tr>
+								<td class="key"><label for="NextMaxSpectators"><?php echo Utils::t('Nb max of spectators'); ?></label></td>
+								<td class="value col2">
+									<input class="text width1" type="text" name="CurrentMaxSpectators" id="CurrentMaxSpectators" readonly="readonly" value="<?php echo $data['srvOpt']['CurrentMaxSpectators']; ?>" />
+								</td>
+								<td class="key col3"><label for="NextMaxSpectators"><?php echo Utils::t('Next value'); ?></label></td>
+								<td class="value">
+									<input class="text width1" type="number" min="0" name="NextMaxSpectators" id="NextMaxSpectators" value="<?php echo $data['srvOpt']['NextMaxSpectators']; ?>" />
+								</td>
+								<td class="preview"></td>
+							</tr>
+						<?php endif; ?>
+					</table>
+				</fieldset>
+			<?php endif; ?>
+			
+			<?php if (AdminServAdminLevel::hasPermission('srvopts_advanced')): ?>
+				<fieldset class="srvopts_advanced">
+					<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/options.png" alt="" /><?php echo Utils::t('Advanced'); ?></legend>
+					<table>
+						<tr>
+							<td class="key"><label for="IsP2PUpload"><?php echo Utils::t('P2P Upload'); ?></label></td>
+							<td class="value col2">
+								<input class="text" type="checkbox" name="IsP2PUpload" id="IsP2PUpload"<?php if ($data['srvOpt']['IsP2PUpload'] != 0): echo ' checked="checked"'; endif; ?> value="" />
+							</td>
+							<td class="key col3"><label for="IsP2PDownload"><?php echo Utils::t('P2P Download'); ?></label></td>
+							<td class="value">
+								<input class="text" type="checkbox" name="IsP2PDownload" id="IsP2PDownload"<?php if ($data['srvOpt']['IsP2PDownload'] != 0): echo ' checked="checked"'; endif; ?> value="" />
+							</td>
+							<td class="preview"></td>
+						</tr>
+						<tr>
+							<td class="key"><label for="NextLadderMode"><?php echo Utils::t('Ladder mode'); ?></label></td>
+							<td class="value col2">
+								<input class="text width1" type="text" name="CurrentLadderMode" id="CurrentLadderMode" readonly="readonly" value="<?php echo $data['srvOpt']['CurrentLadderModeName']; ?>" />
+							</td>
+							<td class="key col3"><label for="NextLadderMode"><?php echo Utils::t('Next value'); ?></label></td>
+							<td class="value">
+								<select class="width1" name="NextLadderMode" id="NextLadderMode">
+									<option value="0"<?php if ($data['srvOpt']['NextLadderMode'] == 0): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Inactive'); ?></option>
+									<option value="1"<?php if ($data['srvOpt']['NextLadderMode'] == 1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Forced'); ?></option>
+								</select>
+							</td>
+							<td class="preview"></td>
+						</tr>
+						<tr>
+							<td class="key"><label for="NextVehicleNetQuality"><?php echo Utils::t('Vehicles quality'); ?></label></td>
+							<td class="value col2">
+								<input class="text width1" type="text" name="CurrentVehicleNetQuality" id="CurrentVehicleNetQuality" readonly="readonly" value="<?php echo $data['srvOpt']['CurrentVehicleNetQualityName']; ?>" />
+							</td>
+							<td class="key col3"><label for="NextVehicleNetQuality"><?php echo Utils::t('Next value'); ?></label></td>
+							<td class="value">
+								<select class="width1" name="NextVehicleNetQuality" id="NextVehicleNetQuality">
+									<option value="0"<?php if ($data['srvOpt']['NextVehicleNetQuality'] == 0): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Fast'); ?></option>
+									<option value="1"<?php if ($data['srvOpt']['NextVehicleNetQuality'] == 1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('High'); ?></option>
+								</select>
+							</td>
+							<td class="preview"></td>
+						</tr>
+						<tr>
+							<td class="key"><label for="NextCallVoteTimeOut"><?php echo Utils::t('Vote expiration'); ?> <span>(<?php echo Utils::t('sec'); ?>)</span></label></td>
+							<td class="value col2">
+								<input class="text width1" type="text" name="CurrentCallVoteTimeOut" id="CurrentCallVoteTimeOut" readonly="readonly" value="<?php echo TimeDate::millisecToSec($data['srvOpt']['CurrentCallVoteTimeOut']); ?>" />
+							</td>
+							<td class="key col3"><label for="NextCallVoteTimeOut"><?php echo Utils::t('Next value'); ?></label></td>
+							<td class="value">
+								<input class="text width1" type="number" min="0" name="NextCallVoteTimeOut" id="NextCallVoteTimeOut" value="<?php echo TimeDate::millisecToSec($data['srvOpt']['NextCallVoteTimeOut']); ?>" />
+							</td>
+							<td class="preview"></td>
+						</tr>
+						<tr>
+							<td class="key"><label for="CallVoteRatio"><?php echo Utils::t('Vote ratio'); ?></label></td>
+							<td class="value" colspan="4">
+								<select name="callVoteRatioDisabled" id="callVoteRatioDisabled"<?php if ($data['srvOpt']['CallVoteRatio'] > -1): echo ' hidden="hidden"'; endif; ?>>
+									<option value="-1"<?php if ($data['srvOpt']['CallVoteRatio'] == -1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Disable'); ?></option>
+									<option value="0"<?php if ($data['srvOpt']['CallVoteRatio'] > -1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Enable'); ?></option>
+								</select>
+								<input class="text" type="number" min="0" max="1" step=".1" name="CallVoteRatio" id="CallVoteRatio" value="<?php echo $data['srvOpt']['CallVoteRatio']; ?>"<?php if ($data['srvOpt']['CallVoteRatio'] == -1): echo ' hidden="hidden"'; endif; ?> />
+								<a class="returnDefaultValue" id="resetCallVoteRatio" href="?p=<?php echo USER_PAGE; ?>"<?php if ($data['srvOpt']['CallVoteRatio'] == -1): echo ' hidden="hidden"'; endif; ?>><?php echo Utils::t('Disable vote ratio'); ?></a>
+							</td>
+						</tr>
+						<?php if (SERVER_VERSION_NAME == 'ManiaPlanet'): ?>
+							<tr>
+								<td class="key"><label for="ClientInputsMaxLatency"><?php echo Utils::t('Client inputs max latency'); ?></label></td>
+								<td class="value" colspan="4">
+									<select name="ClientInputsMaxLatency" id="ClientInputsMaxLatency"<?php if ($data['srvOpt']['ClientInputsMaxLatency'] > 0): echo ' hidden="hidden"'; endif; ?>>
+										<option value="0"><?php echo Utils::t('Automatic'); ?></option>
+										<option value="more"><?php echo Utils::t('Choose number'); ?></option>
+									</select>
+									<input class="text" type="number" min="0" name="ClientInputsMaxLatencyValue" id="ClientInputsMaxLatencyValue" value="<?php echo $data['srvOpt']['ClientInputsMaxLatency']; ?>"<?php if ($data['srvOpt']['ClientInputsMaxLatency'] == 0): echo ' hidden="hidden"'; endif; ?> />
+									<a class="returnDefaultValue" id="resetClientInputsMaxLarency" href="?p=<?php echo USER_PAGE; ?>"<?php if ($data['srvOpt']['ClientInputsMaxLatency'] == 0): echo ' hidden="hidden"'; endif; ?>><?php echo Utils::t('Return to the default value'); ?></a>
+								</td>
+							</tr>
+						<?php endif; ?>
+						<tr>
+							<td class="key"><label for="HideServer"><?php echo Utils::t('Hidden server'); ?></label></td>
+							<td class="value" colspan="4">
+								<input class="text" type="checkbox" name="HideServer" id="HideServer"<?php if ($data['srvOpt']['HideServer'] != 0): echo ' checked="checked"'; endif; ?> value="" />
+							</td>
+						</tr>
+						<tr>
+							<td class="key"><label for="AllowMapDownload"><?php echo Utils::t('Map download'); ?></label></td>
+							<td class="value" colspan="4">
+								<input class="text" type="checkbox" name="AllowMapDownload" id="AllowMapDownload"<?php if (SERVER_VERSION_NAME == 'TmForever' && $data['srvOpt']['AllowChallengeDownload'] != 0): echo ' checked="checked"'; elseif (SERVER_VERSION_NAME == 'ManiaPlanet' && $data['srvOpt']['AllowMapDownload'] != 0): echo ' checked="checked"'; endif; ?> value="" />
+							</td>
+						</tr>
+						<tr<?php if (AdminServAdminLevel::isType('Admin') && !AdminServAdminLevel::isType('SuperAdmin')): echo ' hidden="hidden"'; endif; ?>>
+							<td class="key"><label for="AutoSaveReplays"><?php echo Utils::t('Replays auto save'); ?></label></td>
+							<td class="value" colspan="4">
+								<input class="text" type="checkbox" name="AutoSaveReplays" id="AutoSaveReplays"<?php if ($data['srvOpt']['AutoSaveReplays'] != 0): echo ' checked="checked"'; endif; ?> value="" />
+							</td>
+						</tr>
+						<tr>
+							<td class="key"><label for="BuddyNotification"><?php echo Utils::t('Buddy notification'); ?></label></td>
+							<td class="value" colspan="4">
+								<input class="text" type="checkbox" name="BuddyNotification" id="BuddyNotification"<?php if ($data['srvOpt']['BuddyNotification'] != 0): echo ' checked="checked"'; endif; ?> value="" />
+							</td>
+						</tr>
+						<?php if (SERVER_VERSION_NAME == 'ManiaPlanet'): ?>
+							<tr>
+								<td class="key"><label for="DisableHorns"><?php echo Utils::t('Disable horns'); ?></label></td>
+								<td class="value" colspan="4">
+									<input class="text" type="checkbox" name="DisableHorns" id="DisableHorns"<?php if ($data['srvOpt']['DisableHorns'] != 0): echo ' checked="checked"'; endif; ?> value="" />
+								</td>
+							</tr>
+						<?php endif; ?>
+					</table>
+				</fieldset>
+			<?php endif; ?>
+			
+			<?php if (AdminServAdminLevel::hasPermission('srvopts_adminlevelpassword', USER_ADMINLEVEL, 'SuperAdmin')): ?>
+				<fieldset class="srvopts_changeauthpassword">
+					<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/players.png" alt="" /><?php echo Utils::t('Change authentication password'); ?></legend>
+					<table>
+						<tr>
+							<td class="key"><label for="ChangeAuthLevel"><?php echo Utils::t('Admin level'); ?></label></td>
+							<td class="value col2">
+								<select name="ChangeAuthLevel" id="ChangeAuthLevel">
+									<?php if (isset($data['adminLevels']['levels']) && !empty($data['adminLevels']['levels'])): ?>
+										<?php foreach ($data['adminLevels']['levels'] as $levelId => $levelName): ?>
+											<option value="<?php echo $levelName; ?>"><?php echo $levelName; ?></option>
+										<?php endforeach; ?>
+									<?php endif; ?>
+								</select>
+								<span class="changeauthpassword-arrow"> </span>
+								<input class="text" type="password" name="ChangeAuthPassword" id="ChangeAuthPassword" value="" />
+							</td>
+						</tr>
+					</table>
+				</fieldset>
+			<?php endif; ?>
+			
+			<?php if (defined('IS_LOCAL') && IS_LOCAL && AdminServAdminLevel::hasPermission('srvopts_importexport')): ?>
+				<fieldset class="srvopts_importexport">
+					<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_team.png" alt="" /><?php echo Utils::t('Manage server options'); ?></legend>
+					<table>
+						<tr>
+							<td class="key"><label for="srvoptsImport"><?php echo Utils::t('Import'); ?></label></td>
+							<td class="value col2">
+								<input class="text" type="radio" name="srvoptsImportExport" id="srvoptsImport" value="Import" />
+								<select name="srvoptsImportName" id="srvoptsImportName" hidden="hidden">
+									<?php if (isset($data['srvoptsConfigFiles']['files']) && !empty($data['srvoptsConfigFiles']['files'])): ?>
+										<?php foreach ($data['srvoptsConfigFiles']['files'] as $file): ?>
+											<option value="<?php echo $file['filename']; ?>"><?php echo substr($file['filename'], 0, -4); ?></option>
+										<?php endforeach; ?>
+									<?php else: ?>
+										<option value="none"><?php echo Utils::t('No export available'); ?></option>
+									<?php endif; ?>
+								</select>
+							</td>
+						</tr>
+						<tr>
+							<td class="key"><label for="srvoptsExport"><?php echo Utils::t('Export'); ?></label></td>
+							<td class="value col2">
+								<input class="text" type="radio" name="srvoptsImportExport" id="srvoptsExport" value="Export" />
+								<input class="text" hidden="hidden" type="text" name="srvoptsExportName" id="srvoptsExportName" value="<?php echo SERVER_LOGIN; ?>" />
+							</td>
+						</tr>
+					</table>
+				</fieldset>
+			<?php endif; ?>
+		</div>
+		<div class="fright save">
+			<input class="button light" type="submit" name="savesrvopts" id="savesrvopts" value="<?php echo Utils::t('Save'); ?>" />
+		</div>
+	</form>
+</section>
\ No newline at end of file
diff --git a/robots.txt b/robots.txt
new file mode 100644
index 0000000..77470cb
--- /dev/null
+++ b/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
\ No newline at end of file

Fixed code: # Auto detect text files and perform LF normalization
* text=auto

# Custom for Visual Studio
*.cs     diff=csharp
*.sln    merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union

# Standard to msysgit
*.doc	 diff=astextplain
*.DOC	 diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot  diff=astextplain
*.DOT  diff=astextplain
*.pdf  diff=astextplain
*.PDF	 diff=astextplain
*.rtf	 diff=astextplain
*.RTF	 diff=astextplain
Options +FollowSymlinks
Options -Indexes
AdminServ
=========

WebInterface to manage Trackmania Forever and ManiaPlanet dedicated servers.

######Introduction
Welcome to the new home of AdminServ.
The original author of this awesome piece of work - kev717 - gave me [permission](http://forum.maniaplanet.com/viewtopic.php?p=231516#p231516) to continue updating this project.
Feel free to submit pull requests, issues or feature requests.


######About AdminServ
Inspired by remoteCP and similar endeavours, AdminServ is a web interface which allows you to remotely control almost all aspects of your ManiaPlanet or TMForever servers. 

######Main Features
- Compatible with both TMForever and ManiaPlanet servers
- Configure your servers online, from everywhere!
- Display optimizations for Team mode
- Folder-based organization of your maps
- Allows managing your MatchSettings and playlists
- Supports third-party plugins
- Easily customizable (Header logo, Website title name, color scheme)

######Requirements
- A web server
- PHP 5.3+
- A dedicated TMForever/ManiaPlanet server

######How-to install
- Download the [latest release](https://github.com/Chris92de/AdminServ/releases)
- Unpack it on your webserver
- Navigate to wherever you placed it in your browser
- Done! You're ready to configure everything in your browser
- (optional) Add the location of your TMForever/ManiaPlanet server to the allowed open_basedir directories in your php.ini
<?php
class AdminLevelConfig {
	public static $ADMINLEVELS = array(
		/********************* ADMINLEVELS CONFIGURATION *********************/
		
		'SuperAdmin' => array(
			'adminlevel' => array(
				'type' => 'SuperAdmin',
			),
			'access' => array(
				'server_options',
				'game_infos',
				'chat',
				'maps_list',
				'maps_local',
				'maps_upload',
				'maps_order',
				'maps_matchsettings',
				'maps_create_matchsettings',
				'link_access_server',
				'plugins_list',
				'guest_ban',
			),
			'permission' => array(
				'speed_admin',
				'switch_server',
				'player_kick',
				'player_ban',
				'player_guest',
				'player_ignore',
				'player_forcetospectator',
				'player_forcetoplayer',
				'player_changeteam',
				'force_scores',
				'cancel_vote',
				'srvopts_general_name',
				'srvopts_general_comment',
				'srvopts_general_playerpassword',
				'srvopts_general_spectatorpassword',
				'srvopts_general_nbplayers',
				'srvopts_general_nbspectators',
				'srvopts_advanced',
				'srvopts_adminlevelpassword',
				'srvopts_importexport',
				'gameinfos_general_gamemode',
				'gameinfos_general_options',
				'gameinfos_general_warmup',
				'gameinfos_teams_options',
				'gameinfos_gamemode_options',
				'chat_sendmessage',
				'maps_list_moveaftercurrent',
				'maps_list_removetolist',
				'maps_local_add',
				'maps_local_insert',
				'maps_local_download',
				'maps_local_rename',
				'maps_local_move',
				'maps_local_delete',
				'maps_upload_add',
				'maps_upload_insert',
				'maps_upload_folder',
				'maps_matchsettings_save',
				'maps_matchsettings_load',
				'maps_matchsettings_add',
				'maps_matchsettings_insert',
				'maps_matchsettings_edit',
				'maps_matchsettings_delete',
				'folder_new',
				'folder_rename',
				'folder_move',
				'folder_delete',
				'guestban_addplayer',
				'guestban_removeplayer',
				'guestban_playlist_new',
				'guestban_playlist_save',
				'guestban_playlist_load',
				'guestban_playlist_delete',
			),
		),
		'Admin' => array(
			'adminlevel' => array(
				'type' => 'Admin',
			),
			'access' => array(
				'server_options',
				'game_infos',
				'chat',
				'maps_list',
				'maps_local',
				'maps_upload',
				'maps_order',
				'maps_matchsettings',
				'maps_create_matchsettings',
				'link_access_server',
				'plugins_list',
				'guest_ban',
			),
			'permission' => array(
				'speed_admin',
				'switch_server',
				'player_kick',
				'player_ban',
				'player_guest',
				'player_ignore',
				'player_forcetospectator',
				'player_forcetoplayer',
				'player_changeteam',
				'force_scores',
				'cancel_vote',
				'srvopts_general_name',
				'srvopts_general_comment',
				'srvopts_general_playerpassword',
				'srvopts_general_spectatorpassword',
				'srvopts_general_nbplayers',
				'srvopts_general_nbspectators',
				'gameinfos_general_gamemode',
				'gameinfos_general_warmup',
				'gameinfos_teams_options',
				'gameinfos_gamemode_options',
				'chat_sendmessage',
				'maps_list_moveaftercurrent',
				'maps_list_removetolist',
				'maps_local_add',
				'maps_local_insert',
				'maps_local_download',
				'maps_local_rename',
				'maps_local_move',
				'maps_upload_add',
				'maps_upload_insert',
				'maps_upload_folder',
				'maps_matchsettings_save',
				'maps_matchsettings_load',
				'maps_matchsettings_add',
				'maps_matchsettings_insert',
				'maps_matchsettings_edit',
				'folder_new',
				'folder_rename',
				'folder_move',
				'guestban_addplayer',
				'guestban_removeplayer',
				'guestban_playlist_new',
				'guestban_playlist_save',
				'guestban_playlist_load',
			),
		),
		'User' => array(
			'adminlevel' => array(
				'type' => 'User',
			),
			'access' => array(
				'chat',
				'maps_list',
				'link_access_server',
			),
			'permission' => array(
			),
		),
	);
}
?>
<?php
class OnlineConfig {
	/********************* ONLINE CONFIGURATION *********************/
	
	const ACTIVATE = true; // Activate the online configuration
	const PASSWORD = '0b28a5799a32c687dad2c5183718ceac'; // Checking password. This password is generated in MD5
	const ADDRESS = ''; // Checking address. Can be localhost or IP address
	const ADD_ONLY = false; // Add only server. Unable to modify or delete
	const ADMINLEVEL = true; // Activate the admin level configuration
}

class AdminServConfig {
	/********************* OPTIONAL CONFIGURATION *********************/
	
	/* GENERAL */
	const TITLE = 'Admin,Serv'; // The comma seperates the color
	const SUBTITLE = 'For maniaplanet servers'; // if null it's hidden
	const LOGO = 'logo.png'; // if null it's hidden
	const DEFAULT_THEME = 'red'; // The first theme to be loaded
	const DEFAULT_LANGUAGE = 'auto'; // Can be language code (fr, en, etc) or auto = automatic detection
	const USE_DISPLAYSERV = true; // Show DisplayServ tool on connection page
	const AUTOSAVE_MATCHSETTINGS = true; // Save the MatchSettings in the server config (possibility to disable online)
	
	/* ADVANCED */
	const MD5_PASSWORD = false; // if true, the dedicated server password is checked in MD5
	const LIMIT_PLAYERS_LIST = 250; // Display limit for lines in player list
	const LIMIT_MAPS_LIST = 1000; // Display limit for lines in maps list
	const LOCAL_GET_MAPS_ON_SERVER = true; // if true, the current server maps list is loaded in local maps page for easy compare with icon change. But if you have a lot of maps in server, it is better to disable it
	const RECENT_STATUS_PERIOD = 24; // Recent status period in hour for maps/matchsettings/guestban
	const SERVER_CONNECTION_TIMEOUT = 3; // Dedicated server connection timeout in second
	const COOKIE_EXPIRE = 90; // Expiration time for cookies, in days
	
	/* FILES AND FOLDERS */
	public static $MAPS_HIDDEN_FOLDERS = array('MatchSettings', 'Replays'); // Folders to be hidden in maps page
	public static $MATCHSET_HIDDEN_FOLDERS = array('Campaigns', 'Replays'); // Folders to be hidden in matchsettings page
	public static $MAP_EXTENSION = array('map.gbx', 'challenge.gbx', 'gbx'); // Double extensions used in maps page
	public static $MATCHSET_EXTENSION = array('txt'); // MatchSettings extensions used in matchsettings page
	public static $PLAYLIST_EXTENSION = array('playlist.txt'); // Playlist extensions used in guestban page
	
	/* UPLOAD */
	public static $ALLOWED_EXTENSIONS = array('gbx'); // Extensions allowed for upload
	const SIZE_LIMIT = 'auto'; // Limit size per file in MB. If auto, the limit size in php.ini config file is used
	const UPLOAD_ONLINE_FOLDER = 'AdminServ/'; // Path from "Maps" folder for upload online mode
	
	/* LOGS */
	public static $LOGS = array(
		'access' => true,
		'action' => true,
		'error' => true
	);
	
	/* MULTI ADMINSERV */
	const MULTI_ADMINSERV = false; // Use many instances of AdminServ
	public static $PATH_RESOURCES = './resources/'; // You can change the folders location
	public static $PATH_PLUGINS = './plugins/';
	
	/* PLUGINS */
	const PLUGINS_LIST = ''; // The filename for alternative plugin configuration. In the file: $PLUGINS = array('pluginfoldername', 'etc');
	const PLUGINS_LIST_TYPE = 'replace'; // add or replace method
}

class DataBaseConfig {
	/********************* DATABASE CONFIGURATION *********************/
	
	const DB_HOST = '';
	const DB_PORT = '';
	const DB_USER = '';
	const DB_PASS = '';
	const DB_NAME = '';
	const DB_DRIVER = '';
	const DB_TABLE_PREFIX = '';
}

class FTPConfig {
	/********************* FTP CONFIGURATION *********************/
	
	const FTP_HOST = '';
	const FTP_USER = '';
	const FTP_PASS = '';
	const FTP_PORT = 21;
}
?>
<?php
class ExtensionConfig {
	/********************* EXTENSION CONFIGURATION *********************/
	
	// Plugins list installed
	public static $PLUGINS = array(
		'planets',
		'coppers',
	);
	
	
	// Themes color list
	public static $THEMES = array(
		'red' => array(
			'#ea4f4f',
			'#ffc0c0'
		),
		'blue' => array(
			'#5e9cd5',
			'#d9e8ff'
		),
		'green' => array(
			'#8aca1b',
			'#d1e9a8'
		),
		'orange' => array(
			'#ffa600',
			'#ffe3b0'
		),
		'purple' => array(
			'#b15cd5',
			'#e5c4f3'
		),
		'black' => array(
			'#727272',
			'#dedede'
		)
	);
	
	
	// Available language list
	public static $LANG = array(
		'fr' => 'Français',
		'en' => 'English',
		'de' => 'Deutsch',
		'es' => 'Español',
		'no' => 'Norsk',
		'dk' => 'Danish',
		'pl' => 'Polish',
		'nl' => 'Dutch'
	);
	
	
	// Game modes list
	public static $GAMEMODES = array(
		0 => 'Script',
		1 => 'Rounds',
		2 => 'TimeAttack',
		3 => 'Team',
		4 => 'Laps',
		5 => 'Cup',
		6 => 'Stunts'
	);
	public static $TEAMSCRIPTS = array(
		'Elite',
		'Battle',
		'Siege',
		'Heroes',
		'SpeedBall'
	);
	
	
	// Menu list in maps page
	public static $MAPSMENU = array(
		'maps-list' => 'List',
		'maps-local' => 'Local',
		'maps-upload' => 'Send',
		'maps-order' => 'Order',
		'maps-matchset' => 'MatchSettings',
		'maps-creatematchset' => 'Create a MatchSettings'
	);
}
?>
<?php
	session_start();
	require_once './adminserv.cfg.php';
	if( file_exists('./servers.cfg.php') ){
		require_once './servers.cfg.php';
	}
	AdminServConfig::$PATH_RESOURCES = '../'.AdminServConfig::$PATH_RESOURCES;
	require_once AdminServConfig::$PATH_RESOURCES .'core/adminserv.php';
	AdminServ::getClass();
	AdminServUI::lang();
	
	// On vérifie qu'une configuration existe
	if( class_exists('ServerConfig') ){
		// Si on autorise la configuration en ligne
		if( OnlineConfig::ACTIVATE === true ){
			// Si il y a déjà un serveur configuré
			if( AdminServServerConfig::hasServer() ){
				$allowRedirect = false;
				if( OnlineConfig::ADDRESS == null && OnlineConfig::PASSWORD == null ){
					$allowRedirect = true;
				}
				else{
					// Test adresse IP
					if(OnlineConfig::ADDRESS != null){
						if(OnlineConfig::ADDRESS === 'localhost'){
							if( Utils::isLocalhostIP() ){
								$allowRedirect = true;
							}
							else{
								$allowRedirect = false;
							}
						}
						else{
							if( $_SERVER['REMOTE_ADDR'] === OnlineConfig::ADDRESS ){
								$allowRedirect = true;
							}
							else{
								$allowRedirect = false;
							}
						}
					}
					// Test password
					if(OnlineConfig::PASSWORD != null){
						if( isset($_POST['configcheckpassword']) ){
							if(md5($_POST['checkPassword']) === OnlineConfig::PASSWORD){
								$allowRedirect = true;
							}
							else{
								$allowRedirect = false;
							}
						}
						else{
							// Suppression des sessions existante et démarrage d'une nouvelle
							session_unset();
							session_destroy();
							session_start();
							
							// Demande de password
							$_SESSION['adminserv']['check_password'] = true;
							Utils::redirection(false, '..');
						}
					}
				}
			
				// Redirection vers les pages
				if($allowRedirect){
					session_unset();
					session_destroy();
					session_start();
					$_SESSION['adminserv']['allow_config_servers'] = true;
					
					if( OnlineConfig::ADD_ONLY === true || AdminServServerConfig::hasServer() === false ){
						Utils::redirection(false, '../?p=config-addserver');
					}
					else{
						Utils::redirection(false, '../?p=config-servers');
					}
				}
				else{
					AdminServ::error( Utils::t('You are not allowed to configure the servers') );
					Utils::redirection(false, '..');
				}
			}
			// Sinon on créer le mot de passe
			else{
				if( isset($_POST['configsavepassword']) ){
					$password = md5($_POST['savePassword']);
					if( ($result = AdminServServerConfig::savePasswordConfig('./adminserv.cfg.php', $password)) !== true ){
						AdminServ::error( Utils::t('Unable to save password.').' ('.$result.')');
						Utils::redirection(false, '..');
					}
					else{
						session_unset();
						session_destroy();
						session_start();
						$_SESSION['adminserv']['allow_config_servers'] = true;
						Utils::redirection(false, '../?p=config-addserver');
					}
				}
				else{
					// Création du mot de passe
					$_SESSION['adminserv']['get_password'] = true;
					Utils::redirection(false, '..');
				}
			}
		}
		else{
			AdminServ::info( Utils::t('The online configuration is disabled. Use "./config/servers.cfg.php" file.') );
			Utils::redirection(false, '..');
		}
	}
	else{
		Utils::redirection(false, '../?error='.urlencode( Utils::t('The servers configuration file isn\'t recognized by AdminServ.') ) );
	}
?>
<?php
class ServerConfig {
    public static $SERVERS = array(
        /********************* SERVER CONFIGURATION *********************/

        /*
        'new server name' => array(
            'address'		=> 'localhost',
            'port'			=> 5000,
            'mapsbasepath'	=> '',
            'matchsettings'	=> 'MatchSettings/',
            'adminlevel'	=> array('SuperAdmin' => 'all', 'Admin' => 'all', 'User' => 'all'),
            'ds_pw'         => 'User'
        ),
        */
    );
}
?>
<?php
    // FIX FOR MAPBROWSER BY TOFFE
    foreach ($_GET as $key => $value) { if(stristr($value, "../")) $_GET[$key] = str_replace("../", "", $value); }
    foreach ($_POST as $key => $value) { if(stristr($value, "../")) $_POST[$key] = str_replace("../", "", $value); }
	// INCLUDES
	session_start();
	require_once 'config/adminserv.cfg.php';
	require_once 'config/servers.cfg.php';
	require_once 'config/extension.cfg.php';
	require_once 'config/adminlevel.cfg.php';
	require_once AdminServConfig::$PATH_RESOURCES .'core/adminserv.php';
	
	// LOAD TIMER
	if(ADMINSERV_TIMER){
		AdminServ::startTimer();
	}
	
	// INITIALIZE
	AdminServ::checkPHPVersion('5.3.0');
	define('PATH_ROOT', basename(__DIR__).'/');
	$_SESSION['adminserv']['path'] = (AdminServConfig::MULTI_ADMINSERV) ? PATH_ROOT : null;
	AdminServ::getClass();
	
	// GLOBALS
	AdminServEvent::getArgs();
	
	// THEME
	define('USER_THEME', AdminServUI::theme($args['theme']));
	
	// LANG
	define('USER_LANG', AdminServUI::lang($args['lang']));
	
	// VÉRIFICATION DES DROITS
	$checkRightsList = array(
		'./config/adminserv.cfg.php' => 666,
		'./config/servers.cfg.php' => 666,
		'./config/adminlevel.cfg.php' => 666,
	);
	if( in_array(true, AdminServConfig::$LOGS) ){
		if (!Utils::isWinServer()) {
			$checkRightsList['./logs/'] = 777;
		}
	}
	AdminServ::checkRights($checkRightsList);
	
	// LOGOUT
	AdminServEvent::logout();
	
	// LOGS
	AdminServLogs::initialize();
	
	// PLUGINS
	define('USER_PLUGIN', AdminServPlugin::getCurrent());
	
	// INDEX
	unset($args['theme'], $args['lang']);
	if( AdminServEvent::isLoggedIn() ){
		
		// SWITCH SERVER
		AdminServEvent::switchServer();
		
		// SERVER CONNECTION
		if (AdminServ::initialize()) {
			// PAGES BACKOFFICE
			AdminServUI::initBackPage();
		}
	}
	else{
		// PAGES FRONTOFFICE
		AdminServUI::initFrontPage();
	}
?>
; Name and version of plugin
name = 'New plugin'
version = '1.0'
; Game compatibiliy : TmForever, ManiaPlanet or all
game = 'all'
; Minimum access level
adminlevel = 'User'
<?php

?>
; Name and version of plugin
name = 'Coppers'
version = '1.0'
; Game compatibiliy : TmForever, ManiaPlanet or all
game = 'TmForever'
; Minimum access level
adminlevel = 'Admin'
$(document).ready(function(){
	// Default values
	$('#serverToServerLogin, #serverToPlayerMessage, #serverToPlayerLogin2').click(function(){
		if( $(this).val() == $(this).data('default-value') ){
			$(this).val('');
		}
	});
	$('#serverToServerLogin, #serverToPlayerMessage, #serverToPlayerLogin2').blur(function(){
		if( $(this).val() == '' ){
			$(this).val( $(this).data('default-value') );
		}
	});
	
	// Server > Player
	$('#serverToPlayerLogin').change(function(){
		if( $(this).val() == 'more' ){
			$(this).fadeOut('fast');
			$('#serverToPlayerLogin2').fadeIn('fast');
			$(this).attr('hidden', true);
			$('#serverToPlayerLogin2').removeAttr('hidden');
		}
	});
});
<?php
	$translate['Optionnal'] = 'Optionnel';
	$translate['Transfered by AdminServ'] = 'Transferé par AdminServ';
	$translate['Confirmation of the transfer by AdminServ'] = 'Confirmation de transfert par AdminServ';
	$translate['Transaction'] = 'Transaction';
	$translate['No transfer made.'] = 'Aucun transfert effectué.';
	$translate['Infos'] = 'Infos';
	$translate['Number of coppers:'] = 'Nombre de coppers :';
	$translate['Transfer state:'] = 'Statut du transfert :';
	$translate['Transfers'] = 'Transferts';
	$translate['Amount'] = 'Somme';
	$translate['Confirmation from a player on the server is necessary.'] = 'Nécessite une confirmation du joueur sur le serveur.';
	$translate['Transfer'] = 'Transférer';
?>
<?php
	/* INCLUDES */
	$path = AdminServPlugin::getPluginPath();
	$langFile = $path.'lang/'. USER_LANG .'.php';
	if( file_exists($langFile) ){
		include_once $langFile;
	}
	
	
	/* ACTIONS */
	if( isset($_POST['transfercoppers']) ){
		// Server > Server
		if( isset($_POST['serverToServerAmout']) && isset($_POST['serverToServerLogin']) ){
			$serverToServerAmout = intval($_POST['serverToServerAmout']);
			$serverToServerLogin = trim($_POST['serverToServerLogin']);
			
			if($serverToServerAmout > 0 && $serverToServerLogin != Utils::t('Server login') ){
				if( !$client->query('Pay', $serverToServerLogin, $serverToServerAmout, Utils::t('Transfered by AdminServ')) ){
					AdminServ::error();
				}
				else{
					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
					AdminServLogs::add('action', 'Transfer '.$serverToServerAmout.' coppers to '.$serverToServerLogin.' server login');
				}
			}
		}
		
		// Server > Player
		if( isset($_POST['serverToPlayerAmount']) && isset($_POST['serverToPlayerLogin']) ){
			$serverToPlayerAmount = intval($_POST['serverToPlayerAmount']);
			$serverToPlayerMessage = trim($_POST['serverToPlayerMessage']);
			$serverToPlayerLogin = trim($_POST['serverToPlayerLogin']);
			$serverToPlayerLogin2 = trim($_POST['serverToPlayerLogin2']);
			
			if( $serverToPlayerAmount > 0 ){
				// Message
				if($serverToPlayerMessage == Utils::t('Optionnal') ){
					$serverToPlayerMessage = Utils::t('Transfered by AdminServ');
				}
				// Player login
				if($serverToPlayerLogin2 != Utils::t('Player login') ){
					$serverToPlayerLogin = $serverToPlayerLogin2;
				}
				
				// Pay
				if( !$client->query('Pay', $serverToPlayerLogin2, $serverToPlayerAmount, $serverToPlayerMessage) ){
					AdminServ::error();
				}
				else{
					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
					AdminServLogs::add('action', 'Transfer '.$serverToPlayerAmount.' coppers to '.$serverToPlayerLogin2.' player login');
				}
			}
		}
		
		// Server < Player
		if( isset($_POST['playerToServerAmount']) && isset($_POST['playerToServerLogin']) ){
			$playerToServerAmount = intval($_POST['playerToServerAmount']);
			$playerToServerLogin = trim($_POST['playerToServerLogin']);
			
			if( $playerToServerAmount > 0 ){
				if( !$client->query('SendBill', $playerToServerLogin, $playerToServerAmount, Utils::t('Confirmation of the transfer by AdminServ'), SERVER_LOGIN) ){
					AdminServ::error();
				}
				else{
					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
					AdminServLogs::add('action', 'Transfer '.$playerToServerAmount.' coppers from to '.$playerToServerLogin.' player login');
				}
			}
		}
		
		Utils::redirection(false, '?p='.USER_PAGE);
	}
	
	
	/* GET */
	$client->addCall('GetServerCoppers');
	if( isset($_SESSION['adminserv']['transfer_billid']) && $_SESSION['adminserv']['transfer_billid'] != null){
		$client->addCall('GetBillState', array($_SESSION['adminserv']['transfer_billid']) );
	}
	
	if( !$client->multiquery() ){
		AdminServ::error();
	}
	else{
		$queriesData = $client->getMultiqueryResponse();
		
		// Coppers number
		$nbCoppers = $queriesData['GetServerCoppers'];
		
		// Transfer status
		if( isset($queriesData['GetBillState']) ){
			$billState = $queriesData['GetBillState'];
			$transferState = Utils::t('Transaction').' #'.$billState['TransactionId'].' : '.$billState['StateName'];
		}
		else{
			$transferState = '<i>'.Utils::t('No transfer made.').'</i>';
		}
	}
	
	// Players
	$playerCount = AdminServ::getNbPlayers();
	$getPlayerListUI = AdminServUI::getPlayerList();
	
	$client->Terminate();
?>
.plugin-coppers .width2 {
	width: 45%;
}
.plugin-coppers input.width1 {
	width: 83%;
}
.plugin-coppers select.width1 {
	width: 88%;
}
<link rel="stylesheet" href="<?php echo $path; ?>styles/coppers.css" />
<script src="<?php echo $path; ?>js/event.js"></script>

<h2><?php echo Utils::t('Infos'); ?></h2>
<div class="content">
	<p><?php echo Utils::t('Number of coppers:'); ?> <b><?php echo $nbCoppers; ?></b></p>
	<p><?php echo Utils::t('Transfer state:').' '.$transferState; ?></p>
</div>

<h2><?php echo Utils::t('Transfers'); ?></h2>
<form method="post" action="">
<div class="content">
	<fieldset>
		<legend><?php echo Utils::t('Server').' &gt; '.Utils::t('Server'); ?></legend>
		<table>
			<tr>
				<td class="key">
					<label for="serverToServerAmout"><?php echo Utils::t('Amount'); ?></label>
				</td>
				<td class="value">
					<input class="text width2" type="number" min="0" name="serverToServerAmout" id="serverToServerAmout" value="" />
				</td>
			</tr>
			<tr>
				<td class="key">
					<label for="serverToServerLogin"><i><?php echo SERVER_LOGIN; ?></i> →</label>
				</td>
				<td class="value">
					<input class="text width2" type="text" name="serverToServerLogin" id="serverToServerLogin" data-default-value="Login serveur" value="Login serveur" />
				</td>
			</tr>
		</table>
	</fieldset>
	
	<fieldset>
		<legend><?php echo Utils::t('Server').' &gt; '.Utils::t('Player'); ?></legend>
		<table>
			<tr>
				<td class="key">
					<label for="serverToPlayerAmount"><?php echo Utils::t('Amount'); ?></label>
				</td>
				<td class="value">
					<input class="text width2" type="number" min="0" name="serverToPlayerAmount" id="serverToPlayerAmount" value="" />
				</td>
			</tr>
			<tr>
				<td class="key">
					<label for="serverToPlayerMessage"><?php echo Utils::t('Message'); ?></label>
				</td>
				<td class="value">
					<input class="text width2" type="text" name="serverToPlayerMessage" id="serverToPlayerMessage" data-default-value="<?php echo Utils::t('Optionnal'); ?>" value="<?php echo Utils::t('Optionnal'); ?>" />
				</td>
			</tr>
			<tr>
				<td class="key">
					<label for="serverToPlayerLogin"><i><?php echo SERVER_LOGIN; ?></i> →</label>
				</td>
				<td class="value">
					<select class="width2" name="serverToPlayerLogin" id="serverToPlayerLogin"<?php if($playerCount == 0){ echo ' hidden="hidden"'; } ?>>
						<?php echo $getPlayerListUI; ?>
						<option value="more"><?php echo Utils::t('Enter another login'); ?></option>
					</select>
					<input class="text width2" type="text" name="serverToPlayerLogin2" id="serverToPlayerLogin2" data-default-value="<?php echo Utils::t('Player login'); ?>" value="<?php echo Utils::t('Player login'); ?>"<?php if($playerCount != 0){ echo ' hidden="hidden"'; } ?> />
				</td>
			</tr>
		</table>
	</fieldset>
	
	<fieldset>
		<legend><?php echo Utils::t('Server').' &lt; '.Utils::t('Player'); ?></legend>
		<table>
			<tr>
				<td class="key">
					<label for="playerToServerAmount"><?php echo Utils::t('Amount'); ?></label>
				</td>
				<td class="value">
					<input class="text width1" type="number" min="0" name="playerToServerAmount" id="playerToServerAmount" value="" />
				</td>
			</tr>
			<tr>
				<td class="key">
					<label for="playerToServerLogin"><i><?php echo SERVER_LOGIN; ?></i> ←</label>
				</td>
				<td class="value">
					<select class="width1" name="playerToServerLogin" id="playerToServerLogin">
						<?php echo $getPlayerListUI; ?>
					</select>
				</td>
				<td class="info">
					<?php echo Utils::t('Confirmation from a player on the server is necessary.'); ?>
				</td>
			</tr>
		</table>
	</fieldset>
</div>
<div class="fright save">
	<input class="button light" type="submit" name="transfercoppers" id="transfercoppers" value="<?php echo Utils::t('Transfer'); ?>" />
</div>
</form>
; Name and version of plugin
name = 'Planets'
version = '1.0'
; Game compatibiliy : TmForever, ManiaPlanet or all
game = 'ManiaPlanet'
; Minimum access level
adminlevel = 'Admin'
$(document).ready(function(){
	// Default values
	$('#serverToServerLogin, #serverToPlayerMessage, #serverToPlayerLogin2').click(function(){
		if( $(this).val() == $(this).data('default-value') ){
			$(this).val('');
		}
	});
	$('#serverToServerLogin, #serverToPlayerMessage, #serverToPlayerLogin2').blur(function(){
		if( $(this).val() == '' ){
			$(this).val( $(this).data('default-value') );
		}
	});
	
	// Server > Player
	$('#serverToPlayerLogin').change(function(){
		if( $(this).val() == 'more' ){
			$(this).fadeOut('fast');
			$('#serverToPlayerLogin2').fadeIn('fast');
			$(this).attr('hidden', true);
			$('#serverToPlayerLogin2').removeAttr('hidden');
		}
	});
});
<?php
	$translate['Optionnal'] = 'Optionnel';
	$translate['Transfered by AdminServ'] = 'Transferé par AdminServ';
	$translate['Confirmation of the transfer by AdminServ'] = 'Confirmation de transfert par AdminServ';
	$translate['Transaction'] = 'Transaction';
	$translate['No transfer made.'] = 'Aucun transfert effectué.';
	$translate['Infos'] = 'Infos';
	$translate['Number of planets:'] = 'Nombre de planets :';
	$translate['Transfer state:'] = 'Statut du transfert :';
	$translate['Transfers'] = 'Transferts';
	$translate['Amount'] = 'Somme';
	$translate['Confirmation from a player on the server is necessary.'] = 'Nécessite une confirmation du joueur sur le serveur.';
	$translate['Transfer'] = 'Transférer';
?>
<?php
	/* INCLUDES */
	$path = AdminServPlugin::getPluginPath();
	$langFile = $path.'lang/'. USER_LANG .'.php';
	if( file_exists($langFile) ){
		include_once $langFile;
	}
	
	
	/* ACTIONS */
	if( isset($_POST['transferplanets']) ){
		// Server > Server
		if( isset($_POST['serverToServerAmout']) && isset($_POST['serverToServerLogin']) ){
			$serverToServerAmout = intval($_POST['serverToServerAmout']);
			$serverToServerLogin = trim($_POST['serverToServerLogin']);
			
			if($serverToServerAmout > 0 && $serverToServerLogin != Utils::t('Server login') ){
				if( !$client->query('Pay', $serverToServerLogin, $serverToServerAmout, Utils::t('Transfered by AdminServ')) ){
					AdminServ::error();
				}
				else{
					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
					AdminServLogs::add('action', 'Transfer '.$serverToServerAmout.' planets to '.$serverToServerLogin.' server login');
				}
			}
		}
		
		// Server > Player
		if( isset($_POST['serverToPlayerAmount']) && isset($_POST['serverToPlayerLogin']) ){
			$serverToPlayerAmount = intval($_POST['serverToPlayerAmount']);
			$serverToPlayerMessage = trim($_POST['serverToPlayerMessage']);
			$serverToPlayerLogin = trim($_POST['serverToPlayerLogin']);
			$serverToPlayerLogin2 = trim($_POST['serverToPlayerLogin2']);
			
			if( $serverToPlayerAmount > 0 ){
				// Message
				if($serverToPlayerMessage == Utils::t('Optionnal') ){
					$serverToPlayerMessage = Utils::t('Transfered by AdminServ');
				}
				// Player login
				if($serverToPlayerLogin2 != Utils::t('Player login') ){
					$serverToPlayerLogin = $serverToPlayerLogin2;
				}
				
				// Pay
				if( !$client->query('Pay', $serverToPlayerLogin, $serverToPlayerAmount, $serverToPlayerMessage) ){
					AdminServ::error();
				}
				else{
					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
					AdminServLogs::add('action', 'Transfer '.$serverToPlayerAmount.' planets to '.$serverToPlayerLogin.' player login');
				}
			}
		}
		
		// Server < Player
		if( isset($_POST['playerToServerAmount']) && isset($_POST['playerToServerLogin']) ){
			$playerToServerAmount = intval($_POST['playerToServerAmount']);
			$playerToServerLogin = trim($_POST['playerToServerLogin']);
			
			if( $playerToServerAmount > 0 ){
				if( !$client->query('SendBill', $playerToServerLogin, $playerToServerAmount, Utils::t('Confirmation of the transfer by AdminServ'), SERVER_LOGIN) ){
					AdminServ::error();
				}
				else{
					$_SESSION['adminserv']['transfer_billid'] = $client->getResponse();
					AdminServLogs::add('action', 'Transfer '.$playerToServerAmount.' planets from to '.$playerToServerLogin.' player login');
				}
			}
		}
		
		Utils::redirection(false, '?p='.USER_PAGE);
	}
	
	
	/* GET */
	$client->addCall('GetServerPlanets');
	if( isset($_SESSION['adminserv']['transfer_billid']) && $_SESSION['adminserv']['transfer_billid'] != null){
		$client->addCall('GetBillState', array($_SESSION['adminserv']['transfer_billid']) );
	}
	
	if( !$client->multiquery() ){
		AdminServ::error();
	}
	else{
		$queriesData = $client->getMultiqueryResponse();
		
		// Planets number
		$nbPlanets = $queriesData['GetServerPlanets'];
		
		// Transfer status
		if( isset($queriesData['GetBillState']) ){
			$billState = $queriesData['GetBillState'];
			$transferState = Utils::t('Transaction').' #'.$billState['TransactionId'].' : '.$billState['StateName'];
		}
		else{
			$transferState = '<i>'.Utils::t('No transfer made.').'</i>';
		}
	}
	
	// Players
	$playerCount = AdminServ::getNbPlayers();
	$getPlayerListUI = AdminServUI::getPlayerList();
	
	$client->Terminate();
?>
.plugin-planets .width2 {
	width: 45%;
}
.plugin-planets input.width1 {
	width: 83%;
}
.plugin-planets select.width1 {
	width: 88%;
}
<link rel="stylesheet" href="<?php echo $path; ?>styles/planets.css" />
<script src="<?php echo $path; ?>js/event.js"></script>

<h2><?php echo Utils::t('Infos'); ?></h2>
<div class="content">
	<p><?php echo Utils::t('Number of planets:'); ?> <b><?php echo $nbPlanets; ?></b></p>
	<p><?php echo Utils::t('Transfer state:').' '.$transferState; ?></p>
</div>

<h2><?php echo Utils::t('Transfers'); ?></h2>
<form method="post" action="">
<div class="content">
	<fieldset>
		<legend><?php echo Utils::t('Server').' &gt; '.Utils::t('Server'); ?></legend>
		<table>
			<tr>
				<td class="key">
					<label for="serverToServerAmout"><?php echo Utils::t('Amount'); ?></label>
				</td>
				<td class="value">
					<input class="text width2" type="number" min="0" name="serverToServerAmout" id="serverToServerAmout" value="" />
				</td>
			</tr>
			<tr>
				<td class="key">
					<label for="serverToServerLogin"><i><?php echo SERVER_LOGIN; ?></i> →</label>
				</td>
				<td class="value">
					<input class="text width2" type="text" name="serverToServerLogin" id="serverToServerLogin" data-default-value="Login serveur" value="Login serveur" />
				</td>
			</tr>
		</table>
	</fieldset>
	
	<fieldset>
		<legend><?php echo Utils::t('Server').' &gt; '.Utils::t('Player'); ?></legend>
		<table>
			<tr>
				<td class="key">
					<label for="serverToPlayerAmount"><?php echo Utils::t('Amount'); ?></label>
				</td>
				<td class="value">
					<input class="text width2" type="number" min="0" name="serverToPlayerAmount" id="serverToPlayerAmount" value="" />
				</td>
			</tr>
			<tr>
				<td class="key">
					<label for="serverToPlayerMessage"><?php echo Utils::t('Message'); ?></label>
				</td>
				<td class="value">
					<input class="text width2" type="text" name="serverToPlayerMessage" id="serverToPlayerMessage" data-default-value="<?php echo Utils::t('Optionnal'); ?>" value="<?php echo Utils::t('Optionnal'); ?>" />
				</td>
			</tr>
			<tr>
				<td class="key">
					<label for="serverToPlayerLogin"><i><?php echo SERVER_LOGIN; ?></i> →</label>
				</td>
				<td class="value">
					<select class="width2" name="serverToPlayerLogin" id="serverToPlayerLogin"<?php if($playerCount == 0){ echo ' hidden="hidden"'; } ?>>
						<?php echo $getPlayerListUI; ?>
						<option value="more"><?php echo Utils::t('Enter another login'); ?></option>
					</select>
					<input class="text width2" type="text" name="serverToPlayerLogin2" id="serverToPlayerLogin2" data-default-value="<?php echo Utils::t('Player login'); ?>" value="<?php echo Utils::t('Player login'); ?>"<?php if($playerCount != 0){ echo ' hidden="hidden"'; } ?> />
				</td>
			</tr>
		</table>
	</fieldset>
	
	<fieldset>
		<legend><?php echo Utils::t('Server').' &lt; '.Utils::t('Player'); ?></legend>
		<table>
			<tr>
				<td class="key">
					<label for="playerToServerAmount"><?php echo Utils::t('Amount'); ?></label>
				</td>
				<td class="value">
					<input class="text width1" type="number" min="0" name="playerToServerAmount" id="playerToServerAmount" value="" />
				</td>
			</tr>
			<tr>
				<td class="key">
					<label for="playerToServerLogin"><i><?php echo SERVER_LOGIN; ?></i> ←</label>
				</td>
				<td class="value">
					<select class="width1" name="playerToServerLogin" id="playerToServerLogin">
						<?php echo $getPlayerListUI; ?>
					</select>
				</td>
				<td class="info">
					<?php echo Utils::t('Confirmation from a player on the server is necessary.'); ?>
				</td>
			</tr>
		</table>
	</fieldset>
</div>
<div class="fright save">
	<input class="button light" type="submit" name="transferplanets" id="transferplanets" value="<?php echo Utils::t('Transfer'); ?>" />
</div>
</form>
<?php
	// INCLUDES
	session_start();
	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminlevel.cfg.php';
	require_once $configPath.'adminserv.cfg.php';
	require_once $configPath.'extension.cfg.php';
	require_once $configPath.'servers.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	
	// ISSET
	if( isset($_POST['nic']) ){ $nickname = $_POST['nic']; }else{ $nickname = null; }
	if( isset($_POST['clr']) ){ $color = $_POST['clr']; }else{ $color = null; }
	if( isset($_POST['msg']) ){ $message = $_POST['msg']; }else{ $message = null; }
	if( isset($_POST['dst']) ){ $destination = $_POST['dst']; }else{ $destination = null; }
	
	// DATA
	$out = null;
	if($message != null && $destination != null){
		if( AdminServ::initialize(false) ){
			$out = AdminServ::addChatServerLine($message, $nickname, $color, $destination, true);
		}
		$client->Terminate();
	}
	
	// OUT
	echo json_encode($out);
?>
<?php	// AUTHENTICATION	$LEVEL = 'User';	// ISSET	if( isset($_GET['cfg']) ){ $path_cfg = $_GET['cfg']; }else{ $path_cfg = null; }	if( isset($_GET['rsc']) ){ $path_rsc = $_GET['rsc']; }else{ $path_rsc = null; }	// INCLUDES    if(preg_match('/\.cfg\.php$/', $path_cfg)){        $serverConfig = '../../'.str_replace('../', '', $path_cfg);        if(file_exists($serverConfig)){            require_once $serverConfig;        }    }else{        header("HTTP/1.1 400 Bad Request");        die("Specified file is not a config.");    }	require_once '../class/GbxRemote.inc.php';	require_once '../class/tmnick.class.php';	require_once '../class/utils.class.php';	$langCode = Utils::getLang();	$langFile = '../lang/'.$langCode.'.php';	if( file_exists($langFile) ){		require_once $langFile;	}	// FUNCTIONS	function sortByTeam($a, $b){		// Modification		if($a['teamId'] == 0){			$a['teamId'] = 'blue';		}else if($a['teamId'] == 1){			$a['teamId'] = 'red';		}else{			$a['teamId'] = 'spectator';		}		if($b['teamId'] == 0){			$b['teamId'] = 'blue';		}else if($b['teamId'] == 1){			$b['teamId'] = 'red';		}else{			$b['teamId'] = 'spectator';		}		// Comparaison		if($a['teamId'] == $b['teamId']){			return 0;		}		if($a['teamId'] < $b['teamId']){			return -1;		}else{			return 1;		}	}	// DATA	$out = array();	if( class_exists('ServerConfig') ){		if( isset(ServerConfig::$SERVERS) && count(ServerConfig::$SERVERS) > 0 && !isset(ServerConfig::$SERVERS['new server name']) && !isset(ServerConfig::$SERVERS['']) ){			$serverId = 0;			foreach(ServerConfig::$SERVERS as $serverName => $serverValues){				// Connexion				$client = new IXR_ClientMulticall_Gbx;				if( !$client->InitWithIp($serverValues['address'], $serverValues['port']) ){					$out['servers'][$serverId]['error'] = Utils::t('Offline server.');				}				else{					if( !$client->query('Authenticate', $LEVEL, $serverValues['ds_pw']) ){						$out['servers'][$serverId]['error'] = Utils::t('Authentication error.');					}					else{						// Connecté sur						$client->query('GetVersion');						$version = $client->getResponse();						$out['servers'][$serverId]['version']['name'] = $version['Name'];						// Protocole : tmtp ou maniaplanet						$linkProtocol = 'maniaplanet';						if($version['Name'] == 'TmForever'){							$linkProtocol = 'tmtp';						}						$out['servers'][$serverId]['version']['protocol'] = $linkProtocol;						// Jeu						if($version['Name'] == 'TmForever'){							$queryName = array(								'getMapInfo' => 'GetCurrentChallengeInfo',							);						}						else{							$queryName = array(								'getMapInfo' => 'GetCurrentMapInfo',							);						}						// Requêtes						$client->addCall('GetServerName');						$client->addCall('GetSystemInfo');						$client->addCall('GetStatus');						$client->addCall('GetGameMode');						$client->addCall($queryName['getMapInfo']);						$client->addCall('GetPlayerList', array(50, 0) );						$client->addCall('GetMaxPlayers');						$client->multiquery();						$queriesData = $client->getMultiqueryResponse();						// Nom						$out['servers'][$serverId]['name'] = TmNick::toHtml($queriesData['GetServerName'], 10, true, false, '#999');						// Login						$system = $queriesData['GetSystemInfo'];						$out['servers'][$serverId]['serverlogin'] =  $system['ServerLogin'];						// Title						$title = null;						if($version['Name'] != 'TmForever'){							$title = $system['TitleId'];						}						$out['servers'][$serverId]['version']['title'] = $title;						// Statut						$status = $queriesData['GetStatus'];						$out['servers'][$serverId]['status'] = $status['Name'];						// GameMode						$gameMode = $queriesData['GetGameMode'];						$gameModeListName = array(							'Script',							'Rounds',							'TimeAttack',							'Team',							'Laps',							'Laps',							'Stunts',							'Cup'						);						if($version['Name'] == 'TmForever'){							$gameMode++;						}						$gameModeName = $gameModeListName[$gameMode];                        if($gameModeName == 'Script') {                            $client->addCall('GetScriptName');                            $client->multiquery();                            $scriptname = $client->getMultiqueryResponse();                            $out['servers'][$serverId]['gamemode'] = $gameModeName." (".str_replace('.Script.txt','',$scriptname['GetScriptName']['CurrentValue']).")";                        } else {						    $out['servers'][$serverId]['gamemode'] = $gameModeName;                        }						// Map						$currentMapInfo = $queriesData[$queryName['getMapInfo']];						$currentMapEnv = $currentMapInfo['Environnement'];						if($currentMapEnv == 'Speed'){							$currentMapEnv = 'Desert';						}						else if($currentMapEnv == 'Alpine'){							$currentMapEnv = 'Snow';						}						$currentMapEnvFile = null;						$pathToEnvFile = $path_rsc.'images/env/'.strtolower($currentMapEnv).'.png';						if( file_exists('../../'.$pathToEnvFile) ){							$currentMapEnvFile = $pathToEnvFile;						}						$out['servers'][$serverId]['map']['name'] = TmNick::toHtml(htmlspecialchars($currentMapInfo['Name'], ENT_QUOTES, 'UTF-8'), 10, true, false, '#999');						$out['servers'][$serverId]['map']['env']['name'] = $currentMapEnv;						$out['servers'][$serverId]['map']['env']['filename'] = $currentMapEnvFile;						// Players						$playerList = $queriesData['GetPlayerList'];						$countPlayerList = count($playerList);						if( $countPlayerList > 0 ){							$playerId = 0;							foreach($playerList as $player){								if($player['IsSpectator'] != 0){ $playerStatus = Utils::t('Spectator'); }else{ $playerStatus = Utils::t('Player'); }								if($player['TeamId'] == 0){ $teamName = Utils::t('Blue'); }else if($player['TeamId'] == 1){ $teamName = Utils::t('Red'); }else{ $teamName = Utils::t('Spectator'); }								$out['players'][$serverId]['list'][$playerId] = array(									'name' => TmNick::toHtml(htmlspecialchars($player['NickName'], ENT_QUOTES, 'UTF-8'), 10, true),									'status' => $playerStatus,									'teamId' => $player['TeamId'],									'teamName' => $teamName								);								$playerId++;							}						}						else{							$out['players'][$serverId]['list'] = Utils::t('No player');						}						// Tri mode team						if($gameModeName == 'Team' && $countPlayerList > 0){							uasort($out['players'][$serverId]['list'], 'sortByTeam');						}						// Count players						$maxPlayers = $queriesData['GetMaxPlayers'];						$out['players'][$serverId]['count']['current'] = $countPlayerList;						$out['players'][$serverId]['count']['max'] = $maxPlayers['NextValue'];					}				}				// Déconnexion				$client->Terminate();				$serverId++;			}		}	}	// Retour	echo json_encode($out);?>
<?php
	// ISSET
	if( isset($_GET['cfg']) ){ $path_cfg = $_GET['cfg']; }else{ $path_cfg = null; }

	// INCLUDES
	require_once '../class/utils.class.php';

    if(preg_match('/\.cfg\.php$/', $path_cfg)){
        $serverConfig = '../../'.str_replace('../', '', $path_cfg);
        if(file_exists($serverConfig)){
            require_once $serverConfig;
        }
    }else{
        header("HTTP/1.1 400 Bad Request");
        die("Specified file is not a config.");
    }

	$langCode = Utils::getLang();
	$langFile = '../lang/'.$langCode.'.php';
	if( file_exists($langFile) ){
		require_once $langFile;
	}

	// DATA
	$out = array();
	if( class_exists('ServerConfig') ){
		if( isset(ServerConfig::$SERVERS) && count(ServerConfig::$SERVERS) > 0 && !isset(ServerConfig::$SERVERS['new server name']) && !isset(ServerConfig::$SERVERS['']) ){
			$out['servers'] = count(ServerConfig::$SERVERS);
			$out['label']['server'] = Utils::t('Server');
			$out['label']['name'] = Utils::t('Server name');
			$out['label']['login'] = Utils::t('Server login');
			$out['label']['connect'] = Utils::t('Connected on');
			$out['label']['status'] = Utils::t('Status');
			$out['label']['gamemode'] = Utils::t('Game mode');
			$out['label']['currentmap'] = Utils::t('Current map');
			$out['label']['players'] = Utils::t('Players');
			$out['label']['accessserverplayer'] = Utils::t('Access as player');
			$out['label']['accessserverspectate'] = Utils::t('Access as spectator');
			$out['label']['addfavourite'] = Utils::t('Add to favourite');
		}
	}
	echo json_encode($out);
?>
<?php
	// INCLUDES
	session_start();
	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminlevel.cfg.php';
	require_once $configPath.'adminserv.cfg.php';
	require_once $configPath.'extension.cfg.php';
	require_once $configPath.'servers.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	AdminServUI::lang();
	
	// ISSET
	if( isset($_GET['s']) ){ $hideServerLines = $_GET['s']; }else{ $hideServerLines = false; }
	
	// DATA
	$out = null;
	if( AdminServ::initialize(false) ){
		$out = AdminServ::getChatServerLines($hideServerLines);
	}
	
	// OUT
	$client->Terminate();
	echo json_encode($out);
?>
<?php
	// INCLUDES
	require_once '../class/tmnick.class.php';
	
	// ISSET
	if( isset($_GET['t']) ){ $text = stripslashes($_GET['t']); }else{ $text = null; }
	
	// DATA
	$out = null;
	if($text != null){
		$out['str'] = TmNick::toHtml( nl2br($text), 10, false, false, '#666');
	}
	
	// OUT
	echo json_encode($out);
?>
<?php
	// INCLUDES
	session_start();
	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminlevel.cfg.php';
	require_once $configPath.'adminserv.cfg.php';
	require_once $configPath.'extension.cfg.php';
	require_once $configPath.'servers.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	AdminServUI::lang();
	
	// ISSET
	if( isset($_GET['mode']) ){ $mode = addslashes($_GET['mode']); }else{ $mode = null; }
	if( isset($_GET['sort']) ){ $sort = addslashes($_GET['sort']); }else{ $sort = null; }
	if($mode){
		$_SESSION['adminserv']['mode']['general'] = $mode;
	}
	
	// DATA
	if( AdminServ::initialize() ){
		$out = AdminServ::getCurrentServerInfo($sort);
	}
	
	// OUT
	$client->Terminate();
	echo json_encode($out);
?>
<?php
	// INCLUDES
	session_start();
	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminlevel.cfg.php';
	require_once $configPath.'adminserv.cfg.php';
	require_once $configPath.'extension.cfg.php';
	require_once $configPath.'servers.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	
	// DATA
	$out = array();
	if( AdminServ::initialize() ){
		$path = AdminServ::getMapsDirectoryPath();
		$out = Folder::getArborescence($path, AdminServConfig::$MAPS_HIDDEN_FOLDERS, substr_count($path, '/'));
	}
	
	// OUT
	$client->Terminate();
	echo json_encode($out);
?>
<?php
	// INCLUDES
	session_start();
	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminlevel.cfg.php';
	require_once $configPath.'adminserv.cfg.php';
	require_once $configPath.'extension.cfg.php';
	require_once $configPath.'servers.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	AdminServUI::lang();
	
	// ISSET
	if( isset($_GET['mode']) ){ $mode = addslashes($_GET['mode']); }else{ $mode = null; }
	if( isset($_GET['sort']) ){ $sort = addslashes($_GET['sort']); }else{ $sort = null; }
	if($mode){
		$_SESSION['adminserv']['mode']['maps'] = $mode;
	}
	
	// DATA
	if( AdminServ::initialize() ){
		$out = AdminServ::getMapList($sort);
	}
	
	// OUT
	$client->Terminate();
	echo json_encode($out);
?>
<?php
	// INCLUDES
	session_start();
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminserv.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	
	// ISSET
	if( isset($_GET['path']) ){ $path = $_GET['path']; }else{ $path = null; }
	if( isset($_GET['name']) ){ $name = $_GET['name']; }else{ $name = null; }
	
	// CHECKING
	$out = false;
	if($path && $name){
		$struct = Folder::read($path);
		if( !strstr($name, '.txt') ){
			$name = $name.'.txt';
		}
		
		if( count($struct['files']) > 0 ){
			foreach($struct['files'] as $fileName => $fileValues){
				if($name == $fileName){
					$out = true;
					break;
				}
			}
		}
	}
	
	// OUT
	echo json_encode($out);
?>
<?php
	// INCLUDES
	session_start();
	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminlevel.cfg.php';
	require_once $configPath.'adminserv.cfg.php';
	require_once $configPath.'extension.cfg.php';
	require_once $configPath.'servers.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	AdminServUI::lang();
	
	// ISSET
	if( isset($_GET['path']) ){ $path = addslashes($_GET['path']); }else{ $path = null; }
	if( isset($_GET['d']) ){ $directory = addslashes($_GET['d']); }else{ $directory = null; }
	if( isset($_GET['op']) ){ $operation = addslashes($_GET['op']); }else{ $operation = null; }
	if( isset($_GET['select']) ){ $selection = $_GET['select']; }else{ $selection = null; }
	
	// DATA
	$out = null;
	if( AdminServ::initialize() && $path != null ){
		// Maps
		if($path == 'currentServerSelection'){
			$mapsImport = AdminServ::getMapList();
		}
		else{
			$currentDir = Folder::read($path, AdminServConfig::$MATCHSET_HIDDEN_FOLDERS, AdminServConfig::$MATCHSET_EXTENSION, intval(AdminServConfig::RECENT_STATUS_PERIOD * 3600) );
			$mapsImport = AdminServ::getLocalMapList($currentDir, $directory);
		}
		
		// Faire une sélection
		if($operation == 'setSelection'){
			// On supprime les maps non sélectionnées
			if( $selection != null && count($selection) > 0 ){
				foreach($mapsImport['lst'] as $id => $values){
					if( !in_array($id, $selection) ){
						unset($mapsImport['lst'][$id]);
					}
				}
			}
			else{
				foreach($mapsImport['lst'] as $id => $values){
					unset($mapsImport['lst'][$id]);
				}
			}
		}
		
		// Enregistrement de la sélection du MatchSettings
		if($operation != 'getSelection'){
			AdminServ::saveMatchSettingSelection($mapsImport);
		}
		
		$client->Terminate();
	}
	
	// OUT
	if($operation == 'getSelection'){
		echo json_encode($mapsImport);
	}
	else{
		echo json_encode($_SESSION['adminserv']['matchset_maps_selected']);
	}
?>
<?php
	// INCLUDES
	session_start();
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminserv.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	AdminServUI::lang();
	
	// DATA
	if( !isset($_SESSION['adminserv']['matchset_maps_selected']) ){
		// Retourne "Aucune map"
		AdminServ::saveMatchSettingSelection();
	}
	else{
		// Enlever une map de la sélection
		if( isset($_GET['remove']) ){
			$removeSelection = intval($_GET['remove']);
			$mapsSelection = $_SESSION['adminserv']['matchset_maps_selected'];
			
			// Liste
			if( isset($mapsSelection['lst']) && is_array($mapsSelection['lst']) && count($mapsSelection['lst']) > 0 ){
				foreach($mapsSelection['lst'] as $id => $values){
					if($id == $removeSelection){
						unset($mapsSelection['lst'][$id]);
						break;
					}
				}
			}
			
			$_SESSION['adminserv']['matchset_maps_selected'] = $mapsSelection;
			AdminServ::saveMatchSettingSelection();
		}
	}
	
	echo json_encode($_SESSION['adminserv']['matchset_maps_selected']);
?>
<?php
	// INCLUDES
	session_start();
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminlevel.cfg.php';
	require_once $configPath.'adminserv.cfg.php';
	require_once $configPath.'servers.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	
	// ISSET
	if( isset($_GET['srv']) ){ $serverName = $_GET['srv']; }else{ $serverName = null; }
	
	$out = array();
	if($serverName != null){
		$out = AdminServAdminLevel::getServerList($serverName);
	}
	
	echo json_encode($out);
?>
<?php
	// INCLUDES
	session_start();
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminserv.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	
	// ISSET
 	if( isset($_POST['srt']) ){ $sort = $_POST['srt']; }else{ $sort = null; }
	if( isset($_POST['ord']) ){ $order = $_POST['ord']; }else{ $order = 'asc'; }
	if( isset($_POST['lst']) ){ $list = $_POST['lst']; }else{ $list = null; }
	
	// DATA
	$out = null;
	if($sort != null && $list != null){
		$list = json_decode($list, true);
		
		switch($sort){
			case 'name':
				usort($list['lst'], 'AdminServSort::sortByName');
				break;
			case 'env':
				usort($list['lst'], 'AdminServSort::sortByEnviro');
				break;
			case 'author':
				usort($list['lst'], 'AdminServSort::sortByAuthor');
				break;
			case 'rand':
				shuffle($list['lst']);
				break;
		}
		if($order == 'desc'){
			$list['lst'] = array_reverse($list['lst']);
		}
		$out = array(
			'cid' => $list['cid'],
			'lst' => $list['lst'],
			'nbm' => $list['nbm'],
		);
	}
	
	// OUT
	echo json_encode($out);
?>
<?php
	// INCLUDES
	session_start();
	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminlevel.cfg.php';
	require_once $configPath.'adminserv.cfg.php';
	require_once $configPath.'extension.cfg.php';
	require_once $configPath.'servers.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	
	// ISSET
	if( isset($_POST['method']) ){ $method = $_POST['method']; }else{ $method = null; }
	if( isset($_POST['params']) ){ $params = $_POST['params']; }else{ $params = null; }
	
	// DATA
	$out = null;
	if( AdminServ::initialize() ){
		if(SERVER_VERSION_NAME == 'ManiaPlanet'){
			if($method == 'set' && $params != null){
				$scriptSettings = array();
				if( count($params) > 0 ){
					foreach($params as $param){
						$scriptSettings[$param['name']] = Str::setValueType($param['value'], $param['type']);
					}
				}
				
				if( !$client->query('SetModeScriptSettings', $scriptSettings) ){
					$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
				}
				else{
					$out = true;
				}
			}
			else{
				if( !$client->query('GetModeScriptInfo') ){
					$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
				}
				else{
					$out = $client->getResponse();
				}
			}
		}
	}
	
	// OUT
	$client->Terminate();
	echo json_encode($out);
?>
<?php
	// INCLUDES
	session_start();
	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }
	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';
	require_once $configPath.'adminlevel.cfg.php';
	require_once $configPath.'adminserv.cfg.php';
	require_once $configPath.'extension.cfg.php';
	require_once $configPath.'servers.cfg.php';
	require_once '../core/adminserv.php';
	AdminServConfig::$PATH_RESOURCES = '../';
	AdminServ::getClass();
	
	// ISSET
	if( isset($_POST['cmd']) ){ $cmd = addslashes( htmlspecialchars($_POST['cmd']) ); }else{ $cmd = null; }
	
	// SPEED ADMIN
	$out = false;
	if($cmd != null){
		if( AdminServ::initialize() ){
			$out = AdminServ::speedAdmin($cmd);
		}
	}
	
	// OUT
	$client->Terminate();
	echo json_encode($out);
?>
<?php	// INCLUDES	session_start();	if( !isset($_SESSION['adminserv']['sid']) ){ exit; }	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';	require_once $configPath.'adminlevel.cfg.php';	require_once $configPath.'adminserv.cfg.php';	require_once $configPath.'extension.cfg.php';	require_once $configPath.'servers.cfg.php';	require_once '../core/adminserv.php';	AdminServConfig::$PATH_RESOURCES = '../';	AdminServ::getClass();	AdminServUI::lang();	// ISSET	if( isset($_GET['path']) ){ $path = $_GET['path']; }else{ $path = null; }	if( isset($_GET['gtlm']) ){ $gtlm = $_GET['gtlm']; }else{ $gtlm = null; }	if( isset($_GET['mset']) ){ $mset = $_GET['mset']; }else{ $mset = null; }	if( isset($_GET['type']) ){ $type = $_GET['type']; }else{ $type = null; }	// DATA	if( AdminServ::initialize() ){		// Path		$mapDirectoryPath = AdminServ::getMapsDirectoryPath();		if(preg_match('/^\//', $path)){            header("HTTP/1.1 400 Bad Request");            die("Absolute paths are not allowed.");        }		if($path === null){			$path = $mapDirectoryPath;		}		if( substr($path, -1, 1) != '/'){			$path = $path.'/';		}		if( !file_exists($path) ){			$path = null;			if( defined('AdminServConfig::UPLOAD_ONLINE_FOLDER') && AdminServConfig::UPLOAD_ONLINE_FOLDER != null ){				$path = AdminServConfig::UPLOAD_ONLINE_FOLDER;			}		}		// Fonction de rappel pour le remplacement des caractères spéciaux		function replaceFilename($str){			return Str::replaceChars($str);		}		// Jeu		if(SERVER_VERSION_NAME == 'TmForever'){			$queries = array(				'insert' => 'InsertChallenge',				'add' => 'AddChallenge',				'type' => $type			);		}		else{			$queries = array(				'insert' => 'InsertMap',				'add' => 'AddMap',				'type' => $type			);		}		// Taille max		if(AdminServConfig::SIZE_LIMIT == 'auto'){			$sizeLimit1 = (intval(ini_get('post_max_size')) * 1024 * 1024);			$sizeLimit2 = (intval(ini_get('upload_max_filesize')) * 1024 * 1024);			$sizeLimit = min($sizeLimit1, $sizeLimit2);		}		else{			$sizeLimit = (intval(AdminServConfig::SIZE_LIMIT) * 1024 * 1024);		}		// Enregistrement du fichier		$result = FileUploader::saveUploadedFileToManiaPlanetServer($client, $path, $queries, AdminServConfig::$ALLOWED_EXTENSIONS, $sizeLimit, 'replaceFilename');		// Sauvegarde du MatchSettings		if($mset && SERVER_MATCHSET && $type != 'local' && isset($result['success']) && $result['success'] == true){			if( !$client->query('SaveMatchSettings', $mapDirectoryPath.SERVER_MATCHSET) ){				$result['error'] = '['.$client->getErrorCode().'] '.$client->getErrorMessage();			}		}	}	$client->Terminate();	echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);?>
{"4x4-off-road.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#663300\">4x4 off road<\/span><\/span>","Environment":"Canyon","FileName":"4x4-off-road.Map.Gbx","UId":"Qv3k5wnovhc5WbbEmUMsXXao3A1","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"8-defonce.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#006666\">8 d\u00e9fonc\u00e9<\/span><\/span>","Environment":"Canyon","FileName":"8-defonce.Map.Gbx","UId":"hYenoR7LZzdVSgaux_pSEYNwu45","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Attention-au-frein.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc33\">Attention au frein<\/span><\/span>","Environment":"Canyon","FileName":"Attention-au-frein.Map.Gbx","UId":"a0pRKdQoPI5zLmADzIGZLzHwdPh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Attraction.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">Attraction<\/span><\/span>","Environment":"Canyon","FileName":"Attraction.Map.Gbx","UId":"M42mf_WR3zKFGngLdv4dl_WkSkf","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Autoroute.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#009900\">Autoroute<\/span><\/span>","Environment":"Canyon","FileName":"Autoroute.Map.Gbx","UId":"sZ9IeicBn4KAq28YmjmstwEYjv0","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Boite.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0066\">Boite<\/span><\/span>","Environment":"Canyon","FileName":"Boite.Map.Gbx","UId":"LjZ10Y1fpp9OUIuX7O71Mb7PZ01","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Canada---Etape-1.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">Canada <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 1<\/span><\/span>","Environment":"Canyon","FileName":"Canada---Etape-1.Map.Gbx","UId":"04Bc42Q79i87E8kAQz6_kdX7tQj","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Canada---Etape-2.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">Canada <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 2<\/span><\/span>","Environment":"Canyon","FileName":"Canada---Etape-2.Map.Gbx","UId":"b81vfeiBo9am2NxJTZmGr39pjW8","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Canada---Etape-3.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">Canada <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 3<\/span><\/span>","Environment":"Canyon","FileName":"Canada---Etape-3.Map.Gbx","UId":"y5onnQXohjAB0IM5R4RAdaitTKe","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Canada---Etape-4.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">Canada <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 4<\/span><\/span>","Environment":"Canyon","FileName":"Canada---Etape-4.Map.Gbx","UId":"NK37fOQJaYX7TFrnBV3uQnZ8S93","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"CreationSkin.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:white\">Cr\u00e9ationSkin<\/span><\/span>","Environment":"Canyon","FileName":"CreationSkin.Map.Gbx","UId":"4JUUciJTt4pXA31rhzziUnMsW31","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Race"}},"Egypte---Etape-1.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc00\">Egypte <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 1<\/span><\/span>","Environment":"Canyon","FileName":"Egypte---Etape-1.Map.Gbx","UId":"FbRbV3sLZgvSPOa2cgpFssfmsYe","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Egypte---Etape-2.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc00\">Egypte <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 2<\/span><\/span>","Environment":"Canyon","FileName":"Egypte---Etape-2.Map.Gbx","UId":"wgmbpGVJ4YDN1rWnv3rQgK1OzJg","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Egypte---Etape-3.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc00\">Egypte <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 3<\/span><\/span>","Environment":"Canyon","FileName":"Egypte---Etape-3.Map.Gbx","UId":"2OWdjMFiLnIKTDPbLIaKEoY4pu0","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Egypte---Etape-4.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc00\">Egypte <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 4<\/span><\/span>","Environment":"Canyon","FileName":"Egypte---Etape-4.Map.Gbx","UId":"kERIXFivYyDC48EokcdoMHNMa24","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Elite---ArchWays.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite - <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff2200\">Ar<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff3311\">ch<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff4422\">Wa<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff5533\">ys<\/span><\/span>","Environment":"Storm","FileName":"Elite---ArchWays.Map.Gbx","UId":"SKFHlXwDZnJiau2r2iRMMur7BC5","Author":"nadeolive","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---Collided.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite - <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff2200\">Co<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff3311\">lli<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff4422\">de<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff5533\">d<\/span><\/span>","Environment":"Storm","FileName":"Elite---Collided.Map.Gbx","UId":"03K2a6a0q9WihtbQmEodDXsQZE9","Author":"nadeolive","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---ESL_Tilt.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite - <\/span><span class=\"tmnick_italic tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">ESL|<\/span><span class=\"\" style=\"font-size: 10pt;color:white\"> Tilt<\/span><\/span>","Environment":"Storm","FileName":"Elite---ESL_Tilt.Map.Gbx","UId":"MG5o8ZAHgcD4zZtrnzScizCjFZd","Author":"kyb","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---Fortress.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite - <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff2200\">Fo<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff3311\">rt<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff4422\">re<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff5533\">ss<\/span><\/span>","Environment":"Storm","FileName":"Elite---Fortress.Map.Gbx","UId":"6niuYlVqoCIkDlCdFTpEZTh7LF8","Author":"nadeolive","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---Isolated-.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:white\">Elite - Isolated <\/span><\/span>","Environment":"Storm","FileName":"Elite---Isolated-.Map.Gbx","UId":"0kJYrghOkWOUBV2Ym1o_GbqIjfl","Author":"skoonyz","Recent":0,"Type":{"Name":"SiegeArena","FullName":"ShootMania\\SiegeArena"}},"Elite---Paladin.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite<\/span><span class=\"tmnick_bold\" style=\"font-size: 10pt;color:white\"> - <\/span><span class=\"tmnick_bold\" style=\"font-size: 10pt;color:#ffff55\">Paladin<\/span><\/span>","Environment":"Storm","FileName":"Elite---Paladin.Map.Gbx","UId":"M50azStIw1KWYPAJOGitLV4msYk","Author":"kryw","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---Quick.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:white\">Elite - Quick<\/span><\/span>","Environment":"Storm","FileName":"Elite---Quick.Map.Gbx","UId":"lD4uGyw8OGFTJgUxpfVEAREnBA3","Author":"skoonyz","Recent":0,"Type":{"Name":"SiegeArena","FullName":"ShootMania\\SiegeArena"}},"Elite---Swift.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite<\/span><span class=\"tmnick_bold\" style=\"font-size: 10pt;color:white\"> - <\/span><span class=\"tmnick_bold tmnick_italic\" style=\"font-size: 10pt;color:#004499\">Swift<\/span><\/span>","Environment":"Storm","FileName":"Elite---Swift.Map.Gbx","UId":"48FyaLm__ft12cQ6i96KrmoRuwi","Author":"ph0enix","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Elite---TheCastle.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Elite - <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff2200\">Th<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff3311\">eC<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff4422\">as<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff5533\">tl<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff6644\">e<\/span><\/span>","Environment":"Storm","FileName":"Elite---TheCastle.Map.Gbx","UId":"Lx2Ik2GEcSObirozQvio6bRRWHj","Author":"nadeolive","Recent":0,"Type":{"Name":"EliteArena","FullName":"ShootMania\\EliteArena"}},"Finlande---Etape-1.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#003399\">Finlande <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 1<\/span><\/span>","Environment":"Canyon","FileName":"Finlande---Etape-1.Map.Gbx","UId":"Jjv2bS9bSAhPDo0ddGQ65IuHahh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Finlande---Etape-2.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#003399\">Finlande <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 2<\/span><\/span>","Environment":"Canyon","FileName":"Finlande---Etape-2.Map.Gbx","UId":"VN5iYuP5oYx0PnvDKHbM09TKPL1","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Finlande---Etape-3.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#003399\">Finlande <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 3<\/span><\/span>","Environment":"Canyon","FileName":"Finlande---Etape-3.Map.Gbx","UId":"Saa55CJ4euzzNo8sYf1BhwwhEN8","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Finlande---Etape-4.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#003399\">Finlande <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">Etape 4<\/span><\/span>","Environment":"Canyon","FileName":"Finlande---Etape-4.Map.Gbx","UId":"ub3X0hFop3dyIdJXV_SeZID27Dh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Free-way.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#99ff33\">Free way<\/span><\/span>","Environment":"Canyon","FileName":"Free-way.Map.Gbx","UId":"ftaKnDEO7zyYIH0Irdxn6wonXD0","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Hummm.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0099cc\">Hummm<\/span><\/span>","Environment":"Canyon","FileName":"Hummm.Map.Gbx","UId":"4yRQq_90nR47IxnaHu1evHDIDm3","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"In-the-sky.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#66ffff\">In the sky<\/span><\/span>","Environment":"Canyon","FileName":"In-the-sky.Map.Gbx","UId":"dEu6pX1lC02z7sgIh8L3PXmIAhh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Jouissance-saccadee.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#996600\">Jou\u00efssance saccad\u00e9e<\/span><\/span>","Environment":"Canyon","FileName":"Jouissance-saccadee.Map.Gbx","UId":"l4ZFhAq_iVFEwcWOnUqShYcxZok","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Jump-and-jump-and....Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#000033\">Jump and jump and...<\/span><\/span>","Environment":"Canyon","FileName":"Jump-and-jump-and....Map.Gbx","UId":"IlA6Gk99GLAhmlRiyhA6EttoXW3","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Jump-around.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffcc00\">Jump around<\/span><\/span>","Environment":"Canyon","FileName":"Jump-around.Map.Gbx","UId":"AxYOLDm_yHl8Vpr2OTKPrjjNWic","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Labyrinthe.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ccff00\">Labyrinthe<\/span><\/span>","Environment":"Canyon","FileName":"Labyrinthe.Map.Gbx","UId":"qjhyktiuJbyuYe1WmeU5cEhFrSb","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Looping-en-folie.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0000cc\">Looping en folie<\/span><\/span>","Environment":"Canyon","FileName":"Looping-en-folie.Map.Gbx","UId":"4fTM17a8FfjhYK7eTczAWbp5Rzl","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Micromania-1.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#990033\">Micromania <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffffff\">#1<\/span><\/span>","Environment":"Canyon","FileName":"Micromania-1.Map.Gbx","UId":"RiP6EIEzDXeDpoyeDW46Nd5AFY3","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Mountain.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:white\">Mountain<\/span><\/span>","Environment":"Canyon","FileName":"Mountain.Map.Gbx","UId":"aiYLZv1Rfye5oyortcvA2xLfzSd","Author":"dangmaar","Recent":0,"Type":{"Name":"Race","FullName":"Race"}},"Multi-track.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#cc6600\">Multi track<\/span><\/span>","Environment":"Canyon","FileName":"Multi-track.Map.Gbx","UId":"J5mYHM7toOpf02a84rxqDgHz74","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Pilot-only.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#9933cc\">Pilot only<\/span><\/span>","Environment":"Canyon","FileName":"Pilot-only.Map.Gbx","UId":"hV5F90irAgT8KCItlA98lffhI_i","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Propulsion-arride.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#990000\">Propulsion arride<\/span><\/span>","Environment":"Canyon","FileName":"Propulsion-arride.Map.Gbx","UId":"JoGkfMUfcPbFwJlEcEF3YDUiiQ1","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Race-building.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#000000\">Race building<\/span><\/span>","Environment":"Canyon","FileName":"Race-building.Map.Gbx","UId":"anbrAYil1kFI0RRPfHwGdzzjeNh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Razmotte.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#99ff00\">Razmotte<\/span><\/span>","Environment":"Canyon","FileName":"Razmotte.Map.Gbx","UId":"a9zuQJgfKHz20kAsYSQlDMxGxfk","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"TrackMania\\Race"}},"Routes-de-corse.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#cc5500\">Routes de corse<\/span><\/span>","Environment":"Canyon","FileName":"Routes-de-corse.Map.Gbx","UId":"npVglWKptFQoczmEBB7fkbvYJjj","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Suede---Etape-1.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0088cc\">Su\u00e8de <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffff00\">Etape 1<\/span><\/span>","Environment":"Canyon","FileName":"Suede---Etape-1.Map.Gbx","UId":"0JSJchwnoPLXs7E0kSREdRVxAR1","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Suede---Etape-2.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0088cc\">Su\u00e8de <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffff00\">Etape 2<\/span><\/span>","Environment":"Canyon","FileName":"Suede---Etape-2.Map.Gbx","UId":"aQYVgcAnWd8W6o4yOXx8HHEDPS9","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Suede---Etape-3.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0088cc\">Su\u00e8de <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffff00\">Etape 3<\/span><\/span>","Environment":"Canyon","FileName":"Suede---Etape-3.Map.Gbx","UId":"8VX6HVIT_wCCBhgWIOKcMwm5O_2","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Suede---Etape-4.Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#0088cc\">Su\u00e8de <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#333333\">- <\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ffff00\">Etape 4<\/span><\/span>","Environment":"Canyon","FileName":"Suede---Etape-4.Map.Gbx","UId":"pirzLg0bV7owjst4AG6Yu2Qtphh","Author":"kev717","Recent":0,"Type":{"Name":"Race","FullName":"Trackmania\\Race"}},"Tmeless..Map.Gbx":{"Name":"<span class=\"tmnick_global\" style=\"background-color:transparent\"><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#000000\">T<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">!<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#000000\">meless<\/span><span class=\"tmnick_shadowed\" style=\"font-size: 10pt;color:#ff0000\">.<\/span><\/span>","Environment":"Stadium","FileName":"Tmeless..Map.Gbx","UId":"UoU7guI2ww_P5cWCRwUMfSej3w1","Author":"unholy79","Recent":0,"Type":{"Name":"Race","FullName":"TrackMania\\Race"}}}
<?php
/* vim: set noexpandtab tabstop=2 softtabstop=2 shiftwidth=2: */

/*
	IXR - The Incutio XML-RPC Library - (c) Incutio Ltd 2002
	Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
	Site:   http://scripts.incutio.com/xmlrpc/
	Manual: http://scripts.incutio.com/xmlrpc/manual.php
	Errors: http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
	Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php

	Modified to support protocol 'GbxRemote 2' ('GbxRemote 1')
	This version is for LittleEndian (e.g. Intel PC) machines.  For BegEndian
	machines use GbxRemote.bem.php as GbxRemote.inc.php instead.

	Release 2007-09-22 - Slig:
		Modified to support >256KB received data (and now >2MB data produce a specific error message)
		Modified readCB() to wait the initial timeout only before first read packet
		Modified readCB() to return true if there is data to get with getCBResponses()
		Modified to support amd64 (for $recvhandle)
		Modified IXR_ClientMulticall_Gbx::addCall() to fit Aseco 0.6.1
		Added IXR_Client_Gbx::bytes_sent & bytes_received counters
		Fix for a changed feature since php5.1.1 about reference parameter assignment (was used in stream_select)
		Workaround for stream_select return value bug with amd64

	Release 2008-01-20 - Slig / Xymph / Assembler Maniac:
		Workaround for fread delay bug in some cases
		Added IXR_Client_Gbx::resetError() method (by Xymph)
		Some comments and strings code cleanup (by Xymph)
		Fix stream_set_timeout($this->socket,...) (thx to CavalierDeVache)
		Added a default timeout value to IXR_Client_Gbx::readCB($timeout)
		Changed calls with timeout on a stream to use microseconds instead of seconds (by AM)
		Removed IXR_Client_Gbx::bytes_sent & bytes_received counters - not used (by AM)

	Release 2008-02-05 - Slig:
		Changed some socket read/write timeouts back to seconds to avoid 'transport error'
		Changed max data received from 2MB to 4MB

	Release 2008-05-20 - Xymph:
		Prevented unpack() warnings in IXR_Client_Gbx::query() when the connection dies
		Changed IXR_Client_Gbx::resetError() to assign 'false' for correct isError()
		Tweaked some 'transport error' messages

	Release 2009-04-08 - Gou1:
		Added method IXR_Client_Gbx::queryIgnoreResult()
		Added methods IXR_Client_Gbx::sendRequest() & IXR_Client_Gbx::getResult()
		IXR_Client_Gbx::queryIgnoreResult checks if the request is larger than 512KB to avoid errors
		If larger than 512KB and method is system.multicall, try to divide the request into
		two separate requests with two separate IXR_Client_Gbx::queryIgnoreResult() calls

	Release 2009-06-03 - Xymph:
		Suppress possible repetitive CRT warning at stream_select

	Release 2011-04-09 - Xymph / La beuze:
		Added optional timeout mechanism to IXR_Client_Gbx::InitWithIp()

	Release 2011-05-22 - Xymph:
		Added non-error (true) return status to IXR_Client_Gbx::queryIgnoreResult()
		Updated status codes and messages for transport/endian errors
		Prevented possible PHP warning in IXR_Client_Gbx::getErrorCode() and getErrorMessage()

	Release 2011-12-04 - Xymph:
		Prevented possible PHP warning in IXR_Value::calculateType
*/

if (!defined('LF')) {
	define('LF', "\n");
}

class IXR_Value {
	public $data;
	public $type;

	function IXR_Value ($data, $type = false) {
		$this->data = $data;
		if (!$type) {
			$type = $this->calculateType();
		}
		$this->type = $type;
		if ($type == 'struct') {
			// Turn all the values in the array into new IXR_Value objects
			foreach ($this->data as $key => $value) {
				$this->data[$key] = new IXR_Value($value);
			}
		}
		if ($type == 'array') {
			for ($i = 0, $j = count($this->data); $i < $j; $i++) {
				$this->data[$i] = new IXR_Value($this->data[$i]);
			}
		}
	}

	function calculateType() {
		if ($this->data === true || $this->data === false) {
			return 'boolean';
		}
		if (is_integer($this->data)) {
			return 'int';
		}
		if (is_double($this->data)) {
			return 'double';
		}
		// Deal with IXR object types base64 and date
		if (is_object($this->data) && ($this->data instanceof IXR_Date)) {
			return 'date';
		}
		if (is_object($this->data) && ($this->data instanceof IXR_Base64)) {
			return 'base64';
		}
		// If it is a normal PHP object convert it into a struct
		if (is_object($this->data)) {
			$this->data = get_object_vars($this->data);
			return 'struct';
		}
		if (!is_array($this->data)) {
			return 'string';
		}
		// We have an array - is it an array or a struct?
		if ($this->isStruct($this->data)) {
			return 'struct';
		} else {
			return 'array';
		}
	}

	function getXml() {
		// Return XML for this value
		switch ($this->type) {
			case 'boolean':
				return '<boolean>' . ($this->data ? '1' : '0') . '</boolean>';
				break;
			case 'int':
				return '<int>' . $this->data . '</int>';
				break;
			case 'double':
				return '<double>' . $this->data . '</double>';
				break;
			case 'string':
				return '<string>' . htmlspecialchars($this->data) . '</string>';
				break;
			case 'array':
				$return = '<array><data>' . LF;
				foreach ($this->data as $item) {
					$return .= '	<value>' . $item->getXml() . '</value>' . LF;
				}
				$return .= '</data></array>';
				return $return;
				break;
			case 'struct':
				$return = '<struct>' . LF;
				foreach ($this->data as $name => $value) {
					$return .= '	<member><name>' . $name . '</name><value>';
					$return .= $value->getXml() . '</value></member>' . LF;
				}
				$return .= '</struct>';
				return $return;
				break;
			case 'date':
			case 'base64':
				return $this->data->getXml();
				break;
		}
		return false;
	}

	function isStruct($array) {
		// Nasty function to check if an array is a struct or not
		$expected = 0;
		foreach ($array as $key => $value) {
			if ((string)$key != (string)$expected) {
				return true;
			}
			$expected++;
		}
		return false;
	}
}


class IXR_Message {
	public $message;
	public $messageType;  // methodCall / methodResponse / fault
	public $faultCode;
	public $faultString;
	public $methodName;
	public $params;
	// Current variable stacks
	protected $_arraystructs = array();  // Stack to keep track of the current array/struct
	protected $_arraystructstypes = array();  // Stack to keep track of whether things are structs or array
	protected $_currentStructName = array();  // A stack as well
	protected $_param;
	protected $_value;
	protected $_currentTag;
	protected $_currentTagContents;
	// The XML parser
	protected $_parser;

	function IXR_Message ($message) {
		$this->message = $message;
	}

	function parse() {
		// first remove the XML declaration
		$this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message);
		if (trim($this->message) == '') {
			return false;
		}
		$this->_parser = xml_parser_create();
		// Set XML parser to take the case of tags into account
		xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
		// Set XML parser callback functions
		xml_set_object($this->_parser, $this);
		xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
		xml_set_character_data_handler($this->_parser, 'cdata');
		if (!xml_parse($this->_parser, $this->message)) {
			/* die(sprintf('GbxRemote XML error: %s at line %d',
			               xml_error_string(xml_get_error_code($this->_parser)),
			               xml_get_current_line_number($this->_parser))); */
			return false;
		}
		xml_parser_free($this->_parser);
		// Grab the error messages, if any
		if ($this->messageType == 'fault') {
			$this->faultCode = $this->params[0]['faultCode'];
			$this->faultString = $this->params[0]['faultString'];
		}
		return true;
	}

	function tag_open($parser, $tag, $attr) {
		$this->currentTag = $tag;
		switch ($tag) {
			case 'methodCall':
			case 'methodResponse':
			case 'fault':
				$this->messageType = $tag;
				break;
			// Deal with stacks of arrays and structs
			case 'data':  // data is to all intents and purposes more interesting than array
				$this->_arraystructstypes[] = 'array';
				$this->_arraystructs[] = array();
				break;
			case 'struct':
				$this->_arraystructstypes[] = 'struct';
				$this->_arraystructs[] = array();
				break;
		}
	}

	function cdata($parser, $cdata) {
		$this->_currentTagContents .= $cdata;
	}

	function tag_close($parser, $tag) {
		$valueFlag = false;
		switch ($tag) {
			case 'int':
			case 'i4':
				$value = (int)trim($this->_currentTagContents);
				$this->_currentTagContents = '';
				$valueFlag = true;
				break;
			case 'double':
				$value = (double)trim($this->_currentTagContents);
				$this->_currentTagContents = '';
				$valueFlag = true;
				break;
			case 'string':
				$value = (string)trim($this->_currentTagContents);
				$this->_currentTagContents = '';
				$valueFlag = true;
				break;
			case 'dateTime.iso8601':
				$value = new IXR_Date(trim($this->_currentTagContents));
				// $value = $iso->getTimestamp();
				$this->_currentTagContents = '';
				$valueFlag = true;
				break;
			case 'value':
				// If no type is indicated, the type is string
				if (trim($this->_currentTagContents) != '') {
					$value = (string)$this->_currentTagContents;
					$this->_currentTagContents = '';
					$valueFlag = true;
				}
				break;
			case 'boolean':
				$value = (boolean)trim($this->_currentTagContents);
				$this->_currentTagContents = '';
				$valueFlag = true;
				break;
			case 'base64':
				$value = base64_decode($this->_currentTagContents);
				$this->_currentTagContents = '';
				$valueFlag = true;
				break;
				// Deal with stacks of arrays and structs
			case 'data':
			case 'struct':
				$value = array_pop($this->_arraystructs);
				array_pop($this->_arraystructstypes);
				$valueFlag = true;
				break;
			case 'member':
				array_pop($this->_currentStructName);
				break;
			case 'name':
				$this->_currentStructName[] = trim($this->_currentTagContents);
				$this->_currentTagContents = '';
				break;
			case 'methodName':
				$this->methodName = trim($this->_currentTagContents);
				$this->_currentTagContents = '';
				break;
		}

		if ($valueFlag) {
			/*
			if (!is_array($value) && !is_object($value)) {
				$value = trim($value);
			}
			*/
			if (count($this->_arraystructs) > 0) {
				// Add value to struct or array
				if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') {
					// Add to struct
					$this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value;
				} else {
					// Add to array
					$this->_arraystructs[count($this->_arraystructs)-1][] = $value;
				}
			} else {
				// Just add as a paramater
				$this->params[] = $value;
			}
		}
	}
}


class IXR_Request {
	public $method;
	public $args;
	public $xml;

	function IXR_Request($method, $args) {
		$this->method = $method;
		$this->args = $args;
		$this->xml = '<?xml version="1.0" encoding="utf-8" ?><methodCall><methodName>' . $this->method . '</methodName><params>';
		foreach ($this->args as $arg) {
			$this->xml .= '<param><value>';
			$v = new IXR_Value($arg);
			$this->xml .= $v->getXml();
			$this->xml .= '</value></param>' . LF;
		}
		$this->xml .= '</params></methodCall>';
	}

	function getLength() {
		return strlen($this->xml);
	}

	function getXml() {
		return $this->xml;
	}
}


class IXR_Error {
	public $code;
	public $message;

	function IXR_Error($code, $message) {
		$this->code = $code;
		$this->message = $message;
	}

	function getXml() {
		$xml = <<<EOD
<methodResponse>
	<fault>
		<value>
			<struct>
				<member>
					<name>faultCode</name>
					<value><int>{$this->code}</int></value>
				</member>
				<member>
					<name>faultString</name>
					<value><string>{$this->message}</string></value>
				</member>
			</struct>
		</value>
	</fault>
</methodResponse>
EOD;
		return $xml;
	}
}


class IXR_Date {
	public $year;
	public $month;
	public $day;
	public $hour;
	public $minute;
	public $second;

	function IXR_Date($time) {
		// $time can be a PHP timestamp or an ISO one
		if (is_numeric($time)) {
			$this->parseTimestamp($time);
		} else {
			$this->parseIso($time);
		}
	}

	function parseTimestamp($timestamp) {
		$this->year = date('Y', $timestamp);
		$this->month = date('Y', $timestamp);
		$this->day = date('Y', $timestamp);
		$this->hour = date('H', $timestamp);
		$this->minute = date('i', $timestamp);
		$this->second = date('s', $timestamp);
	}

	function parseIso($iso) {
		$this->year = substr($iso, 0, 4);
		$this->month = substr($iso, 4, 2);
		$this->day = substr($iso, 6, 2);
		$this->hour = substr($iso, 9, 2);
		$this->minute = substr($iso, 12, 2);
		$this->second = substr($iso, 15, 2);
	}

	function getIso() {
		return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second;
	}

	function getXml() {
		return '<dateTime.iso8601>'.$this->getIso().'</dateTime.iso8601>';
	}

	function getTimestamp() {
		return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
	}
}


class IXR_Base64 {
	public $data;

	function IXR_Base64($data) {
		$this->data = $data;
	}

	function getXml() {
		return '<base64>'.base64_encode($this->data).'</base64>';
	}
}


//////////////////////////////////////////////////////////
// Nadeo modifications                                  //
//  (many thanks to slig for adding callback support)   //
//////////////////////////////////////////////////////////
class IXR_Client_Gbx {
	public $socket;
	public $message = false;
	public $cb_message = array();
	public $reqhandle;
	public $protocol = 0;
	// Storage place for an error message
	public $error = false;

	function bigEndianTest() {
		list($endiantest) = array_values(unpack('L1L', pack('V', 1)));
		if ($endiantest != 1) {
			echo "Machine reports itself as BigEndian, float handling must be altered\r\n";
			echo "Overwrite GbxRemote.inc.php with GbxRemote.bem.php\r\n";
			die('App Terminated');
			return false;
		}
		return true;
	}  // bigEndianTest

	function IXR_Client_Gbx() {
		$this->socket = false;
		$this->reqhandle = 0x80000000;
	}

	function InitWithIp($ip, $port, $timeout = null) {

		if (!$this->bigEndianTest()) {
			$this->error = new IXR_Error(-31999, 'endian error - script doesn\'t match machine type');
			return false;
		}

		// open connection, with timeout if specified
		if (!isset($timeout)) {
			$this->socket = @fsockopen($ip, $port, $errno, $errstr);
		} else {
			$init_time = microtime(true);
			$init_timeout = 5; // retry every 5s
			while (true) {
				$this->socket = @fsockopen($ip, $port, $errno, $errstr, $init_timeout);
				if ($this->socket || (microtime(true) - $init_time >= $timeout))
					break;
			}
		}
		if (!$this->socket) {
			$this->error = new IXR_Error(-32300, "transport error - could not open socket (error: $errno, $errstr)");
			return false;
		}
		// handshake
		$array_result = unpack('Vsize', fread($this->socket, 4));
		$size = $array_result['size'];
		if ($size > 64) {
			$this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol header');
			return false;
		}
		$handshake = fread($this->socket, $size);
		if ($handshake == 'GBXRemote 1') {
			$this->protocol = 1;
		} else if ($handshake == 'GBXRemote 2') {
			$this->protocol = 2;
		} else {
			$this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol version');
			return false;
		}
		return true;
	}

	function Init($port) {
		return $this->InitWithIp('localhost', $port);
	}

	function Terminate() {
		if ($this->socket) {
			fclose($this->socket);
			$this->socket = false;
		}
	}

	protected function sendRequest(IXR_Request $request) {
		$xml = $request->getXml();

		@stream_set_timeout($this->socket, 20);  // timeout 20s (to write the request)
		// send request
		$this->reqhandle++;
		if ($this->protocol == 1) {
			$bytes = pack('Va*', strlen($xml), $xml);
		} else {
			$bytes = pack('VVa*', strlen($xml), $this->reqhandle, $xml);
		}

		$bytes_to_write = strlen($bytes);
		while ($bytes_to_write > 0) {
			$r = @fwrite($this->socket, $bytes);
			if ($r === false || $r == 0) {
				// connection interrupted
				return false; // or die?
			}

			$bytes_to_write -= $r;
			if ($bytes_to_write == 0)
				break;

			$bytes = substr($bytes, $r);
		}

		return true;
	}

	protected function getResult() {
		$contents = '';
		$contents_length = 0;
		do {
			$size = 0;
			$recvhandle = 0;
			@stream_set_timeout($this->socket, 20);  // timeout 20s (to read the reply header)
			// Get result
			if ($this->protocol == 1) {
				$contents = fread($this->socket, 4);
				if (strlen($contents) == 0) {
					$this->error = new IXR_Error(-32300, 'transport error - cannot read size');
					return false;
				}
				$array_result = unpack('Vsize', $contents);
				$size = $array_result['size'];
				$recvhandle = $this->reqhandle;
			} else {
				$contents = fread($this->socket, 8);
				if (strlen($contents) == 0) {
					$this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle');
					return false;
				}
				$array_result = unpack('Vsize/Vhandle', $contents);
				$size = $array_result['size'];
				$recvhandle = $array_result['handle'];
				// -- amd64 support --
				$bits = sprintf('%b', $recvhandle);
				if (strlen($bits) == 64) {
					$recvhandle = bindec(substr($bits, 32));
				}
			}

			if ($recvhandle == 0 || $size == 0) {
				$this->error = new IXR_Error(-32300, 'transport error - connection interrupted!');
				return false;
			}
			if ($size > 4096*1024) {
				$this->error = new IXR_Error(-32300, "transport error - response too large ($size)");
				return false;
			}

			$contents = '';
			$contents_length = 0;
			@stream_set_timeout($this->socket, 0, 10000);  // timeout 10 ms (for successive reads until end)
			while ($contents_length < $size) {
				$contents .= fread($this->socket, $size-$contents_length);
				$contents_length = strlen($contents);
			}

			if (($recvhandle & 0x80000000) == 0) {
				// this is a callback, not our answer! handle= $recvhandle, xml-rpc= $contents
				// just add it to the message list for the user to read
				$new_cb_message = new IXR_Message($contents);
				if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') {
					array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params));
				}
			}
		} while ((int)$recvhandle != (int)$this->reqhandle);

		$this->message = new IXR_Message($contents);
		if (!$this->message->parse()) {
			// XML error
			$this->error = new IXR_Error(-32700, 'parse error. not well formed');
			return false;
		}
		// Is the message a fault?
		if ($this->message->messageType == 'fault') {
			$this->error = new IXR_Error($this->message->faultCode, $this->message->faultString);
			return false;
		}
		// Message must be OK
		return true;
	}


	function query() {
		$args = func_get_args();
		$method = array_shift($args);

		if (!$this->socket || $this->protocol == 0) {
			$this->error = new IXR_Error(-32300, 'transport error - client not initialized');
			return false;
		}

		$request = new IXR_Request($method, $args);

		// Check if request is larger than 512 Kbytes
		if (($size = $request->getLength()) > 1024*1024-8) {
			$this->error = new IXR_Error(-32300, "transport error - request too large ($size)");
			return false;
		}

		// Send request
		$ok = $this->sendRequest($request);
		if (!$ok) {
			$this->error = new IXR_Error(-32300, 'transport error - connection interrupted!');
			return false;
		}

		// Get result
		return $this->getResult();
	}

	// Non-blocking query method: doesn't read the response
	function queryIgnoreResult() {
		$args = func_get_args();
		$method = array_shift($args);

		if (!$this->socket || $this->protocol == 0) {
			$this->error = new IXR_Error(-32300, 'transport error - client not initialized');
			return false;
		}

		$request = new IXR_Request($method, $args);

		// Check if the request is greater than 512 Kbytes to avoid errors
		// If the method is system.multicall, make two calls (possibly recursively)
		if (($size = $request->getLength()) > 1024*1024-8) {
			if ($method = 'system.multicall' && isset($args[0])) {
				$count = count($args[0]);
				// If count is 1, query cannot be reduced
				if ($count < 2) {
					$this->error = new IXR_Error(-32300, "transport error - request too large ($size)");
					return false;
				}
				$length = floor($count/2);
				$args1 = array_slice($args[0], 0, $length);
				$args2 = array_slice($args[0], $length, ($count-$length));

				$res1 = $this->queryIgnoreResult('system.multicall', $args1);
				$res2 = $this->queryIgnoreResult('system.multicall', $args2);
				return ($res1 && $res2);
			}
			// If the method is not a multicall, just stop
			else {
				$this->error = new IXR_Error(-32300, "transport error - request too large ($size)");
				return false;
			}
		}

		// Send request
		$ok = $this->sendRequest($request);
		if (!$ok) {
			$this->error = new IXR_Error(-32300, 'transport error - connection interrupted!');
			return false;
		}
		return true;
	}

	function readCB($timeout = 2000) {  // timeout 2 ms
		if (!$this->socket || $this->protocol == 0) {
			$this->error = new IXR_Error(-32300, 'transport error - client not initialized');
			return false;
		}
		if ($this->protocol == 1)
			return false;

		$something_received = count($this->cb_message)>0;
		$contents = '';
		$contents_length = 0;

		@stream_set_timeout($this->socket, 0, 10000);  // timeout 10 ms (to read available data)
		// (assignment in arguments is forbidden since php 5.1.1)
		$read = array($this->socket);
		$write = NULL;
		$except = NULL;
		$nb = @stream_select($read, $write, $except, 0, $timeout);
		// workaround for stream_select bug with amd64
		if ($nb !== false)
			$nb = count($read);

		while ($nb !== false && $nb > 0) {
			$timeout = 0;  // we don't want to wait for the full time again, just flush the available data

			$size = 0;
			$recvhandle = 0;
			// Get result
			$contents = fread($this->socket, 8);
			if (strlen($contents) == 0) {
				$this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle');
				return false;
			}
			$array_result = unpack('Vsize/Vhandle', $contents);
			$size = $array_result['size'];
			$recvhandle = $array_result['handle'];

			if ($recvhandle == 0 || $size == 0) {
				$this->error = new IXR_Error(-32300, 'transport error - connection interrupted!');
				return false;
			}
			if ($size > 4096*1024) {
				$this->error = new IXR_Error(-32300, "transport error - response too large ($size)");
				return false;
			}

			$contents = '';
			$contents_length = 0;
			while ($contents_length < $size) {
				$contents .= fread($this->socket, $size-$contents_length);
				$contents_length = strlen($contents);
			}

			if (($recvhandle & 0x80000000) == 0) {
				// this is a callback. handle= $recvhandle, xml-rpc= $contents
				//echo 'CALLBACK('.$contents_length.')[ '.$contents.' ]' . LF;
				$new_cb_message = new IXR_Message($contents);
				if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') {
					array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params));
				}
				$something_received = true;
			}

			// (assignment in arguments is forbidden since php 5.1.1)
			$read = array($this->socket);
			$write = NULL;
			$except = NULL;
			$nb = @stream_select($read, $write, $except, 0, $timeout);
			// workaround for stream_select bug with amd64
			if ($nb !== false)
				$nb = count($read);
		}
		return $something_received;
	}

	function getResponse() {
		// methodResponses can only have one param - return that
		return $this->message->params[0];
	}

	function getCBResponses() {
		// (look at the end of basic.php for an example)
		$messages = $this->cb_message;
		$this->cb_message = array();
		return $messages;
	}

	function isError() {
		return is_object($this->error);
	}

	function resetError() {
		$this->error = false;
	}

	function getErrorCode() {
		if ($this->isError())
			return $this->error->code;
		else
			return 0;
	}

	function getErrorMessage() {
		if ($this->isError())
			return $this->error->message;
		else
			return '';
	}
}


class IXR_ClientMulticall_Gbx extends IXR_Client_Gbx {
	public $calls = array();

	function addCall($methodName, $args = array() ) {
		$this->calls[] = array('methodName' => $methodName, 'params' => $args);
		
		return (count($this->calls) - 1);
	}

	function multiquery($ignoreResult = false) {
		// Prepare multicall, then call the parent::query() (or queryIgnoreResult) method
		if ($ignoreResult) {
			$result = parent::queryIgnoreResult('system.multicall', $this->calls);
		} else {
			$result = parent::query('system.multicall', $this->calls);
		}
		return $result;
	}

	function getMultiqueryResponse() {
		$out = array();
		
		if (!empty($this->calls)) {
			$result = $this->getResponse();
			foreach ($this->calls as $i => $method) {
				if (isset($result[$i]['faultCode'])) {
					$out[$method['methodName']] = array();
				}
				else {
					if (count($result[$i]) == 1 && isset($result[$i][0])) {
						$out[$method['methodName']] = $result[$i][0];
					}
					else {
						$out[$method['methodName']] = $result[$i];
					}
				}
			}
		}
		
		$this->calls = array();
		return $out;
	}
}
?>
<?php
/**
* Class File
*
* Méthodes de traitement de fichier
*/
abstract class File {
	
	/**
	* Récupère l'extension d'un fichier
	*
	* @param  string $filename -> Le chemin ou nom du fichier
	* @return string "php"
	*/
	public static function getExtension($filename){
		$out = null;
		
		$pathinfo = pathinfo($filename);
		if( isset($pathinfo['extension']) ){
			$out = strtolower($pathinfo['extension']);
		}
		
		return $out;
	}
	
	
	/**
	* Récupère une double extension
	*
	* @param string $filename -> Le chemin ou nom du fichier
	* @return string "class.php"
	*/
	public static function getDoubleExtension($filename){
		$out = null;
		$filenameEx = explode('.', $filename);
		$countFilenameEx = count($filenameEx);
		
		if( $countFilenameEx > 2 ){
			$out = $filenameEx[$countFilenameEx - 2];
			$out .= '.'.$filenameEx[$countFilenameEx - 1];
		}
		
		return strtolower($out);
	}
	
	
	/**
	* Créer ou ajoute des données à un fichier
	*
	* @param  string $filename -> Le chemin ou nom du fichier
	* @param  string $data     -> Données à écrire
	* @return true si réussi, sinon erreur string
	*/
	public static function save($filename, $data = null, $appendData = true){
		$out = null;
		
		if( file_exists($filename) ){
			$append = ($appendData) ? FILE_APPEND : 0;
			
			if( file_put_contents($filename, $data, $append) ){
				$out = true;
			}
			else{
				$out = 'No such file or file is not writable';
			}
		}
		else{
			if( $handle = fopen($filename, 'w') ){
				$out = true;
				fclose($handle);
			}
			else{
				$out = 'No such file or file is not writable';
			}
		}
		
		return $out;
	}
	
	
	/**
	* Enregistre les données dans un fichier au pointeur
	*
	* @param  string $filename -> Le chemin ou nom du fichier
	* @param  string $data     -> Données à écrire
	* @param  string $seek     -> Le pointeur pour l'endroit à écrire
	*/
	public static function saveAtSeek($filename, $data, $seek = 0){
		$out = null;
		
		if( file_exists($filename) && is_writable($filename) ){
			$handle = fopen($filename, 'r+');
			fseek($handle, $seek, SEEK_CUR);
			if( fwrite($handle, $data) ){
				$out = true;
			}
			fclose($handle);
		}
		else{
			$out = 'No such file or file is not writable';
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le pointeur à partir d'une chaine de caractère dans un fichier
	*
	* @param string $filename -> Le chemin du fichier
	* @param string $string   -> La chaine à rechercher
	* @param bool   $lastChar -> Retourner le pointer à partir du dernier caractère de la chaine recherchée
	* @return int or text error
	*/
	public static function getSeekFromString($filename, $string, $lastChar = false){
		$out = null;
		
		if( file_exists($filename) && is_writable($filename) ){
			$handle = fopen($filename, 'r');
			$content = fread($handle, filesize($filename) );
			$out = strpos($content, $string);
			if($lastChar){
				$out += strlen($string);
			}
			fclose($handle);
		}
		else{
			$out = 'No such file or file is not writable';
		}
		
		return $out;
	}
	
	
	/**
	* Renomme un fichier
	*
	* @param string $filename    -> Chemin du fichier à renommer
	* @param string $newfilename -> Chemin du nouveau fichier renommé
	*/
	public static function rename($filename, $newfilename){
		$out = null;
		
		if( file_exists($filename) ){
			if( @rename($filename, $newfilename) ){
				$out = true;
			}
			else{
				$out = 'Unable to rename file';
			}
		}
		else{
			$out = 'No such file';
		}
		
		return $out;
	}
	
	
	/**
	* Supprime un fichier
	*
	* @param string $filename -> Chemin du fichier à supprimer
	*/
	public static function delete($filename){
		$out = null;
		
		if( file_exists($filename) ){
			if( @unlink($filename) ){
				$out = true;
			}
			else{
				$out = 'Unable to delete file';
			}
		}
		else{
			$out = 'No such file';
		}
		
		return $out;
	}
	
	
	/**
	* Envoi les headers pour télécharger un fichier
	*
	* @param string $pathToFile -> Le chemin du fichier à télécharger
	* @param int    $fileSize   -> Taille du fichier, si null = automatique
	*/
	public static function sendDownloadHeaders($pathToFile, $fileSize = null){
		$path_parts = pathinfo($pathToFile);
		$filename = htmlspecialchars( trim($path_parts['basename']), ENT_QUOTES, 'UTF-8');
		$path = $path_parts['dirname'].'/';
		
		header('Content-Disposition: attachment; filename="'.$filename);
		header('Content-Type: application/force-download');
		header('Content-Transfer-Encoding: binary');
		if($fileSize != null){
			header('Content-Length: '.$fileSize);
		}
		else{
			header('Content-Length: '.filesize($pathToFile));
		}
		header('Pragma: no-cache');
		if( preg_match('/MSIE/i', $_SERVER['HTTP_USER_AGENT']) ){
			header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
		}
		else{
			header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
		}
		header('Expires: 0');
	}
	
	
	/**
	* Permet de télécharger un fichier
	*
	* @param string $pathToFile -> Le chemin du fichier à télécharger
	* @param int    $fileSize   -> Taille du fichier, si null = automatique
	*/
	public static function download($pathToFile, $fileSize = null){
		self::sendDownloadHeaders($pathToFile, $fileSize);
		flush();
		readfile($pathToFile);
	}
}
?>
<?php
/**
* Class Folder
*
* Méthodes de traitement de dossier
*/
abstract class Folder {
	
	/**
	* Liste les dossiers et fichiers d'un répertoire
	*
	* @param  string $path                 -> Le chemin du répertoire à lister
	* @param  mixed  $hidden_folders       -> Les dossiers à masquer : array('dossier1', 'dossier2); ou 'all' pour ne pas charger les dossiers
	* @param  mixed  $hidden_files         -> Les fichiers ou extension à masquer : array('Thumbs.db', 'index.php', 'exe');  ou 'all' pour ne pas charger les fichiers
	* @param  int    $recent_status_period -> Période pour afficher le statut "récent"
	* @return array ['folders'], ['files']
	*/
	public static function read($path = '.', $hiddenFolders = array(), $hiddenFiles = array(), $recentStatusPeriod = 86400){
		$out = array();
		$midnight = time() - (date('H') * 3600) - (date('i') * 60);
		if( substr($path, -1, 1) != '/'){ $path .= '/'; }
		
		if( !class_exists('File') && !class_exists('Str') ){
			$out = 'Class "File" or "Str" not exists';
		}
		else{
			if( !is_dir($path) ){
				$out = 'Not directory';
			}
			else{
				$dir = scandir($path);
				foreach($dir as $entry){
					$entry = utf8_encode($entry);
					if($entry != '.' && $entry != '..'){
						$pathToEntry = $path.'/'.$entry;
						
						if($hiddenFolders !== 'all' && is_dir($pathToEntry) ){
							if( !in_array($entry, $hiddenFolders) ){
								$out['folders'][$entry]['size'] = Str::formatSize(self::getSize($pathToEntry));
								$out['folders'][$entry]['nb_file'] = self::countFiles($pathToEntry, $hiddenFiles);
							}
						}
						else if($hiddenFiles !== 'all' && !in_array($entry, $hiddenFiles) ){
							$extension = File::getExtension($entry);
							
							if( !in_array($extension, $hiddenFiles) ){
								$out['files'][$entry] = @array_slice(@stat($pathToEntry), 20, 3);
								$out['files'][$entry]['size'] = Str::formatSize($out['files'][$entry]['size']);
								$out['files'][$entry]['filename'] = $entry;
								$out['files'][$entry]['extension'] = $extension;
								$out['files'][$entry]['recent'] = (isset($out['files'][$entry]['mtime']) && ($out['files'][$entry]['mtime'] > ($midnight - $recentStatusPeriod))) ? 1 : 0;
							}
						}
					}
				}
				
				if( empty($out['folders']) ){
					$out['folders'] = null;
				}
				if( empty($out['files']) ){
					$out['files'] = null;
				}
			}
		}
		return $out;
	}
	
	
	/**
	* Créer un dossier
	*
	* @param string $dirname -> Chemin du dossier à créer
	* @return true si réussi sinon message d'erreur
	*/
	public static function create($dirname){
		$out = null;
		
		if( !file_exists($dirname) ){
			umask(0000);
			if( mkdir($dirname, 0777, true) ){
				$out = true;
			}
			else{
				$out = 'Create folder failed';
			}
		}
		else{
			$out = 'Folder already exists';
		}
		
		return $out;
	}
	
	
	/**
	* Renomme un dossier
	*
	* @param string $oldname -> Chemin de l'ancien dossier
	* @param string $newname -> Chemin du nouveau dossier
	* @return true si réussi sinon message d'erreur
	*/
	public static function rename($oldname, $newname){
		$out = null;
		
		if( file_exists($oldname) ){
			if( is_dir($oldname) ){
				if( rename($oldname, $newname) ){
					$out = true;
				}
				else{
					$out = 'Rename '.$oldname.' failed';
				}
			}
			else{
				$out = 'Not directory';
			}
		}
		else{
			$out = 'Folder no exists';
		}
		
		return $out;
	}
	
	
	/**
	* Supprime un dossier avec son contenu (dossiers + fichiers)
	*
	* @param string $dirname -> Chemin du dossier à supprimer
	* @return true si réussi sinon message d'erreur
	*/
	public static function delete($dirname){
		$out = null;
		if( substr($dirname, -1, 1) != '/'){ $dirname .= '/'; }
		
		if( class_exists('File') ){
			if( file_exists($dirname) ){
				$dir = scandir($dirname);
				foreach($dir as $file){
					if($file != '.' && $file != '..'){
						$pathToFile = $dirname.$file;
						
						if( is_dir($pathToFile) ){
							self::delete($pathToFile);
						}
						else{
							File::delete($pathToFile);
						}
					}
				}
				
				if( @rmdir($dirname) !== true ){
					$out = 'Unable to delete '.$dirname;
				}
				else{
					$out = true;
				}
			}
			else{
				$out = 'Dir not exists';
			}
		}
		else{
			$out = 'Class "File" not exists';
		}
		
		return $out;
	}
	
	
	/**
	* Compte le nombre de fichier présent dans un dossier
	*
	* @param string $path        -> Le chemin du dossier
	* @param array  $hiddenFiles -> Les fichiers ou extensions à ne pas prendre en compte
	* @return int
	*/
	public static function countFiles($path, $hiddenFiles = array() ){
		$out = 0;
		if( substr($path, -1, 1) != '/'){ $path .= '/'; }
		
		if( class_exists('File') ){
			if( file_exists($path) ){
				$dir = scandir($path);
				foreach($dir as $file){
					$pathToFile = $path.$file;
					
					if( is_dir($pathToFile) && $file != '.' && $file != '..' ){
						if( is_numeric( $result = self::countFiles($pathToFile, $hiddenFiles) ) ){
							$out += $result;
						}
						else{
							$out = $result;
							break;
						}
					}
					else{
						if($file != '.' && $file != '..'){
							if( !in_array($file, $hiddenFiles) ){
								if( !in_array(File::getExtension($file), $hiddenFiles) ){
									$out++;
								}
							}
						}
					}
				}
			}
			else{
				$out = 'Dir not exists';
			}
		}
		else{
			$out = 'Class "File" not exists';
		}
		
		return $out;
	}
	
	
	/**
	* Taille d'un dossier
	*
	* @param string $path -> Le chemin du dossier
	* @return int
	*/
	public static function getSize($path){
		$out = 0;
		if( substr($path, -1, 1) != '/'){ $path .= '/'; }
		
		if( file_exists($path) ){
			$dir = scandir($path);
			foreach($dir as $file){
				if( $file != '..' && $file != '.' ){
					$pathToFile = $path.'/'.$file;
					if( is_dir($pathToFile) ){
						$out += self::getSize($pathToFile);
					}
					else{
						$out += @filesize($pathToFile);
					}
				}
			}
		}
		else{
			$out = 'Dir not exists';
		}
		
		return $out;
	}
	
	
	/**
	* Retourne l'arborescence complete du chemin avec un décalage du dossier
	*
	* @param string $path          -> Le chemin du dossier
	* @param array  $hiddenFiles   -> Les fichiers ou extensions à ne pas prendre en compte
	* @param int    $hidePathLevel -> Nombre de niveau du chemin à masquer pour l'affichage
	* @return array
	*/
	public static function getArborescence($path = '.', $hiddenFolders = array(), $hidePathLevel = 0){
		$out = array();
		$struct = self::read($path, $hiddenFolders);
		
		// Décalage selon la profondeur de l'arborescence
		$countSlash = substr_count($path, '/') - $hidePathLevel;
		$pathLevel = null;
		for($i = 0; $i < $countSlash; $i++){
			$pathLevel .= '&#9474;&nbsp;';
		}
		$pathLevel .= '&#9500;&nbsp;';
		
		if( isset($struct['folders']) && count($struct['folders']) > 0 ){
			foreach($struct['folders'] as $dir => $values){
				$out[] = array(
					'path' => $path.$dir.'/',
					'name' => $dir,
					'level' => $pathLevel
				);
				$out = array_merge($out, self::getArborescence($path.$dir.'/', $hiddenFolders, $hidePathLevel) );
			}
		}
		
		return $out;
	}
	
	
	/**
	* Vérifie les droits par rapport au chmod
	*/
	public static function checkRights($path, $minChmod){
		$out = array();
		$chars = str_split($minChmod);
		
		$i = 0;
		foreach($chars as $char){
			if($i == 0){ $group = 'owner'; }
			else if($i == 1){ $group = 'group'; }
			else{ $group = 'other'; }
			$out[$group]['request'] = $char;
			
			switch($char){
				case 7:
					$out[$group]['result']['r'] = is_readable($path);
					$out[$group]['result']['w'] = is_writable($path);
					$out[$group]['result']['x'] = is_executable($path);
					break;
				case 6:
					$out[$group]['result']['r'] = is_readable($path);
					$out[$group]['result']['w'] = is_writable($path);
					break;
				case 5:
					$out[$group]['result']['r'] = is_readable($path);
					$out[$group]['result']['x'] = is_executable($path);
					break;
				case 4:
					$out[$group]['result']['r'] = is_readable($path);
					break;
				case 3:
					$out[$group]['result']['w'] = is_writable($path);
					$out[$group]['result']['x'] = is_executable($path);
					break;
				case 2:
					$out[$group]['result']['w'] = is_writable($path);
					break;
				case 1:
					$out[$group]['result']['x'] = is_executable($path);
					break;
				default:
					$out[$group]['result']['r'] = false;
					$out[$group]['result']['w'] = false;
					$out[$group]['result']['x'] = false;
			}
			$i++;
		}
		
		return $out;
	}
	
	
	/**
	* Converti un chmod int (777) en string (rwxrwxrwx)
	*/
	public static function chmodToStr($chmod){
		$out = null;
		$chars = str_split($chmod);
		
		foreach($chars as $char){
			switch($char){
				case 7:
					$out .= 'rwx';
					break;
				case 6:
					$out .= 'rw-';
					break;
				case 5:
					$out .= 'r-x';
					break;
				case 4:
					$out .= 'r--';
					break;
				case 3:
					$out .= '-wx';
					break;
				case 2:
					$out .= '-w-';
					break;
				case 1:
					$out .= '--x';
					break;
			}
		}
		
		return $out;
	}
}
?>
<?php
/* vim: set noexpandtab tabstop=2 softtabstop=2 shiftwidth=2: */

/**
 * GBXDataFetcher - Fetch GBX challenge/map/replay/pack data for TrackMania (TM)
 *                  & ManiaPlanet (MP) files
 * Created by Xymph <tm@gamers.org>
 * Thanks to Electron for additional input & prototyping
 * Based on information at http://en.tm-wiki.org/wiki/GBX,
 * http://www.tm-forum.com/viewtopic.php?p=192817#p192817
 * and http://en.tm-wiki.org/wiki/PAK#Header_versions_8.2B
 *
 * v2.3: Add UTF-8 decoding of parsed XML chunk's elements; strip UTF-8 BOM
 *       from various string fields
 * v2.2: Add class GBXPackFetcher; limit loadGBXdata() to first 256KB
 * v2.1: Add exception codes; add $thumbLen to GBXChallMapFetcher
 * v2.0: Complete rewrite
 */

/**
 * @class GBXBaseFetcher
 * @brief The base GBX class with all common functionality
 */
class GBXBaseFetcher
{
	public $parseXml, $xml, $xmlParsed;

	public $authorVer, $authorLogin, $authorNick, $authorZone, $authorEInfo;

	private $_gbxdata, $_gbxlen, $_gbxptr, $_debug, $_error, $_endianess,
	        $_lookbacks, $_parsestack;

	// supported class ID's
	const GBX_CHALLENGE_TMF = 0x03043000;
	const GBX_AUTOSAVE_TMF  = 0x03093000;
	const GBX_CHALLENGE_TM  = 0x24003000;
	const GBX_AUTOSAVE_TM   = 0x2403F000;
	const GBX_REPLAY_TM     = 0x2407E000;

	const MACHINE_ENDIAN_ORDER = 0;
	const LITTLE_ENDIAN_ORDER  = 1;
	const BIG_ENDIAN_ORDER     = 2;

	const LOAD_LIMIT = 256;  // KBs to read in loadGBXdata()

	// initialise new instance
	public function __construct()
	{
		$this->parseXml = false;
		$this->xml = '';
		$this->xmlParsed = array();
		$this->_debug = false;
		$this->_error = '';

		list($endiantest) = array_values(unpack('L1L', pack('V', 1)));
		if ($endiantest != 1)
			$this->_endianess = self::BIG_ENDIAN_ORDER;
		else
			$this->_endianess = self::LITTLE_ENDIAN_ORDER;

		$this->clearGBXdata();
		$this->clearLookbacks();
		$this->_parsestack = array();

		$this->authorVer   = 0;
		$this->authorLogin = '';
		$this->authorNick  = '';
		$this->authorZone  = '';
		$this->authorEInfo = '';
	}

	// enable debug logging
	protected function enableDebug()
	{
		$this->_debug = true;
	}

	// disable debug logging
	protected function disableDebug()
	{
		$this->_debug = false;
	}

	// print message to stderr if debugging
	protected function debugLog($msg)
	{
		if ($this->_debug)
			fwrite(STDERR, $msg."\n");
	}

	// set error message prefix
	protected function setError($prefix)
	{
		$this->_error = (string)$prefix;
	}

	// exit with error exception
	protected function errorOut($msg, $code = 0)
	{
		$this->clearGBXdata();
		throw new Exception($this->_error . $msg, $code);
	}

	// read in raw GBX data
	protected function loadGBXdata($filename)
	{
		$gbxdata = @file_get_contents($filename, false, null, 0, self::LOAD_LIMIT * 1024);
		if ($gbxdata !== false)
			$this->storeGBXdata($gbxdata);
		else
			$this->errorOut('Unable to read GBX data from ' . $filename, 1);
	}

	// store raw GBX data
	protected function storeGBXdata($gbxdata)
	{
		$this->_gbxdata = & $gbxdata;
		$this->_gbxlen = strlen($gbxdata);
		$this->_gbxptr = 0;
	}

	// clear GBX data (to avoid print_r problems & reduce memory usage)
	protected function clearGBXdata()
	{
		$this->storeGBXdata('');
	}

	// get GBX pointer
	protected function getGBXptr()
	{
		return $this->_gbxptr;
	}

	// set GBX pointer
	protected function setGBXptr($ptr)
	{
		$this->_gbxptr = (int)$ptr;
	}

	// move GBX pointer
	protected function moveGBXptr($len)
	{
		$this->_gbxptr += (int)$len;
	}

	// read $len bytes from GBX data
	protected function readData($len)
	{
		if ($this->_gbxptr + $len > $this->_gbxlen)
			$this->errorOut(sprintf('Insufficient data for %d bytes at pos 0x%04X',
			                        $len, $this->_gbxptr), 2);
		$data = '';
		while ($len-- > 0)
			$data .= $this->_gbxdata[$this->_gbxptr++];
		return $data;
	}

	// read signed byte from GBX data
	protected function readInt8()
	{
		$data = $this->readData(1);
		list(, $int8) = unpack('c*', $data);
		return $int8;
	}

	// read signed short from GBX data
	protected function readInt16()
	{
		$data = $this->readData(2);
		if ($this->_endianess == self::BIG_ENDIAN_ORDER)
			$data = strrev($data);
		list(, $int16) = unpack('s*', $data);
		return $int16;
	}

	// read signed long from GBX data
	protected function readInt32()
	{
		$data = $this->readData(4);
		if ($this->_endianess == self::BIG_ENDIAN_ORDER)
			$data = strrev($data);
		list(, $int32) = unpack('l*', $data);
		return $int32;
	}

	// read string from GBX data
	protected function readString()
	{
		$gbxptr = $this->getGBXptr();
		$len = $this->readInt32();
		$len &= 0x7FFFFFFF;
		if ($len <= 0 || $len >= 0x12000) {  // for large XML & Data blocks
			if ($len != 0)
				$this->errorOut(sprintf('Invalid string length %d (0x%04X) at pos 0x%04X',
				                        $len, $len, $gbxptr), 3);
		}
		$data = $this->readData($len);
		return $data;
	}

	// strip UTF-8 BOM from string
	protected function stripBOM($str)
	{
		return str_replace("\xEF\xBB\xBF", '', $str);
	}

	// clear lookback strings
	protected function clearLookbacks()
	{
		$this->_lookbacks = array();
	}

	// read lookback string from GBX data
	protected function readLookbackString()
	{
		if (empty($this->_lookbacks)) {
			$version = $this->readInt32();
			if ($version != 3)
				$this->errorOut('Unknown lookback strings version: ' . $version, 4);
		}

		// check index
		$index = $this->readInt32();
		if ($index == -1) {
			// unassigned (empty) string
			$str = '';
		} elseif (($index & 0xC0000000) == 0) {
			// use external reference string
			switch ($index) {
				case 0xC:
					$str = 'Canyon';
					break;
				case 0xCA:
					$str = 'Storm';
					break;
				default:
					$str = 'UNKNOWN';
			}
		} elseif (($index & 0x3FFFFFFF) == 0) {
			// read string & add to lookbacks
			$str = $this->readString();
			$this->_lookbacks[] = $str;
		} else {
			// use string from lookbacks
			$str = $this->_lookbacks[($index & 0x3FFFFFFF) - 1];
		}

		return $str;
	}

	// XML parser functions
	private function startTag($parser, $name, $attribs)
	{
		foreach ($attribs as $key => &$val)
			$val = utf8_decode($val);
		//echo 'startTag: ' . $name . "\n"; print_r($attribs);
		array_push($this->_parsestack, $name);
		if ($name == 'DEP') {
			$this->xmlParsed['DEPS'][] = $attribs;
		} elseif (count($this->_parsestack) <= 2) {
			// HEADER, IDENT, DESC, TIMES, CHALLENGE/MAP, DEPS, CHECKPOINTS
			$this->xmlParsed[$name] = $attribs;
		}
	}

	private function charData($parser, $data)
	{
		//echo 'charData: ' . $data . "\n";
		if (count($this->_parsestack) == 3)
			$this->xmlParsed[$this->_parsestack[1]][$this->_parsestack[2]] = $data;
		elseif (count($this->_parsestack) > 3)
			$this->debugLog('XML chunk nested too deeply: ', print_r($this->_parsestack, true));
	}

	private function endTag($parser, $name)
	{
		//echo 'endTag: ' . $name . "\n";
		array_pop($this->_parsestack);
	}

	protected function parseXMLstring()
	{
		// define a dedicated parser to handle the attributes
		$xml_parser = xml_parser_create();
		xml_set_object($xml_parser, $this);
		xml_set_element_handler($xml_parser, 'startTag', 'endTag');
		xml_set_character_data_handler($xml_parser, 'charData');

		// escape '&' characters unless already a known entity
		$xml = preg_replace('/&(?!(?:amp|quot|apos|lt|gt);)/', '&amp;', $this->xml);

		if (!xml_parse($xml_parser, utf8_encode($xml), true))
			$this->errorOut(sprintf('XML chunk parse error: %s at line %d',
			                        xml_error_string(xml_get_error_code($xml_parser)),
			                        xml_get_current_line_number($xml_parser)), 12);

		xml_parser_free($xml_parser);
	}

	/**
	 * Check GBX header, main class ID & header block
	 * @param Array $classes
	 *              The main class IDs accepted for this GBX
	 * @return Size of GBX header block
	*/
	protected function checkHeader(array $classes)
	{
		// check magic header
		$data = $this->readData(3);
		$version = $this->readInt16();
		if ($data != 'GBX' || $version != 6)
			$this->errorOut('No magic GBX header', 5);

		// check header block (un)compression
		$data = $this->readData(4);
		if ($data[1] != 'U')
			$this->errorOut('Compressed GBX header block not supported', 6);

		// check main class ID
		$mainClass = $this->readInt32();
		if (!in_array($mainClass, $classes))
			$this->errorOut(sprintf('Main class ID %08X not supported', $mainClass), 7);
		$this->debugLog(sprintf('GBX main class ID: %08X', $mainClass));

		// get header size
		$headerSize = $this->readInt32();
		if ($headerSize == 0)
			$this->errorOut('No GBX header block', 8);

		$this->debugLog(sprintf('GBX header block size: %d (%.1f KB)',
		                        $headerSize, $headerSize / 1024));
		return $headerSize;
	}  // checkHeader

	/**
	 * Get list of chunks from GBX header block
	 * @param Int $headerSize
	 *        Size of header block (chunks list & chunks data)
	 * @param array $chunks
	 *        List of chunk IDs & names
	 * @return List of chunk offsets & sizes
	 */
	protected function getChunksList($headerSize, array $chunks)
	{
		// get number of chunks
		$numChunks = $this->readInt32();
		if ($numChunks == 0)
			$this->errorOut('No GBX header chunks', 9);

		$this->debugLog('GBX number of header chunks: ' . $numChunks);
		$chunkStart = $this->getGBXptr();
		$this->debugLog(sprintf('GBX start of chunk list: 0x%04X', $chunkStart));
		$chunkOffset = $chunkStart + $numChunks * 8;

		// get list of all chunks
		$chunksList = array();
		for ($i = 0; $i < $numChunks; $i++)
		{
			$chunkId = $this->readInt32();
			$chunkSize = $this->readInt32();

			$chunkId &= 0x00000FFF;
			$chunkSize &= 0x7FFFFFFF;

			if (array_key_exists($chunkId, $chunks)) {
				$name = $chunks[$chunkId];
				$chunksList[$name] = array(
					'off' => $chunkOffset,
					'size' => $chunkSize
				);
			} else {
				$name = 'UNKNOWN';
			}
			$this->debugLog(sprintf('GBX chunk %2d  %-8s  Id  0x%03X  Offset  0x%06X  Size %6d',
			                        $i, $name, $chunkId, $chunkOffset, $chunkSize));
			$chunkOffset += $chunkSize;
		}

		//$this->debugLog(print_r($chunksList, true));
		$totalSize = $chunkOffset - $chunkStart + 4;  // numChunks
		if ($headerSize != $totalSize)
			$this->errorOut(sprintf('Chunk list size mismatch: %d <> %d',
			                        $headerSize, $totalSize), 10);

		return $chunksList;
	}  // getChunksList

	/**
	 * Initialize for a new chunk
	 * @param int $offset
	 */
	protected function initChunk($offset)
	{
		$this->setGBXptr($offset);
		$this->clearLookbacks();
	}

	/**
	 * Get XML chunk from GBX header block & optionally parse it
	 * @param array $chunksList
	 *        List of chunk offsets & sizes
	 */
	protected function getXMLChunk(array $chunksList)
	{
		if (!isset($chunksList['XML'])) return;

		$this->initChunk($chunksList['XML']['off']);
		$this->xml = $this->readString();

		if ($chunksList['XML']['size'] != strlen($this->xml) + 4)
			$this->errorOut(sprintf('XML chunk size mismatch: %d <> %d',
			                        $chunksList['XML']['size'], strlen($this->xml) + 4), 11);

		if ($this->parseXml && $this->xml != '')
			$this->parseXMLstring();
	}  // getXMLChunk

	/**
	 * Get Author fields from GBX header block
	 */
	protected function getAuthorFields()
	{
		$this->authorVer   = $this->readInt32();
		$this->authorLogin = $this->readString();
		$this->authorNick  = $this->stripBOM($this->readString());
		$this->authorZone  = $this->stripBOM($this->readString());
		$this->authorEInfo = $this->readString();
	}  // getAuthorFields

	/**
	 * Get Author chunk from GBX header block
	 * @param array $chunksList
	 *        List of chunk offsets & sizes
	 */
	protected function getAuthorChunk(array $chunksList)
	{
		if (!isset($chunksList['Author'])) return;

		$this->initChunk($chunksList['Author']['off']);
		$version = $this->readInt32();
		$this->debugLog('GBX Author chunk version: ' . $version);

		$this->getAuthorFields();
	}  // getAuthorChunk

}  // class GBXBaseFetcher


/**
 * @class GBXChallMapFetcher
 * @brief The class that fetches all GBX challenge/map info
 */
class GBXChallMapFetcher extends GBXBaseFetcher
{
	public $tnImage;

	public $headerVersn, $bronzeTime, $silverTime, $goldTime, $authorTime,
	       $cost, $multiLap, $type, $typeName, $authorScore, $simpleEdit,
	       $nbChecks, $nbLaps;
	public $uid, $envir, $author, $name, $kind, $kindName, $password,
	       $mood, $envirBg, $authorBg, $mapType, $mapStyle, $lightmap, $titleUid;
	public $xmlVer, $exeVer, $exeBld, $validated, $songFile, $songUrl,
	       $modName, $modFile, $modUrl;
	public $thumbLen, $thumbnail, $comment;

	const IMAGE_FLIP_HORIZONTAL = 1;
	const IMAGE_FLIP_VERTICAL   = 2;
	const IMAGE_FLIP_BOTH       = 3;

	/**
	 * Mirror (flip) an image across horizontal, vertical or both axis
	 * Source: http://www.php.net/manual/en/function.imagecopy.php#85992
	 * @param String $imgsrc
	 *        Source image data
	 * @param Int $dir
	 *        Flip direction from the constants above
	 * @return Flipped image data if successful, otherwise source image data
	 */
	private function imageFlip($imgsrc, $dir)
	{
		$width      = imagesx($imgsrc);
		$height     = imagesy($imgsrc);
		$src_x      = 0;
		$src_y      = 0;
		$src_width  = $width;
		$src_height = $height;

		switch ((int)$dir) {
			case self::IMAGE_FLIP_HORIZONTAL:
				$src_y      =  $height;
				$src_height = -$height;
				break;
			case self::IMAGE_FLIP_VERTICAL:
				$src_x      =  $width;
				$src_width  = -$width;
				break;
			case self::IMAGE_FLIP_BOTH:
				$src_x      =  $width;
				$src_y      =  $height;
				$src_width  = -$width;
				$src_height = -$height;
				break;
			default:
				return $imgsrc;
		}

		$imgdest = imagecreatetruecolor($width, $height);
		if (imagecopyresampled($imgdest, $imgsrc, 0, 0, $src_x, $src_y,
		                       $width, $height, $src_width, $src_height)) {
			return $imgdest;
		}
		return $imgsrc;
	}  // imageFlip

	/**
	 * Instantiate GBX challenge/map fetcher
	 *
	 * @param Boolean $parsexml
	 *        If true, the fetcher also parses the XML block
	 * @param Boolean $tnimage
	 *        If true, the fetcher also extracts the thumbnail image;
	 *        if GD/JPEG libraries are present, image will be flipped upright,
	 *        otherwise it will be in the original upside-down format
	 *        Warning: this is binary data in JPEG format, 256x256 pixels for
	 *        TMU/TMF or 512x512 pixels for MP
	 * @param Boolean $debug
	 *        If true, the fetcher prints debug logging to stderr
	 * @return GBXChallMapFetcher
	 *        If GBX data couldn't be extracted, an Exception is thrown with
	 *        the error message & code
	 */
	public function __construct($parsexml = false, $tnimage = false, $debug = false)
	{
		parent::__construct();

		$this->headerVersn = 0;
		$this->bronzeTime  = 0;
		$this->silverTime  = 0;
		$this->goldTime    = 0;
		$this->authorTime  = 0;

		$this->cost        = 0;
		$this->multiLap    = false;
		$this->type        = 0;
		$this->typeName    = '';

		$this->authorScore = 0;
		$this->simpleEdit  = false;
		$this->nbChecks    = 0;
		$this->nbLaps      = 0;

		$this->uid       = '';
		$this->envir     = '';
		$this->author    = '';
		$this->name      = '';
		$this->kind      = 0;
		$this->kindName  = '';

		$this->password  = '';
		$this->mood      = '';
		$this->envirBg   = '';
		$this->authorBg  = '';

		$this->mapType   = '';
		$this->mapStyle  = '';
		$this->lightmap  = 0;
		$this->titleUid  = '';

		$this->xmlVer    = '';
		$this->exeVer    = '';
		$this->exeBld    = '';
		$this->validated = false;
		$this->songFile  = '';
		$this->songUrl   = '';
		$this->modName   = '';
		$this->modFile   = '';
		$this->modUrl    = '';

		$this->thumbLen  = 0;
		$this->thumbnail = '';
		$this->comment   = '';

		$this->parseXml = (bool)$parsexml;
		$this->tnImage  = (bool)$tnimage;
		if ((bool)$debug)
			$this->enableDebug();

		$this->setError('GBX map error: ');
	}  // __construct

	/**
	 * Process GBX challenge/map file
	 *
	 * @param String $filename
	 *        The challenge filename
	 */
	public function processFile($filename)
	{
		$this->loadGBXdata((string)$filename);

		$this->processGBX();
	}  // processFile

	/**
	 * Process GBX challenge/map data
	 *
	 * @param String $gbxdata
	 *        The challenge/map data
	 */
	public function processData($gbxdata)
	{
		$this->storeGBXdata((string)$gbxdata);

		$this->processGBX();
	}  // processData

	// process GBX data
	private function processGBX()
	{
		// supported challenge/map class IDs
		$challclasses = array(
			self::GBX_CHALLENGE_TMF,
			self::GBX_CHALLENGE_TM,
		);

		$headerSize = $this->checkHeader($challclasses);
		$headerStart = $headerEnd = $this->getGBXptr();

		// desired challenge/map chunk IDs
		$chunks = array(
			0x002 => 'Info',     // TM, MP
			0x003 => 'String',   // TM, MP
			0x004 => 'Version',  // TM, MP
			0x005 => 'XML',      // TM, MP
			0x007 => 'Thumbnl',  // TM, MP
			0x008 => 'Author',   // MP
		);

		$chunksList = $this->getChunksList($headerSize, $chunks);

		$this->getInfoChunk($chunksList);
		$headerEnd = max($headerEnd, $this->getGBXptr());

		$this->getStringChunk($chunksList);
		$headerEnd = max($headerEnd, $this->getGBXptr());

		$this->getVersionChunk($chunksList);
		$headerEnd = max($headerEnd, $this->getGBXptr());

		$this->getXMLChunk($chunksList);
		$headerEnd = max($headerEnd, $this->getGBXptr());

		$this->getThumbnlChunk($chunksList);
		$headerEnd = max($headerEnd, $this->getGBXptr());

		$this->getAuthorChunk($chunksList);
		$headerEnd = max($headerEnd, $this->getGBXptr());

		if ($headerSize != $headerEnd - $headerStart)
			$this->errorOut(sprintf('Header size mismatch: %d <> %d',
			                        $headerSize, $headerEnd - $headerStart), 16);

		if ($this->parseXml) {
			if (isset($this->xmlParsed['HEADER']['VERSION']))
				$this->xmlVer = $this->xmlParsed['HEADER']['VERSION'];
			if (isset($this->xmlParsed['HEADER']['EXEVER']))
				$this->exeVer = $this->xmlParsed['HEADER']['EXEVER'];
			if (isset($this->xmlParsed['HEADER']['EXEBUILD']))
				$this->exeBld = $this->xmlParsed['HEADER']['EXEBUILD'];
			if ($this->lightmap == 0 && isset($this->xmlParsed['HEADER']['LIGHTMAP']))
				$this->lightmap = (int)$this->xmlParsed['HEADER']['LIGHTMAP'];
			if ($this->authorZone == '' && isset($this->xmlParsed['IDENT']['AUTHORZONE']))
				$this->authorZone = $this->xmlParsed['IDENT']['AUTHORZONE'];
			if ($this->envir == 'UNKNOWN' && isset($this->xmlParsed['DESC']['ENVIR']))
				$this->envir = $this->xmlParsed['DESC']['ENVIR'];
			if ($this->nbLaps == 0 && isset($this->xmlParsed['DESC']['NBLAPS']))
				$this->nbLaps = (int)$this->xmlParsed['DESC']['NBLAPS'];
			if (isset($this->xmlParsed['DESC']['VALIDATED']))
				$this->validated = (bool)$this->xmlParsed['DESC']['VALIDATED'];
			if (isset($this->xmlParsed['DESC']['MOD']))
				$this->modName = $this->xmlParsed['DESC']['MOD'];

			// extract optional song & mod filenames
			if (!empty($this->xmlParsed['DEPS'])) {
				for ($i = 0; $i < count($this->xmlParsed['DEPS']); $i++) {
					if (preg_match('/ChallengeMusics\\\\(.+)/', $this->xmlParsed['DEPS'][$i]['FILE'], $path)) {
						$this->songFile = $path[1];
						if (isset($this->xmlParsed['DEPS'][$i]['URL']))
							$this->songUrl = $this->xmlParsed['DEPS'][$i]['URL'];
					} elseif (preg_match('/.+\\\\Mod\\\\.+/', $this->xmlParsed['DEPS'][$i]['FILE'], $path)) {
						$this->modFile = $path[0];
						if (isset($this->xmlParsed['DEPS'][$i]['URL']))
							$this->modUrl = $this->xmlParsed['DEPS'][$i]['URL'];
					}
				}
			}
		}

		$this->clearGBXdata();
	}  // processGBX

	/**
	 * Get Info chunk from GBX header block
	 * @param array $chunksList
	 *        List of chunk offsets & sizes
	 */
	protected function getInfoChunk(array $chunksList)
	{
		if (!isset($chunksList['Info'])) return;

		$this->initChunk($chunksList['Info']['off']);
		$version = $this->readInt8();
		$this->debugLog('GBX Info chunk version: ' . $version);

		if ($version >= 3) {
			$zero = $this->readInt32();

			$this->bronzeTime = $this->readInt32();

			$this->silverTime = $this->readInt32();

			$this->goldTime = $this->readInt32();

			$this->authorTime = $this->readInt32();

			if ($version >= 4) {
				$this->cost = $this->readInt32();

				if ($version >= 6) {
					$this->multiLap = (bool)$this->readInt32();

					$this->type = $this->readInt32();
					switch ($this->type) {
						case 0: $this->typeName = 'Race';
						        break;
						case 1: $this->typeName = 'Platform';
						        break;
						case 2: $this->typeName = 'Puzzle';
						        break;
						case 3: $this->typeName = 'Crazy';
						        break;
						case 4: $this->typeName = 'Shortcut';
						        break;
						case 5: $this->typeName = 'Stunts';
						        break;
						case 6: $this->typeName = 'Script';
						        break;
						default: $this->typeName = 'UNKNOWN';
					}

					if ($version >= 9) {
						$zero = $this->readInt32();

						if ($version >= 10) {
							$this->authorScore = $this->readInt32();

							if ($version >= 11) {
								$this->simpleEdit = (bool)$this->readInt32();

								if ($version >= 12) {
									$zero = $this->readInt32();

									if ($version >= 13) {
										$this->nbChecks = $this->readInt32();

										$this->nbLaps = $this->readInt32();
									}
								}
							}
						}
					}
				}
			}
		}
	}  // getInfoChunk

	/**
	 * Get String chunk from GBX header block
	 * @param array $chunksList
	 *        List of chunk offsets & sizes
	 */
	protected function getStringChunk(array $chunksList)
	{
		if (!isset($chunksList['String'])) return;

		$this->initChunk($chunksList['String']['off']);
		$version = $this->readInt8();
		$this->debugLog('GBX String chunk version: ' . $version);

		$this->uid = $this->readLookbackString();

		$this->envir  = $this->readLookbackString();
		$this->author = $this->readLookbackString();

		$this->name = $this->stripBOM($this->readString());

		$this->kind = $this->readInt8();
		switch ($this->kind) {
			case 0: $this->kindName = '(internal)EndMarker';
			        break;
			case 1: $this->kindName = '(old)Campaign';
			        break;
			case 2: $this->kindName = '(old)Puzzle';
			        break;
			case 3: $this->kindName = '(old)Retro';
			        break;
			case 4: $this->kindName = '(old)TimeAttack';
			        break;
			case 5: $this->kindName = '(old)Rounds';
			        break;
			case 6: $this->kindName = 'InProgress';
			        break;
			case 7: $this->kindName = 'Campaign';
			        break;
			case 8: $this->kindName = 'Multi';
			        break;
			case 9: $this->kindName = 'Solo';
			        break;
			case 10: $this->kindName = 'Site';
			         break;
			case 11: $this->kindName = 'SoloNadeo';
			         break;
			case 12: $this->kindName = 'MultiNadeo';
			         break;
			default: $this->kindName = 'UNKNOWN';
		}

		if ($version >= 1) {
			$this->moveGBXptr(4);  // skip unknown

			$this->password = $this->readString();

			if ($version >= 2) {
				$this->mood = $this->readLookbackString();

				$this->envirBg  = $this->readLookbackString();
				$this->authorBg = $this->readLookbackString();

				if ($version >= 3) {
					$this->moveGBXptr(8);  // skip mapOrigin

					if ($version >= 4) {
						$this->moveGBXptr(8);  // skip mapTarget

						if ($version >= 5) {
							$this->moveGBXptr(16);  // skip unknown

							if ($version >= 9) {
								$this->mapType  = $this->readString();
								$this->mapStyle = $this->readString();

								$this->moveGBXptr(8);  // skip lightmapCacheUID

								$this->lightmap = $this->readInt8();

								if ($version >= 11) {
									$this->titleUid = $this->readLookbackString();
								}
							}
						}
					}
				}
			}
		}
	}  // getStringChunk

	/**
	 * Get Version chunk from GBX header block
	 * @param array $chunksList
	 *        List of chunk offsets & sizes
	 */
	protected function getVersionChunk(array $chunksList)
	{
		if (!isset($chunksList['Version'])) return;

		$this->initChunk($chunksList['Version']['off']);
		$this->headerVersn = $this->readInt32();
	}  // getVersionChunk

	/**
	 * Get Thumbnail/Comments chunk from GBX header block
	 * @param array $chunksList
	 *        List of chunk offsets & sizes
	 */
	protected function getThumbnlChunk(array $chunksList)
	{
		if (!isset($chunksList['Thumbnl'])) return;

		$this->initChunk($chunksList['Thumbnl']['off']);
		$version = $this->readInt32();
		$this->debugLog('GBX Thumbnail chunk version: ' . $version);

		if ($version == 1) {
			$thumbSize = $this->readInt32();
			$this->debugLog(sprintf('GBX Thumbnail size: %d (%.1f KB)',
			                        $thumbSize, $thumbSize / 1024));

			$this->moveGBXptr(strlen('<Thumbnail.jpg>'));
			$this->thumbnail = $this->readData($thumbSize);
			$this->thumbLen = strlen($this->thumbnail);
			$this->moveGBXptr(strlen('</Thumbnail.jpg>'));

			$this->moveGBXptr(strlen('<Comments>'));
			$this->comment = $this->stripBOM($this->readString());
			$this->moveGBXptr(strlen('</Comments>'));

			// return extracted thumbnail image?
			if ($this->tnImage) {
				// check for GD/JPEG libraries
				if (function_exists('imagecreatefromjpeg') &&
				    function_exists('imagecopyresampled')) {
					// flip thumbnail via temporary file
					$tmp = tempnam(sys_get_temp_dir(), 'gbxflip');
					if (@file_put_contents($tmp, $this->thumbnail) !== false) {
						if ($tn = @imagecreatefromjpeg($tmp)) {
							$tn = $this->imageFlip($tn, self::IMAGE_FLIP_HORIZONTAL);
							if (@imagejpeg($tn, $tmp)) {
								if (($tn = @file_get_contents($tmp)) !== false) {
									$this->thumbnail = $tn;
								}
							}
						}
						unlink($tmp);
					}
				}
			} else {
				$this->thumbnail = '';
			}
		}
	}  // getThumbnlChunk

}  // class GBXChallMapFetcher


/**
 * @class GBXChallengeFetcher
 * @brief Wrapper class for backwards compatibility with the old GBXChallengeFetcher
 * @deprecated Do not use for new development, use GBXChallMapFetcher instead
 */
class GBXChallengeFetcher extends GBXChallMapFetcher
{
	public $authortm, $goldtm, $silvertm, $bronzetm, $ascore, $azone, $multi, $editor,
	       $pub, $nblaps, $parsedxml, $xmlver, $exever, $exebld, $songfile, $songurl,
         $modname, $modfile, $modurl;

	/**
	 * Fetches a hell of a lot of data about a GBX challenge
	 *
	 * @param String $filename
	 *        The challenge filename (must include full path)
	 * @param Boolean $parsexml
	 *        If true, the script also parses the XML block
	 * @param Boolean $tnimage
	 *        If true, the script also extracts the thumbnail image; if GD/JPEG
	 *        libraries are present, image will be flipped upright, otherwise
	 *        it will be in the original upside-down format
	 *        Warning: this is binary data in JPEG format, 256x256 pixels for
   *        TMU/TMF or 512x512 pixels for MP
	 * @return GBXChallengeFetcher
	 *        If $uid is empty, GBX data couldn't be extracted
	 */
	public function __construct($filename, $parsexml = false, $tnimage = false)
	{
		parent::__construct($parsexml, $tnimage, false);

		try
		{
			$this->processFile($filename);

			$this->authortm  = $this->authorTime;
			$this->goldtm    = $this->goldTime;
			$this->silvertm  = $this->silverTime;
			$this->bronzetm  = $this->bronzeTime;
			$this->ascore    = $this->authorScore;
			$this->azone     = $this->authorZone;
			$this->multi     = $this->multiLap;
			$this->editor    = $this->simpleEdit;
			$this->pub       = $this->authorBg;
			$this->nblaps    = $this->nbLaps;
			$this->parsedxml = $this->xmlParsed;
			$this->xmlver    = $this->xmlVer;
			$this->exever    = $this->exeVer;
			$this->exebld    = $this->exeBld;
			$this->songfile  = $this->songFile;
			$this->songurl   = $this->songUrl;
			$this->modname   = $this->modName;
			$this->modfile   = $this->modFile;
			$this->modurl    = $this->modUrl;
		}
		catch (Exception $e)
		{
			$this->uid = '';
		}
	}

}  // class GBXChallengeFetcher


/**
 * @class GBXReplayFetcher
 * @brief The class that fetches all GBX replay info
 * @note The interface for GBXReplayFetcher has changed compared to the old class,
 *       but there is no wrapper because no third-party XASECO[2] plugins used that
 */
class GBXReplayFetcher extends GBXBaseFetcher
{
	public $uid, $envir, $author, $replay, $nickname, $login, $titleUid;
	public $xmlVer, $exeVer, $exeBld, $respawns, $stuntScore, $validable,
	       $cpsCur, $cpsLap;

	/**
	 * Instantiate GBX replay fetcher
	 *
	 * @param Boolean $parsexml
	 *        If true, the fetcher also parses the XML block
	 * @param Boolean $debug
	 *        If true, the fetcher prints debug logging to stderr
	 * @return GBXReplayFetcher
	 *        If GBX data couldn't be extracted, an Exception is thrown with
	 *        the error message & code
	 */
	public function __construct($parsexml = false, $debug = false)
	{
		parent::__construct();

		$this->uid      = '';
		$this->envir    = '';
		$this->author   = '';
		$this->replay   = 0;
		$this->nickname = '';
		$this->login    = '';
		$this->titleUid = '';

		$this->xmlVer     = '';
		$this->exeVer     = '';
		$this->exeBld     = '';
		$this->respawns   = 0;
		$this->stuntScore = 0;
		$this->validable  = false;
		$this->cpsCur     = 0;
		$this->cpsLap     = 0;

		$this->parseXml = (bool)$parsexml;
		if ((bool)$debug)
			$this->enableDebug();

		$this->setError('GBX replay error: ');
	}  // __construct

	/**
	 * Process GBX replay file
	 *
	 * @param String $filename
	 *        The replay filename
	 */
	public function processFile($filename)
	{
		$this->loadGBXdata((string)$filename);

		$this->processGBX();
	}  // processFile

	/**
	 * Process GBX replay data
	 *
	 * @param String $gbxdata
	 *        The replay data
	 */
	public function processData($gbxdata)
	{
		$this->storeGBXdata((string)$gbxdata);

		$this->processGBX();
	}  // processData

	// process GBX data
	private function processGBX()
	{
		// supported replay class IDs
		$replayclasses = array(
			self::GBX_AUTOSAVE_TMF,
			self::GBX_AUTOSAVE_TM,
			self::GBX_REPLAY_TM,
		);

		$headerSize = $this->checkHeader($replayclasses);
		$headerStart = $headerEnd = $this->getGBXptr();

		// desired replay chunk IDs
		$chunks = array(
			0x000 => 'String',  // TM, MP
			0x001 => 'XML',     // TM, MP
			0x002 => 'Author',  // MP
		);

		$chunksList = $this->getChunksList($headerSize, $chunks);

		$this->getStringChunk($chunksList);
		$headerEnd = max($headerEnd, $this->getGBXptr());

		$this->getXMLChunk($chunksList);
		$headerEnd = max($headerEnd, $this->getGBXptr());

		$this->getAuthorChunk($chunksList);
		$headerEnd = max($headerEnd, $this->getGBXptr());

		if ($headerSize != $headerEnd - $headerStart)
			$this->errorOut(sprintf('Header size mismatch: %d <> %d',
			                        $headerSize, $headerEnd - $headerStart), 20);

		if ($this->parseXml) {
			if (isset($this->xmlParsed['HEADER']['VERSION']))
				$this->xmlVer = $this->xmlParsed['HEADER']['VERSION'];
			if (isset($this->xmlParsed['HEADER']['EXEVER']))
				$this->exeVer = $this->xmlParsed['HEADER']['EXEVER'];
			if (isset($this->xmlParsed['HEADER']['EXEBUILD']))
				$this->exeBld = $this->xmlParsed['HEADER']['EXEBUILD'];
			if (isset($this->xmlParsed['TIMES']['RESPAWNS']))
				$this->respawns = (int)$this->xmlParsed['TIMES']['RESPAWNS'];
			if (isset($this->xmlParsed['TIMES']['STUNTSCORE']))
				$this->stuntScore = (int)$this->xmlParsed['TIMES']['STUNTSCORE'];
			if (isset($this->xmlParsed['TIMES']['VALIDABLE']))
				$this->validable = (bool)$this->xmlParsed['TIMES']['VALIDABLE'];
			if (isset($this->xmlParsed['CHECKPOINTS']['CUR']))
				$this->cpsCur = (int)$this->xmlParsed['CHECKPOINTS']['CUR'];
			if (isset($this->xmlParsed['CHECKPOINTS']['ONELAP']))
				$this->cpsLap = (int)$this->xmlParsed['CHECKPOINTS']['ONELAP'];
		}

		$this->clearGBXdata();
	}  // processGBX

	/**
	 * Get String chunk from GBX header block
	 * @param array $chunksList
	 *        List of chunk offsets & sizes
	 */
	protected function getStringChunk(array $chunksList)
	{
		if (!isset($chunksList['String'])) return;

		$this->initChunk($chunksList['String']['off']);
		$version = $this->readInt32();
		$this->debugLog('GBX String chunk version: ' . $version);

		if ($version >= 2) {
			$this->uid = $this->readLookbackString();

			$this->envir  = $this->readLookbackString();
			$this->author = $this->readLookbackString();

			$this->replay = $this->readInt32();

			$this->nickname = $this->stripBOM($this->readString());

			if ($version >= 6) {
				$this->login = $this->readString();

				if ($version >= 8) {
					$this->moveGBXptr(1);  // skip unknown

					$this->titleUid = $this->readLookbackString();
				}
			}
		}
	}  // getStringChunk

}  // class GBXReplayFetcher


/**
 * @class GBXPackFetcher
 * @brief The class that fetches all GBX pack info
 */
class GBXPackFetcher extends GBXBaseFetcher
{
	public $headerVersn, $flags, $infoMlUrl, $creatDate, $comment, $titleId,
	       $usageSubdir, $buildInfo, $authorUrl, $exeVer, $exeBld, $xmlDate;

	/**
	 * Read Windows FileTime and convert to Unix timestamp
	 * Filetime = 64-bit value with the number of 100-nsec intervals since Jan 1, 1601 (UTC)
	 * Based on http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/
	 * @return Unix timestamp, or -1 on error
	 */
	private function readFiletime()
	{
		// Unix epoch (1970-01-01) - Windows epoch (1601-01-01) in 100ns units
		$EPOCHDIFF = '116444735995904000';
		$UINT32MAX = '4294967296';
		$USEC2SEC  = 1000000;

		$lo = $this->readInt32();
		$hi = $this->readInt32();

		// check for 64-bit platform
		if (PHP_INT_SIZE >= 8) {
			// use native math
			if ($lo < 0) $lo += (1 << 32);
			$date = ($hi << 32) + $lo;
			$this->debugLog(sprintf('PAK CreationDate source: %016x', $date));
			if ($date == 0) return -1;

			// convert to Unix timestamp in usec
			$stamp = ($date - (int)$EPOCHDIFF) / 10;
			$this->debugLog(sprintf('PAK CreationDate 64-bit: %u.%06u',
			                        $stamp / $USEC2SEC, $stamp % $USEC2SEC));
			return (int)($stamp / $USEC2SEC);

		// check for 32-bit platform
		} elseif (PHP_INT_SIZE >= 4) {
			$this->debugLog(sprintf('PAK CreationDate source: %08x%08x', $hi, $lo));
			if ($lo == 0 && $hi == 0) return -1;

			// workaround signed/unsigned braindamage on x32
			$lo = sprintf('%u', $lo);
			$hi = sprintf('%u', $hi);

			// try and use GMP
			if (function_exists('gmp_mul')) {
				$date = gmp_add(gmp_mul($hi, $UINT32MAX), $lo);
				// convert to Unix timestamp in usec
				$stamp = gmp_div(gmp_sub($date, $EPOCHDIFF), 10);
				$stamp = gmp_div_qr($stamp, $USEC2SEC);
				$this->debugLog(sprintf('PAK CreationDate GNU MP: %u.%06u',
				                        gmp_strval($stamp[0]), gmp_strval($stamp[1])));
				return (int)gmp_strval($stamp[0]);
			}

			// try and use BC Math
			if (function_exists('bcmul')) {
				$date = bcadd(bcmul($hi, $UINT32MAX), $lo);
				// convert to Unix timestamp in usec
				$stamp = bcdiv(bcsub($date, $EPOCHDIFF), 10, 0);
				$this->debugLog(sprintf('PAK CreationDate BCMath: %u.%06u',
				                        bcdiv($stamp, $USEC2SEC), bcmod($stamp, $USEC2SEC)));
				return (int)bcdiv($stamp, $USEC2SEC);
			}

			// compute everything manually
			$a = substr($hi, 0, -5);
			$b = substr($hi, -5);
			// hope that float precision is enough
			$ac = $a * 42949;
			$bd = $b * 67296;
			$adbc = $a * 67296 + $b * 42949;
			$r4 = substr($bd, -5) + substr($lo, -5);
			$r3 = substr($bd, 0, -5) + substr($adbc, -5) + substr($lo, 0, -5);
			$r2 = substr($adbc, 0, -5) + substr($ac, -5);
			$r1 = substr($ac, 0, -5);
			while ($r4 >= 100000) { $r4 -= 100000; $r3++; }
			while ($r3 >= 100000) { $r3 -= 100000; $r2++; }
			while ($r2 >= 100000) { $r2 -= 100000; $r1++; }
			$date = ltrim(sprintf('%d%05d%05d%05d', $r1, $r2, $r3, $r4), '0');

			// convert to Unix timestamp in usec
			$r3 = substr($date, -6)     - substr($EPOCHDIFF, -6);
			$r2 = substr($date, -12, 6) - substr($EPOCHDIFF, -12, 6);
			$r1 = substr($date, -18, 6) - substr($EPOCHDIFF, -18, 6);
			if ($r3 < 0) { $r3 += 1000000; $r2--; }
			if ($r2 < 0) { $r2 += 1000000; $r1--; }
			$stamp = substr(sprintf('%d%06d%06d', $r1, $r2, $r3), 0, -1);
			$this->debugLog(sprintf('PAK CreationDate manual: %s.%s',
			                        substr($stamp, 0, -6), substr($stamp, -6)));
			return (int)substr($stamp, 0, -6);
		} else {
			return -1;
		}
	}

	/**
	 * Instantiate GBX pack fetcher
	 *
	 * @param Boolean $parsexml
	 *        If true, the fetcher also parses the XML block
	 * @param Boolean $debug
	 *        If true, the fetcher prints debug logging to stderr
	 * @return GBXPackFetcher
	 *        If GBX data couldn't be extracted, an Exception is thrown with
	 *        the error message & code
	 */
	public function __construct($parsexml = false, $debug = false)
	{
		parent::__construct();

		$this->headerVersn = 0;
		$this->flags       = 0;
		$this->infoMlUrl   = '';
		$this->creatDate   = -1;
		$this->comment     = '';
		$this->titleId     = '';
		$this->usageSubdir = '';
		$this->buildInfo   = '';
		$this->authorUrl   = '';
		$this->exeVer      = '';
		$this->exeBld      = '';
		$this->xmlDate     = '';

		$this->parseXml = (bool)$parsexml;
		if ((bool)$debug)
			$this->enableDebug();

		$this->setError('GBX pack error: ');
	}  // __construct

	/**
	 * Process GBX pack file
	 *
	 * @param String $filename
	 *        The pack filename
	 */
	public function processFile($filename)
	{
		$this->loadGBXdata((string)$filename);

		$this->processGBX();
	}  // processFile

	/**
	 * Process GBX pack data
	 *
	 * @param String $gbxdata
	 *        The pack data
	 */
	public function processData($gbxdata)
	{
		$this->storeGBXdata((string)$gbxdata);

		$this->processGBX();
	}  // processData

	// process GBX data
	private function processGBX()
	{
		// check magic header
		$data = $this->readData(8);
		if ($data != 'NadeoPak')
			$this->errorOut('No magic NadeoPak header', 5);

		$this->headerVersn = $this->readInt32();
		if ($this->headerVersn < 8)
			$this->errorOut(sprintf('Pack version %d not supported', $this->headerVersn), 24);

		$this->moveGBXptr(32);  // skip ContentsChecksum

		$this->flags = $this->readInt32();

		$this->getAuthorFields();

		$this->infoMlUrl = $this->readString();

		$this->creatDate = $this->readFiletime();

		$this->comment = $this->stripBOM($this->readString());

		if ($this->headerVersn >= 12) {
			$this->xml = $this->readString();
			$this->titleId = $this->readString();
			if ($this->parseXml && $this->xml != '') {
				$this->parseXMLstring();

				if (isset($this->xmlParsed['HEADER']['EXEVER']))
					$this->exeVer = $this->xmlParsed['HEADER']['EXEVER'];
				if (isset($this->xmlParsed['HEADER']['EXEBUILD']))
					$this->exeBld = $this->xmlParsed['HEADER']['EXEBUILD'];
				if (isset($this->xmlParsed['IDENT']['CREATIONDATE']))
					$this->xmlDate = $this->xmlParsed['IDENT']['CREATIONDATE'];
			}
		}

		$this->usageSubdir = $this->readString();

		$this->buildInfo = $this->readString();

		$this->authorUrl = $this->readString();

		if ($this->headerVersn >= 10)
			$this->moveGBXptr(16);  // skip unused

		$this->clearGBXdata();
	}  // processGBX

}  // class GBXPackFetcher
?>
<?php
/**
* Class Str
*
* Méthodes de traitement de chaines de caractères
*/
abstract class Str {
	
	/**
	* Formatage de la taille
	* 
	* @param int $size -> Taille
	* @return string
	*/
	public static function formatSize($size){
		$u = array('octets', 'Ko', 'Mo', 'Go', 'To');
		$i = 0;
		$m = 0;
		
		while($size >= 1){
			$m = $size;
			$size /= 1024;
			$i++;
		}
		if(!$i){
			$i = 1;
		}
		$d = explode('.', $m);
		
		if($d[0] != $m){
			$m = number_format($m, 1, ',', ' ');
		}
		
		return $m.' '.$u[$i-1];
	}
	
	
	/**
	* Modifie les antislashes d'un lien local en slashes pour usage web
	*
	* @param string $path -> Le chemin à modifier
	* @return string
	*/
	public static function toSlash($path){
		$out = null;
		
		if( strstr($path, '\\') ){
			$newPath = explode('\\', $path);
			foreach($newPath as $part){
				$out .= $part.'/';
			}
			$out = substr($out, 0, -1);
		}
		else{
			$out = $path;
		}
		
		return $out;
	}
	
	
	/**
	* Remplace ou supprime les caractères spéciaux
	*
	* @param string $str -> La chaine de caractères
	*/
	public static function replaceSpecialChars($str, $replaceSpace = true){
		// Listes
		$toRemove = array(
			"'", '"', '&', '<', '>', '+', '=', '*', '/', '²', '~', '#', '{', '[', '(', '|', '`', '\\', '^', '@', ')', ']', '}', '¨', '$', '£', '¤',
			'!', '%', '§', ':', ';', ',', '?', '«', '»', '“', '”', '„', '…', '¡', '¿', '‘', '’', 'ˆ', '˜', '¸', '·', '•', '¯', '‾', '—', '¦', '†',
			'‡', '¶', '©', '®', '™', '◊', '♠', '♣', '♥', '♦', '←', '↑', '→', '↓', '↔', 'Γ', 'δ', 'Δ', 'ζ', 'θ', 'Θ', 'ι', 'Λ', 'ξ', 'Ξ', 'π', 'Π',
			'σ', 'ς', 'Σ', 'φ', 'Φ', 'ψ', 'Ψ', 'ω', 'Ω', '°', '≤', '≥', '≈', '≠', '≡', '±', '×', '÷', '⁄', '‰', '¼', '½', '¾', '¹', '³', 'º', 'ª',
			'′', '″', '∂', '∏', '∑', '√', '∞', '¬', '∩', '∫', '⇒', '⇔', '∀', '∃', '∇', '∈', '∋', '∝', '∠', '∧', '∨', '∴', '∼', '⊂', '⊃',
			'⊆', '⊇', '⊥'
		);
		if($replaceSpace){
			$toDash = array(
				' ', '  '
			);
		}
		
		// Remplacement
		$str = trim($str);
		$str = str_replace($toRemove, '', $str);
		if($replaceSpace){
			$str = str_replace($toDash, '-', $str);
		}
		else{
			$str = trim($str);
		}
		return $str;
	}
	
	
	/**
	* Remplace les caractères accentués par leurs caractères normal
	*
	* @param string $str -> La chaine de caractères
	*/
	public static function replaceAccentChars($str){
		$str = utf8_decode($str);
		$str = strtr($str, utf8_decode('ÀÁÂÃÄÅΑλàáâãäåαβþÐÒÓÔÕÖØòóôõöøÈÉÊËèéêë€εƒÇç¢ÌÍÎÏìíîïÙÚÛÜ∪ùúûüµυÿýýŸÝ¥ÑñηŔŕρτ'), 'AAAAAAAAaaaaaaaBbDOOOOOOooooooEEEEeeeeEefCccIIIIiiiiUUUUUuuuuuuyyyYYYNnnRrpt');
		return utf8_encode($str);
	}
	
	
	/**
	* Remplace ou supprime les caractères spéciaux et remplace les caractères accentués
	*
	* @param string $str -> La chaine de caractères
	*/
	public static function replaceChars($str){
		return self::replaceSpecialChars( self::replaceAccentChars($str) );
	}
	
	
	/**
	* Récupère le type d'une valeur
	*
	* @param  mixed $val -> La valeur à analyser
	* @return string
	*/
	public static function getValueType($val){
		$out = null;
		
		if( is_string($val) ){
			$out = 'string';
		}
		elseif( is_bool($val) ){
			$out = 'bool';
		}
		elseif( is_float($val) ){
			$out = 'float';
		}
		elseif( is_int($val) ){
			$out = 'int';
		}
		elseif( is_array($val) ){
			$out = 'array';
		}
		elseif( is_object($val) ){
			$out = 'object';
		}
		elseif( is_resource($val) ){
			$out = 'resource';
		}
		
		return $out;
	}
	
	
	/**
	* Converti le type d'une valeur
	*
	* @param mixed  $val  -> La valeur à convertir
	* @param string $type -> Le type à affecter
	*/
	public static function setValueType($val, $type){
		switch($type){
			case 'array':
				$val = (array)$val;
				break;
			case 'bool':
			case 'boolean':
				$val = (bool)$val;
				break;
			case 'float':
			case 'double':
				$val = (float)$val;
				break;
			case 'int':
			case 'integer':
				$val = (int)$val;
				break;
			default:
				$val = (string)$val;
		}
		
		return $val;
	}
}
?>
<?php
abstract class TimeDate {
	
	/**
	* Retourne la date suivant la langue
	*
	* @param string $format    -> Le format de la fonction strftime()
	* @param int    $timestamp -> Le temps en sec
	* @param string $lang      -> La langue de la date retournée
	* @return string
	*/
	public static function date($format, $timestamp = null, $lang = 'en'){
		if($timestamp === null){
			$timestamp = time();
		}
		setlocale(LC_ALL, $lang);
		return strftime($format, $timestamp);
	}
	
	
	/**
	* Rentourne la date au format INT
	*
	* @param string $date          -> La date sous la forme JJ/MM/AAAA, JJ.MM.AAAA, JJ-MM-AAAA ou JJ MM AAAA sinon mettre $use_strtotime sur true
	* @param bool   $use_strtotime -> Utiliser la méthode php strtotime pour une date d'un autre format
	* @return int
	*/
	public static function dateToTime($date, $use_strtotime = false){
		$out = 0;
		
		if($date){
			$date = trim($date);
			if( strstr($date, '/') && !$use_strtotime){
				$date_ex = explode('/', $date);
			}
			else if( strstr($date_ex, '.')  && !$use_strtotime){
				$date_ex = explode('.', $date_ex);
			}
			else if( strstr($date_ex, '-')  && !$use_strtotime){
				$date_ex = explode('-', $date_ex);
			}
			else if( strstr($date_ex, ' ')  && !$use_strtotime){
				$date_ex = explode(' ', $date_ex);
			}
			
			if( !$use_strtotime ){
				$out = mktime(0, 0, 0, $date_ex[1], $date_ex[0], $date_ex[2]); 
			}
			else{
				$out = strtotime($date);
			}
		}
		
		return $out;
	}
	
	
	/**
	* Retourne un temps au format INT
	*
	* @param string $time          -> Le temps sous la forme HH:MM:SS, HH:MM.SS, HH.MM.SS, HH-MM-SS ou HH MM SS sinon mettre $use_strtotime sur true
	* @param bool   $use_strtotime -> Utiliser la méthode php strtotime pour un temps d'un autre format
	* @return int
	*/
	public static function timeToSec($time, $use_strtotime){
		$out = 0;
		$h = 3600;
		$m = 60;
		$s = 1;
		
		if($time){
			$time = trim($time);
			if( strstr($time, ':') && !strstr($time, '.') && !$use_strtotime){
				$time_ex = explode(':', $time);
			}
			else if( strstr($time, ':') && strstr($time, '.') && !$use_strtotime){
				$time_ex = explode(':', $time);
				$time_ex2 = explode('.', $time);
				$out = ($time_ex[0] * $h) + ($time_ex[1] * $m) + ($time_ex2[1] * $s); 
			}
			else if( strstr($time, '.') && !strstr($time, ':') && !$use_strtotime){
				$time_ex = explode('.', $time);
			}
			else if( strstr($time, '-') && !$use_strtotime){
				$time_ex = explode('-', $time);
			}
			else if( strstr($time, ' ') && !$use_strtotime){
				$time_ex = explode(' ', $time);
			}
			
			
			if( !$use_strtotime && $out === 0){
				$out = ($time_ex[0] * $h) + ($time_ex[1] * $m) + ($time_ex[2] * $s); 
			}
			else{
				$out = strtotime($time);
			}
		}
		
		return $out;
	}
	
	
	/**
	* Formate une date pour une entrée MySQL
	*
	* @param string $type          -> Le type Mysql à retourner
	* @param string $date          -> La date sous la forme JJ/MM/AAAA, JJ.MM.AAAA, JJ-MM-AAAA ou JJ MM AAAA sinon mettre $use_strtotime sur true
	* @param string $time          -> Le temps sous la forme HH:MM:SS, HH:MM.SS, HH.MM.SS, HH-MM-SS ou HH MM SS
	* @param bool   $use_strtotime -> Utiliser la méthode php strtotime pour une date d'un autre format
	* @return string
	*/
	public static function formatDateForMySQL($type, $date, $time = '00:00:00', $use_strtotime = false){
		$out = '000-00-00 00:00:00';
		$type = strtoupper($type);
		$date = trim($date);
		
		switch($type){
			case 'DATE':
				$out = date('Y-m-d', self::dateToTime($date, $use_strtotime));
				break;
			case 'DATETIME':
				$datetotime = self::dateToTime($date, $use_strtotime);
				$timetosec = self::timeToSec($time, $use_strtotime);
				$out = date('Y-m-d H:i:s', $datetotime + $timetosec);
				break;
			case 'TIME':
				$out = date('H:i:s', self::timeToSec($time, $use_strtotime));
				break;
			case 'YEAR':
				$out = date('Y', self::dateToTime($date, $use_strtotime));
				break;
			default:
				$out = self::formatDateForMySQL('DATETIME', $date, $time, $use_strtotime);
		}
		return $out;
	}
	
	
	/**
	* Récupère l'âge à partir de l'année de naissance
	*
	* @param string $birthday -> Sous la forme jj/mm/aaaa ou autre
	*/
	public static function getYearOld($birthday){
		$out = null;
		$birthdayDate = getdate( self::dateToTime($birthday) );
		$currentDate = getdate();
		
		if( $birthdayDate['mon'] < $currentDate['mon'] || ($birthdayDate['mon'] == $currentDate['mon'] && $birthdayDate['mday'] <= $currentDate['mday']) ){
			$out = $currentDate['year'] - $birthdayDate['year'];
		}
		else{
			$out = $currentDate['year'] - $birthdayDate['year'] - 1;
		}
		
		return $out;
	}
	
	
	/**
	* Retourne une date relative sous la forme il y a x jours/heures/minutes/secondes
	*
	* @param int $time -> Temps en seconde
	* @return string
	*/
	public static function relativeTime($time){
		$out = null;
		$timeDifference = time() - $time;
		
		if($timeDifference > 0){
			$seconds = $timeDifference;
			$minutes = round($timeDifference/60);
			$hours = round($timeDifference/3600);
			$days = round($timeDifference/86400);
			$weeks = round($timeDifference/604800);
			$months = round($timeDifference/2419200);
			$years = round($timeDifference/29030400);
			
			if($seconds < 60){
				$out .= 'Il y a moins d\'une minute';
			}
			else if($minutes < 60){
				$out .= 'Il y a '.$minutes.' minute'; if($minutes > 1){ $out .= 's'; }
			}
			else if($hours < 24){
				$out .= 'Il y a '.$hours.' heure'; if($hours > 1){ $out .= 's'; }
			}
			else if($days < 7){
				$out .= 'Il y a '.$days.' jour'; if($days > 1){ $out .= 's'; }
			}
			else if($weeks < 4){
				$out .= 'Il y a '.$weeks.' semaine'; if($weeks > 1){ $out .= 's'; }
			}
			else if($months < 12){
				$out .= 'Il y a '.$months.' mois';
			}
			else{
				$out .= 'Il y a '.$years.' an'; if($years > 1){ $out .= 's'; }
			}
		}
		
		return $out;
	}
	
	
	/**
	* Transforme un temps en seconde sous forme 0 jour 0 heure 0 minute 0 seconde
	*
	* @param  int  $sec      -> Secondes à transformer
	* @param  bool $fullText -> Retourner le texte en entier
	* @return string
	*/
	public static function secToStringTime($sec, $fullText = true){
		$out = null;
		
		$year = 1*60*60*24*365;
		$day = 1*60*60*24;
		$hour = 1*60*60;
		$minute = 1*60;
		$second = 1;
		
		$timeDifference = intval($sec);
		$yearCount = floor($timeDifference / $year);
		$timeDifference -= $yearCount * $year;
		$dayCount = floor($timeDifference / $day);
		$timeDifference -= $dayCount * $day;
		$hourCount = floor($timeDifference / $hour);
		$timeDifference -= $hourCount * $hour;
		$minuteCount = floor($timeDifference / $minute);
		$timeDifference -= $minuteCount * $minute;
		$secondCount = floor($timeDifference / $second);
		$timeDifference -= $secondCount * $second;
		
		$strDay = $dayCount.'d'; if($fullText){ $strDay .= 'day'; if($dayCount > 1){ $strDay .= 's'; } }
		$strHour = $hourCount.'h'; if($fullText){ $strHour .= 'hour'; if($hourCount > 1){ $strHour .= 's'; } }
		$strMinute = $minuteCount.'min'; if($fullText){ $strMinute .= 'minute'; if($minuteCount > 1){ $strMinute .= 's'; } }
		$strSecond = $secondCount.'sec'; if($fullText){ $strSecond .= 'second'; if($secondCount > 1){ $strSecond .= 's'; } }
		
		if($dayCount != 0){
			$out .= $strDay.', '.$strHour.' '.$strMinute.' '.$strSecond;
		}
		else if($dayCount == 0 && $hourCount != 0){
			$out .= $strHour.' '.$strMinute.' '.$strSecond;
		}
		else if($dayCount == 0 && $hourCount == 0){
			$out .= $strMinute.' '.$strSecond;
		}
		
		return $out;
	}
	
	
	/**
	* Forme le temps millisecondes en 00:00:00
	*
	* @param  string $millisec -> Temps en millisecondes
	* @return string
	*/
	public static function format($millisec){
		$cen = intval( ($millisec % 1000) / 10 );
		if($cen < 10){
			$cen = '0'.$cen;
		}
		$sec = intval( ($millisec / 1000) % 60 );
		if($sec < 10){
			$sec = '0'.$sec;
		}
		$min = intval($millisec / 60000);
		if($min < 10){
			$min = '0'.$min;
		}
		
		return $min.':'.$sec.':'.$cen;
	}
	
	
	/**
	* Méthodes de convertion du temps (Min, sec, millisec)
	*/
	public static function secToMillisec($sec){
		$sec = intval( round($sec) );
		$millisec = $sec * 1000;
		if($millisec > 0){ return $millisec; }
		else{ return 0; }
	}
	public static function millisecToSec($millisec){
		$millisec = intval( round($millisec) );
		$sec = $millisec / 1000;
		if($sec > 0){ return $sec; }
		else{ return 0; }
	}
	public static function secToMin($sec){
		$sec = intval( round($sec) );
		$min = $sec / 60;
		if($min > 0){ return $min; }
		else{ return 0; }
	}
	public static function minToSec($min){
		$min = intval( round($min) );
		$sec = $min * 60;
		if($sec > 0){ return $sec; }
		else{ return 0; }
	}
	public static function millisecToMin($millisec){
		$millisec = intval( round($millisec) );
		$sec = $millisec / 1000;
		$min = $sec / 60;
		if($min > 0){ return $min; }
		else{ return 0; }
	}
}
?>
<?php
/**
* Cette classe gère les chaines TMF, c'est à dire que cette classe permet de convertir une chaine TM en:
*   - html (ombre et lien sont géré)
*   - texte brut -> sans la mise en forme
*   - image (tout format supporté, image d'arrière plan ou pas)
*
* @author Mr. Das - Gildas de Cadoudal - gdecad@gmail.com
* @package framework
*/
class TmNick {
	/**
	* Ces codes sont valables dans l'ensemble des jeux TrackMania :
	* 
	* $t Majuscule
	* $i Italique
	* $s Ombré
	* $w Espacements larges
	* $n Espacements courts
	* $m Espacements normaux
	* $g Couleur par défaut
	* $z Tout réinitialiser
	* $$ Ecrire un "$"
	* $o Gras avec espacements semi-larges
	* $h Lien interne vers un Manialink
	* $p Lien interne avec info joueur
	* $l Lien externe vers un site web
	*/
	public  static $m_fontPath = 'fonts/';
	public  static $linkProtocol = 'tmtp';
	private static $m_pattern = '/\\$\\$|\\$[0-9a-fA-F][0-9a-zA-Z]{2}|\\$[twmgonishplzTWMGONISHLZ]/';
	private static $m_patternLink = '/(?:\\[(?P<url>[^\\[\\]]*)\\]){0,1}(?P<label>.+){0,1}/';
	private static $m_lstTags = array('h','p','l','o','g','t','w','m','n','i','s','z','color');
	private static $m_css = array(
		'h' => 'tmnick_internallink',
		'p' => 'tmnick_internallink_withlogin',
		'l' => 'tmnick_externallink',
		'o' => 'tmnick_bold',
		'g' => 'tmnick_defaultcolor',
		't' => 'tmnick_upper',
		'w' => 'tmnick_wide',
		'm' => 'tmnick_normal',
		'n' => 'tmnick_short',
		'i' => 'tmnick_italic',
		's' => 'tmnick_shadowed',
		'z' => 'tmnick_raz'
	);
	private static $m_fonts = array(
		'h' => '',
		'l' => '',
		'o' => 'DM',
		'g' => '',
		't' => '',
		'w' => '',
		'm' => '',
		'n' => 'CN',
		'i' => 'IT',
		's' => '',
		'z' => 'MD'
	);
	private static $m_defaultHexaOnError = '0';
	private static $m_colorNameToHtml = array(
		'aliceblue' => '#f0f8ff', 'antiquewhite' => '#faebd7', 'aqua' => '#00ffff', 'aquamarine' => '#7fffd4', 'azure' => '#f0ffff', 'beige' => '#f5f5dc', 'bisque' => '#ffe4c4', 'black' => '#000000', 'blanchedalmond' => '#ffebcd', 'blue' => '#0000ff',
		'blueviolet' => '#8a2be2', 'brown' => '#a52a2a', 'burlywood' => '#deb887', 'cadetblue' => '#5f9ea0', 'chartreuse' => '#7fff00', 'chocolate' => '#d2691e', 'coral' => '#ff7f50', 'cornflowerblue' => '#6495ed', 'cornsilk' => '#fff8dc', 'crimson' => '#dc143c',
		'cyan' => '#00ffff', 'darkblue' => '#00008b', 'darkcyan' => '#008b8b', 'darkgoldenrod' => '#b8860b', 'darkgray' => '#a9a9a9', 'darkgrey' => '#a9a9a9', 'darkgreen' => '#006400', 'darkkhaki' => '#bdb76b', 'darkmagenta' => '#8b008b', 'darkolivegreen' => '#556b2f',
		'darkorange' => '#ff8c00', 'darkorchid' => '#9932cc', 'darkred' => '#8b0000', 'darksalmon' => '#e9967a', 'darkseagreen' => '#8fbc8f', 'darkslateblue' => '#483d8b', 'darkslategray' => '#2f4f4f', 'darkslategrey' => '#2f4f4f', 'darkturquoise' => '#00ced1', 'darkviolet' => '#9400d3',
		'deeppink' => '#ff1493', 'deepskyblue' => '#00bfff', 'dimgray' => '#696969', 'dimgrey' => '#696969', 'dodgerblue' => '#1e90ff', 'firebrick' => '#b22222', 'floralwhite' => '#fffaf0', 'forestgreen' => '#228b22', 'fuchsia' => '#ff00ff', 'gainsboro' => '#dcdcdc',
		'ghostwhite' => '#f8f8ff', 'gold' => '#ffd700', 'goldenrod' => '#daa520', 'gray' => '#808080', 'grey' => '#808080', 'green' => '#008000', 'greenyellow' => '#adff2f', 'honeydew' => '#f0fff0', 'hotpink' => '#ff69b4', 'indianred' => '#cd5c5c',
		'indigo' => '#4b0082', 'ivory' => '#fffff0', 'khaki' => '#f0e68c', 'lavender' => '#e6e6fa', 'lavenderblush' => '#fff0f5', 'lawngreen' => '#7cfc00', 'lemonchiffon' => '#fffacd', 'lightblue' => '#add8e6', 'lightcoral' => '#f08080', 'lightcyan' => '#e0ffff',
		'lightgoldenrodyellow' => '#fafad2', 'lightgray' => '#d3d3d3', 'lightgrey' => '#d3d3d3', 'lightgreen' => '#90ee90', 'lightpink' => '#ffb6c1', 'lightsalmon' => '#ffa07a', 'lightseagreen' => '#20b2aa', 'lightskyblue' => '#87cefa', 'lightslategray' => '#778899', 'lightslategrey' => '#778899',
		'lightsteelblue' => '#b0c4de', 'lightyellow' => '#ffffe0', 'lime' => '#00ff00', 'limegreen' => '#32cd32', 'linen' => '#faf0e6', 'magenta' => '#ff00ff', 'maroon' => '#800000', 'mediumaquamarine' => '#66cdaa', 'mediumblue' => '#0000cd', 'mediumorchid' => '#ba55d3',
		'mediumpurple' => '#9370d8', 'mediumseagreen' => '#3cb371', 'mediumslateblue' => '#7b68ee', 'mediumspringgreen' => '#00fa9a', 'mediumturquoise' => '#48d1cc', 'mediumvioletred' => '#c71585', 'midnightblue' => '#191970', 'mintcream' => '#f5fffa', 'mistyrose' => '#ffe4e1', 'moccasin' => '#ffe4b5',
		'navajowhite' => '#ffdead', 'navy' => '#000080', 'oldlace' => '#fdf5e6', 'olive' => '#808000', 'olivedrab' => '#6b8e23', 'orange' => '#ffa500', 'orangered' => '#ff4500', 'orchid' => '#da70d6', 'palegoldenrod' => '#eee8aa', 'palegreen' => '#98fb98',
		'paleturquoise' => '#afeeee', 'palevioletred' => '#d87093', 'papayawhip' => '#ffefd5', 'peachpuff' => '#ffdab9', 'peru' => '#cd853f', 'pink' => '#ffc0cb', 'plum' => '#dda0dd', 'powderblue' => '#b0e0e6', 'purple' => '#800080', 'red' => '#ff0000',
		'rosybrown' => '#bc8f8f', 'royalblue' => '#4169e1', 'saddlebrown' => '#8b4513', 'salmon' => '#fa8072', 'sandybrown' => '#f4a460', 'seagreen' => '#2e8b57', 'seashell' => '#fff5ee', 'sienna' => '#a0522d', 'silver' => '#c0c0c0', 'skyblue' => '#87ceeb',
		'slateblue' => '#6a5acd', 'slategray' => '#708090', 'slategrey' => '#708090', 'snow' => '#fffafa', 'springgreen' => '#00ff7f', 'steelblue' => '#4682b4', 'tan' => '#d2b48c', 'teal' => '#008080', 'thistle' => '#d8bfd8', 'tomato' => '#ff6347',
		'turquoise' => '#40e0d0', 'violet' => '#ee82ee', 'wheat' => '#f5deb3', 'white' => '#ffffff', 'whitesmoke' => '#f5f5f5', 'yellow' => '#ffff00', 'yellowgreen' => '#9acd32'
	);
	
	
	/**
	* Convertie une chaine TM en HTML
	*
	* @param string $nick                   -> La chaine TM pas de limite de longueur, et peut être multiligne
	* @param int    $fontSize               -> Taille de la police
	* @param bool   $forcedDefault          -> Force la couleur par défaut à être utilise à la place de la mise en forme
	* @param string $defaultColor           -> La couleur par défaut (la couleur peut être au format HTML, nommé, array RGB, ou TM)
	* @param string $defaultBackgroundColor -> La couleur de fond (transparent est possible) (la couleur peut être au format HTML, nommé, array RGB, ou TM)
	* @return string chaine HTML sans le CSS
	*/
	public static function toHtml($nick, $fontSize = 11, $forcedShadow = false, $forcedDefault = false, $defaultColor = 'white', $defaultBackgroundColor = 'transparent'){
		if($forcedShadow){ $nick = '$s'.str_replace(array('$s', '$S'), '', $nick); }
		$linkProtocol = strtolower(self::$linkProtocol);
		
		$defaultHTMLColor = $defaultColor;
		if( empty($defaultColor) ){
			$defaultHTMLColor = 'white';
		}
		else if($defaultColor[0] == '$'){
			$defaultHTMLColor = self::colorToHtml($defaultColor);
		}
		
		$defaultHTMLBackgroundColor = $defaultBackgroundColor;
		if( empty($defaultBackgroundColor) ){
			$defaultHTMLBackgroundColor = 'black';
		}
		else if($defaultBackgroundColor[0] == '$'){
			$defaultHTMLBackgroundColor = self::colorToHtml($defaultBackgroundColor);
		}
		
		$strHtml = '<span class="tmnick_global" style="background-color:'.$defaultHTMLBackgroundColor.'">';
		$lastLink = false;
		$lastLinkTag = false;
		$stack = self::_parse($nick, $defaultColor);
		foreach($stack as $k => $ss){
			$lstClass = $lstStyle = array();
			$prefix = $suffix = '';
			$preContent = $postContent = '';
			foreach($ss['tagsOpen'] as $tag => $open){
				if( (is_string($open) and !empty($open)) or (is_bool($open) and $open) ){
					if( ($tag == 'h' or $tag == 'p' or $tag == 'l') and $lastLink !== $open ){
						$scheme = parse_url($open, PHP_URL_SCHEME);
						if( is_null($scheme) ){
							if($tag == 'l'){
								$open = 'http://'.$open;
							}
							else if($tag == 'h'){
								$open = $linkProtocol.':///:'.$open;
							}
							else if($tag == 'p'){
								$open = $linkProtocol.':///:'.$open.'?playerlogin=&lang=&nickname=&path=';
							}
						}
						
						$prefix .= '<a href="'.$open.'" target="_blank" class="'.self::$m_css[$tag].'">';
						$lastLinkTag = $tag;
						$lastLink = $open;
					}
					else if($tag == 'color'){
						if($forcedDefault){
							$lstStyle[] = 'color:'.$defaultHTMLColor;
						}
						else{
							$lstStyle[] = 'color:'.$open;
						}
					}
					else{
						$lstClass[] = self::$m_css[$tag];
					}
				}
				else{
					if($tag == $lastLinkTag and $lastLink !== $open){
						$prefix .= '</a>';
						$lastLink = false;
					}
				}
			}
			
			$strHtml .= $prefix;
			if( !empty($ss['content']) ){
				$strHtml .= '<span class="{$class$}" style="font-size: '.$fontSize.'pt;{$style$}">';
				$strHtml .= $preContent.'{$content$}'.$postContent;
				$strHtml .= '</span>';
			}
			$strHtml .= $suffix;
			
			$strHtml = str_replace('{$content$}', $ss['content'], $strHtml);
			$strHtml = str_replace('{$class$}', implode(' ', $lstClass), $strHtml);
			$strHtml = str_replace('{$style$}', implode(';', $lstStyle), $strHtml);
		}
		
		$tags = array('h', 'p', 'l');
		foreach($tags as $k => $tag){
			if( isset($ss) and $ss['tagsOpen'][$tag] ){
				$strHtml .= '</a>';
			}
		}
		
		$strHtml .= '</span>';
		
		return $strHtml;
	}
	
	
	/**
	* Affiche une chaine TM en image
	*
	* @param string $nick                 -> La chaine TM pas de limite de longueur, et peut être multiligne
	* @param string $type                 -> Le type de l'image (gif, jpg, jpeg, png, ico, bmp, wbmp, xpm)
	* @param int    $fontSize             -> Taille de la police
	* @param bool   $forceDefault         -> Force la couleur par défaut à être utilise à la place de la mise en forme
	* @param string $defaultColor         -> La couleur par défaut (la couleur peut être au format HTML, nommé, array RGB, ou TM)
	* @param string $defaultImgBackground -> Le chemin vers l'image de fond si vous en voulez une
	* @param array  $arrRelativePosition  -> Tableau assoc avec les index 'x' et 'y', donnant la position du texte par rapport au bord gauche et/ou haut de l'image de fond, ces valeur peuvent être négative, dans ce cas la valeur represente la position depuis le bord droite et/ou bas
	* @return bool
	*/
	public static function toImg($nick, $type = 'png', $fontSize = 12, $forceDefault = false, $defaultColor = 'white', $defaultImgBackground = null, $arrRelativePosition = array() ){
		if(self::_isSupportedImageType($type) === false){
			$imErr = self::_getErrorRessource('Le type "'.$type.'" n\'est pas supporté.');
			return self::_getImageFromRessource($imErr, 'png');
		}
		
		$res = true;
		$nickText = self::toText($nick);
		
		$lines = str_replace('\r\n', '\n', $nick);
		$lines = str_replace('\r', '\n', $lines);
		$lines = explode('\n', $lines);
		
		// this gets the length of the longest string, in characters to determine
		// the width of the output image
		$xMax = -1;
		$len = 0;
		$count_lines =  count($lines);
		for($x = 0; $x < $count_lines; $x++){
			if(strlen($lines[$x]) > $len){
				$len = strlen(self::toText($lines[$x]));
				$xMax = $x;
			}
		}
		
		$defaultRGBColor = self::colorToRGB($defaultColor);
		
		$width = $height = 0;
		
		// initialization
		$fontFile = self::$m_fontPath.'FRADMIT.TTF';
		$box = self::_imagettfbboxextended($fontSize, 0, $fontFile, self::toText($lines[$xMax]));
		
		// next we turn the height and width into pixel values
		$width = $box['width'] * 2;
		$height = $box['height'] * 2;
		$baseline = $box['y'];
		
		// create image with dimensions to fit text, plus two extra rows and
		// two extra columns for border
		$hasBgImd = false;
		$im = null;
		if( !is_null($defaultImgBackground) and file_exists($defaultImgBackground) ){
			$infos = getimagesize($defaultImgBackground);
			$width = $infos[0];
			$height = $infos[0];
			
			$imgString = file_get_contents($defaultImgBackground);
			$im = imagecreatefromstring($imgString);
			$hasBgImd = true;
		}else{
			$im = imagecreate($width, $height);
		}
		
		if($im){
			// image creation success
			$backColor = imagecolorallocatealpha($im, 254, 254, 254, 127);
			$shadowColor = imagecolorallocatealpha($im, 105, 105, 105, 0);
			if(!$hasBgImd){
				imagefill($im, 0, 0, $backColor);
			}
			
			// this loop outputs the error message to the image
			// imagestring(image, font, x, y, msg, color);
			$x = $y = 0;
			
			if(is_array($arrRelativePosition) and count($arrRelativePosition) > 0){
				if( isset($arrRelativePosition['y']) ){
					if($arrRelativePosition['y'] < 0){
						$y = $width;
					}
					$y += $arrRelativePosition['y'];
				}
				if( isset($arrRelativePosition['x']) ){
					if($arrRelativePosition['x'] < 0){
						$x = $height;
					}
					$x += $arrRelativePosition['x'];
				}
			}
			
			$newX = 0;
			$newY = 0;
			for($i = 0; $i < count($lines); $i++){
				$stack = self::_parse($lines[$i]);
				$xl = $x;
				
				foreach($stack as $k => $ss){
					if($forceDefault){
						$color = $defaultRGBColor;
					}else{
						$color = self::colorToRGB($ss['tagsOpen']['color']);
					}
					$textColor = imagecolorallocatealpha($im, $color[0], $color[1], $color[2], 0);
					$fontText = self::$m_fontPath.'FRA';
					if($ss['tagsOpen']['o'] === true){
						$fontText .= self::$m_fonts['o'];
					}else{
						$fontText .= self::$m_fonts['z'];
					}
					foreach($ss['tagsOpen'] as $t => $o){
						if($o === true and $t != 'o' and $t != 'z'){
							$fontText .= self::$m_fonts[$t];
						}
					}
					$fontText .= '.TTF';
					
					$tbox = self::_imagettfbboxextended($fontSize, 0, $fontText, $ss['content']);
					
					if($ss['tagsOpen']['s'] === true){
						imagettftext($im, $fontSize, 0, $xl + $tbox['x'] + 1, $y + $baseline + ($i * ($tbox['height'] + 5)) + 1, $shadowColor, $fontText, $ss['content']);
					}
					imagettftext($im, $fontSize, 0, $xl + $tbox['x'], $y + $baseline + ($i * ($tbox['height'] + 5)), $textColor, $fontText, $ss['content']);
					
					$xl += $tbox['width'];
					
					if($newX < $xl){
						$newX = $xl;
					}
					if( $newY < ($y + $baseline + ($i * ($tbox['height'] + 5))) + (abs($baseline - $tbox['y'])) ){
						$newY = ($y + $baseline + ($i * ($tbox['height'] + 5))) + (abs($baseline - $tbox['y']));
					}
					if($ss['tagsOpen']['s'] === true){
						$newX++;
						$newY++;
					}
				}
			}
			
			// now, render your image using your favorite image* function
			// (imagejpeg, for instance)
			if(!$hasBgImd){
				$im2 = imagecreate($newX, $newY);
				imagecopyresized($im2, $im, 0, 0, 0, 0, $newX, $newY, $newX, $newY);
				
				$res = self::_getImageFromRessource($im2, $type);
				imagedestroy($im2);
			}else{
				$res = self::_getImageFromRessource($im, $type);
			}
			imagedestroy($im);
		}else{
			// image creation failed, so just dump the array along with extra error
			$error[] = 'Is GD Installed ?';
			die(var_dump($error));
		}
		
		return $res;
	}
	
	
	/**
	* Convertie une chaine TM en text brut
	*
	* @param string $nick -> La chaine TM pas de limite de longueur, et peut être multiligne
	* @return string
	*/
	public static function toText($nick){
		
		if( !is_string($nick) or empty($nick) ){
			return '';
		}
		
		$nb = preg_match_all(self::$m_pattern, $nick, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
		$matches = $matches[0];
		
		$strText = '';
		
		$lastPos = 0;
		foreach($matches as $num => $matche){
			list($code, $pos) = $matche;
			
			if($code != '$$'){
				$strText .= substr($nick, $lastPos, $pos - $lastPos);
				$lastPos = $pos + strlen($matche[0]);
			}
		}
		
		$strText .= substr($nick, $lastPos, strlen($nick) - $lastPos);
		$strText = preg_replace('/(\\[[^\\[\\]]*\\])/', '', $strText);
		
		return $strText;
	}
	
	
	/**
	* Convertie une couleur au format HTML, TM, array RGB, ou nommé en format HTML
	*
	* @param string $color
	* @return string
	*/
	public static function colorToHtml($color){
		$colorHtml = '#';
		
		if( is_string($color) and !empty($color) and strlen($color) == 4 and ($color[0] == '$' or $color[0] == '#') ){
			$color = preg_replace('/[g-z]/', self::$m_defaultHexaOnError, strtolower($color));
			$colorHtml .= $color[1];
			$colorHtml .= $color[1];
			$colorHtml .= $color[2];
			$colorHtml .= $color[2];
			$colorHtml .= $color[3];
			$colorHtml .= $color[3];
		}
		else if(is_array($color) and count($color) == 3){
			$colorHtml .= sprintf('#%02X%02X%02X', $color[1], $color[2], $color[3]);
		}
		else if(is_string($color) and !empty($color) and strlen($color) == 7 and $color[0] == '#'){
			$color = preg_replace('/[g-z]/', self::$m_defaultHexaOnError, strtolower($color));
			$colorHtml = $color;
		}
		else{
			$color = strtolower($color);
			$colorHtml = self::$m_colorNameToHtml[$color];
		}
		
		return $colorHtml;
	}
	
	
	/**
	* Convertie une couleur au format HTML, TM, array RGB, ou nommé en format RGB
	*
	* @param string $color
	* @return string
	*/
	public static function colorToRGB($color){
		$colorRGB = array(0, 0, 0);
		
		if( is_string($color) and !empty($color) and strlen($color) == 4 and ($color[0] == '$' or $color[0] == '#') ){
			$color = preg_replace('/[g-z]/', self::$m_defaultHexaOnError, strtolower($color));
			$hex = $color[1];
			$hex .= $color[1];
			$colorRGB[0] = hexdec($hex);
			$hex = $color[2];
			$hex .= $color[2];
			$colorRGB[1] = hexdec($hex);
			$hex = $color[3];
			$hex .= $color[3];
			$colorRGB[2] = hexdec($hex);
		}
		else if(is_array($color) and count($color) == 3){
			$colorRGB = $color;
		}
		else if(is_string($color) and !empty($color) and strlen($color) == 7 and $color[0] == '#'){
			$color = preg_replace('/[g-z]/', self::$m_defaultHexaOnError, strtolower($color));
			$hex = $color[1];
			$hex .= $color[2];
			$colorRGB[0] = hexdec($hex);
			$hex = $color[3];
			$hex .= $color[4];
			$colorRGB[1] = hexdec($hex);
			$hex = $color[5];
			$hex .= $color[6];
			$colorRGB[2] = hexdec($hex);
		}
		else{
			$color = strtolower($color);
			$colorRGB = self::colorToRGB(self::$m_colorNameToHtml[$color]);
		}
		
		return $colorRGB;
	}
	
	
	/**
	* Retourne le code css nécessaire à la mise en forme du code html
	*
	* @return string
	*/
	public static function getCss(){
		$css = '<style type="text/css">
			.tmnick_global {
				font-style: normal;
				font-weight: none;
				letter-spacing: 0;
			}
			.tmnick_normal { letter-spacing: 0; }
			.tmnick_short { letter-spacing: -1px; }
			.tmnick_wide { letter-spacing: 2px; }
			.tmnick_raz { font-style: normal; font-weight: none; letter-spacing: 0; }
			.tmnick_italic { font-style: italic; }
			.tmnick_bold { font-weight: bold; letter-spacing: 1px; }
			.tmnick_upper { text-transform: uppercase; }
			span.tmnick_shadow { text-shadow: 0 1px 1px #333; }
			.tmnick_shadowed { position: relative; }
			.tmnick_shadowed span { position: relative; }
			span.tmnick_shadow { position: absolute; }
			.tmnick_defaultcolor { }
			a.tmnick_internallink, a.tmnick_internallink:visited {
				color: inherit;
				text-decoration: none;
				border-bottom: thin solid Black;
			}
			a.tmnick_internallink:hover {
				color: inherit;
				text-decoration: none;
				border-bottom: thin solid Blue;
			}
			a.tmnick_internallink_withlogin, a.tmnick_internallink_withlogin:visited  {
				color: inherit;
				text-decoration: none;
				border-bottom: thin solid #F0E68C;
			}
			a.tmnick_internallink_withlogin:hover {
				color: inherit;
				text-decoration: none;
				border-bottom: thin solid Gold;
			}
			a.tmnick_externallink, a.tmnick_externallink:visited {
				color: inherit;
				text-decoration: none;
				border-bottom: thin solid Black;
			}
			a.tmnick_externallink:hover {
				color: inherit;
				text-decoration: none;
				border-bottom: thin solid Orange;
			}
		</style>';
		
		return $css;
	}
	
	
	/**
	* Enlève tous les codes de trackmania
	*
	* @param string $str   -> Texte à traiter
	* @param array $select -> Un ou plusieurs codes à enlever. Par exemple, si on veut enlever seulement le code "$s"
	* @return string texte sans codes $s, $o, etc ...
	*/
	public static function stripNadeoCode($str, $select = array() ){
		if( !empty($select) ){
			$stripNadeoCode = $select;
		}
		else{
			$stripNadeoCode = array('$w', '$W', '$n', '$N', '$o', '$O', '$i', '$I', '$t', '$T', '$s', '$S', '$g', '$G', '$z', '$Z', '$<');
		}
		
		return str_ireplace($stripNadeoCode, '', $str);
	}
	
	
	/**
	* Parse une chaine TM dans une structure de donnée interne utilisé par les méthode toHtml, toImg, et toText
	*
	* @param string $nick la chaine TM pas de limite de longueur, et peut être multiligne
	* @param string $defaultColor la couleur par défaut (la couleur peut être au format HTML, nommé, array RGB, ou TM)
	* @return array
	*/
	private static function _parse($nick, $defaultColor = 'white'){
		
		if( !is_string($nick) or empty($nick) ){
			return array();
		}
		
		$defaultHTMLColor = $defaultColor;
		if( empty($defaultColor) ){
			$defaultHTMLColor = 'white';
		}
		else if($defaultColor[0] == '$'){
			$defaultHTMLColor = self::colorToHtml($defaultColor);
		}
		
		$nb = preg_match_all(self::$m_pattern, $nick, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
		$matches = $matches[0];
		
		$strContent = '';
		$lastPos = 0;
		
		$tagsOpen = array(
			'h' => false,
			'p' => false,
			'l' => false,
			'o' => false,
			'g' => false,
			't' => false,
			'w' => false,
			'm' => false,
			'n' => false,
			'i' => false,
			's' => false,
			'color' => $defaultColor
		);
		
		$stack = array();
		foreach($matches as $num => $matche){
			list($code, $pos) = $matche;
			
			$tag = strtolower(substr($code, 1));
			$param = null;
			if(strlen($tag) == 3){
				// color
				$param = $tag;
				$tag = 'color';
			}
			
			if( !in_array($tag, self::$m_lstTags) ){
				continue;
			}
			
			$strContent = substr($nick, $lastPos, $pos - $lastPos);
			if( !empty($strContent) ){
				array_push($stack, array('content' => $strContent, 'tagsOpen' => $tagsOpen));
			}
			
			switch($tag){
				// raz (close)
				case 'z':
					$tagsOpen = array_merge($tagsOpen,
						array(
							'o' => false,
							'g' => false,
							't' => false,
							'w' => false,
							'm' => false,
							'n' => false,
							'i' => false,
							's' => false,
							'color' => $defaultColor
						)
					);
					break;
				
				// defaultcolor (close)
				case 'g':
					$tagsOpen['color'] = $defaultColor;
					break;
				
				// internal link (open)
				case 'h':
				// internal link with login (open)
				case 'p':
				// external link (open)
				case 'l':
					if(!$tagsOpen[$tag]){
						// open
						$tagsOpen[$tag] = true;
					}
					else{
						// close
						$strLink = '';
						$i = count($stack) - 1;
						while($i >= 0 and $stack[$i]['tagsOpen'][$tag]){
							$strLink = $stack[$i]['content'] . $strLink;
							$i--;
						}
						
						$url = null;
						$nb = preg_match(self::$m_patternLink, $strLink, $regs, PREG_OFFSET_CAPTURE);
						
						if( !empty($regs['label'][0]) ){
							if( empty($regs['url'][0]) ){
								$url = $regs['label'][0];
							}else{
								$url = $regs['url'][0];
							}
						}
						
						$nb = count($stack) - 1;
						$lastMax = strlen($strLink);
						for($j = $nb; $j >= ($i+1); $j--){
							if( !is_null($url) ){
								$subLabel = $stack[$j]['content'];
								$max = max($lastMax - strlen($subLabel), $regs['label'][1]);
								$subLabel = substr($strLink, $max, $lastMax - $max);
								$lastMax = $max;
								$stack[$j]['content'] = $subLabel;
								
								$stack[$j]['tagsOpen'][$tag] = $url;
							}else{
								// poubelle
								unset($stack[$j]);
							}
						}
						
						$tagsOpen[$tag] = false;
					}
					break;
					
				// shadow (open)
				case 's':
				// upper
				case 't':
				// bold
				case 'o':
				// italic
				case 'i':
					if(!$tagsOpen[$tag]){
						// open
						$tagsOpen[$tag] = true;
					}else{
						// close
						$tagsOpen[$tag] = false;
					}
					break;
				
				// wide (open)
				case 'w':
				// normal (open)
				case 'm':
				// short (open)
				case 'n':
					if(!$tagsOpen[$tag]){
						// open
						$tagsOpen['w'] = false;
						$tagsOpen['m'] = false;
						$tagsOpen['n'] = false;
						$tagsOpen[$tag] = true;
					}else{
						// close
						$tagsOpen[$tag] = false;
					}
					break;
				
				case 'color':
					// color (open)
					$tagsOpen[$tag] = self::colorToHtml($code);
					break;
				
				default:
					$stack[(count($stack) - 1)]['content'] .= $code;
					break;
			}
			
			foreach($stack as $s => $st){
				if( empty($st['content']) ){
					unset($stack[$s]);
				}
			}
			
			$lastPos = $pos + strlen($matche[0]);
		}
		
		$strContent = substr($nick, $lastPos);
		if( !empty($strContent) ){
			array_push($stack, array('content' => $strContent, 'tagsOpen' => $tagsOpen));
		}
		
		$tags = array('h', 'p', 'l');
		foreach($tags as $k => $tag){
			if($tagsOpen[$tag]){
				// close
				$strLink = '';
				$i = count($stack) - 1;
				while($i >= 0 and $stack[$i]['tagsOpen'][$tag]){
					$strLink = $stack[$i]['content'] . $strLink;
					$i--;
				}
				
				$url = null;
				$nb = preg_match(self::$m_patternLink, $strLink, $regs, PREG_OFFSET_CAPTURE);
				
				if(!empty($regs['label'][0]) ){
					if(empty($regs['url'][0]) ){
						$url = $regs['label'][0];
					}else{
						$url = $regs['url'][0];
					}
				}
				
				$nb = count($stack) - 1;
				$lastMax = strlen($strLink);
				for($j = $nb; $j >= ($i+1); $j--){
					if( !is_null($url) ){
						$subLabel = $stack[$j]['content'];
						$max = max($lastMax - strlen($subLabel), $regs['label'][1]);
						$subLabel = substr($strLink, $max, $lastMax - $max);
						$lastMax = $max;
						$stack[$j]['content'] = $subLabel;
						
						$stack[$j]['tagsOpen'][$tag] = $url;
					}else{
						// poubelle
						unset($stack[$j]);
					}
				}
				
				$tagsOpen[$tag] = false;
			}
		}
		
		return $stack;
	}
	
	
	/**
	* This function extends imagettfbbox and includes within the returned array
	* the actual text width and height as well as the x and y coordinates the
	* text should be drawn from to render correctly.  This currently only works
	* for an angle of zero and corrects the issue of hanging letters e.g. jpqg
	*
	* @param float $size
	* @param float $angle
	* @param string $fontfile
	* @param string $text
	* @return array
	*/
	private static function _imagettfbboxextended($size, $angle, $fontfile, $text){
		$bbox = imagettfbbox($size, $angle, $fontfile, $text);
	
		//calculate x baseline
		if($bbox[0] >= -1){
			$bbox['x'] = abs($bbox[0] + 1) * -1;
		}else{
			//$bbox['x'] = 0;
			$bbox['x'] = abs($bbox[0] + 2);
		}
	
		//calculate actual text width
		$bbox['width'] = abs($bbox[2] - $bbox[0]);
		if($bbox[0] < -1){
			$bbox['width'] = abs($bbox[2]) + abs($bbox[0]) - 1;
		}
		
		//caculate y baseline
		$bbox['y'] = abs($bbox[5] + 1);
		
		//calculate actaul text height
		$bbox['height'] = abs($bbox[7]) - abs($bbox[1]);
		if($bbox[3] > 0){
			$bbox['height'] = abs($bbox[7] - $bbox[1]) - 1;
		}
		
		return $bbox;
	}
	
	
	/**
	* Construit une ressource d'image d'erreur affcihant toute les erreur de $errors
	*
	* @param mixed $errors string of error or array of string of error
	* @return ressource
	*/
	private static function _getErrorRessource($errors){
		// $error is an array of error messages, each taking up one line
		if( is_string($errors) ){
			$errors = str_replace('\r\n', '\n', $errors);
			$errors = str_replace('\r', '\n', $errors);
			$errors = explode('\n', $errors);
		}
		
		$error = array();
		foreach($errors as $k => $err){
			$err = str_replace('\r\n', '\n', $err);
			$err = str_replace('\r', '\n', $err);
			$error = array_merge($error, explode('\n', $err));
		}
		
		// initialization
		$fontSize = 12;
		
		// this gets the length of the longest string, in characters to determine
		// the width of the output image
		$xMax = -1;
		$len = 0;
		for($x = 0; $x < count($error); $x++){
			if(strlen($error[$x]) > $len){
				$len = strlen($error[$x]);
				$xMax = $x;
			}
		}
		
		$fontFile = self::$m_fontPath.'FRAMD.TTF';
		$box = imagettfbbox($fontSize, 0, $fontFile, $error[$xMax]);
		
		// next we turn the height and width into pixel values
		$width = abs($box[2] - $box[0]);
		$textHeight = abs($box[1] - $box[7]);
		$height = ($textHeight + 2) * count($error);
		
		$im = imagecreate($width, $height);
		
		if($im){
			// image creation success
			$textColor = imagecolorallocatealpha($im, 255, 0, 0, 0);
			$backColor = imagecolorallocatealpha($im, 255, 255, 255, 127);
			imagefill($im, 0, 0, $backColor);
			// this loop outputs the error message to the image
			for($y = 0; $y < count($error); $y++){
				// imagestring(image, font, x, y, msg, color);
				imagettftext($im, $fontSize, 0, 0, ($textHeight + 5) * $y + $textHeight, $textColor, $fontFile, $error[$y]);
			}
			// now, render your image using your favorite image* function
			// (imagejpeg, for instance)
			return $im;
		}else{
			// image creation failed, so just dump the array along with extra error
			$error[] = "Is GD Installed?";
			die(var_dump($error));
		}
	}
	
	
	/**
	* Détermine si le type passé est supporté
	*
	* @param string $type type supporté (gif, jpg, jpeg, png, ico, bmp, wbmp, xpm)
	* @return bool
	*/
	private static function _isSupportedImageType($type){
		$type = strtoupper($type);
		switch($type){
			case 'GIF':
				return IMG_GIF;
				break;
			case 'JPG':
				return IMG_JPG;
				break;
			case 'JPEG':
				return IMG_JPEG;
				break;
			case 'PNG':
				return IMG_PNG;
				break;
			case 'ICO':
			case 'BMP':
			case 'WBMP':
				return IMG_WBMP;
				break;
			case 'XPM':
				return IMG_XPM;
				break;
			default:
				return false;
				break;
		}
	}
	
	
	/**
	* Affiche l'image correspondant à la ressource dans le format souhaité
	*
	* @param ressource $im ressource de l'image
	* @param string $type type de l'image de sortie
	* @return bool
	*/
	private static function _getImageFromRessource($im, $type){
		if( ($imgtype = self::_isSupportedImageType($type)) !== false ){
			header('Content-type:'.image_type_to_mime_type($imgtype).';');
			switch($imgtype){
				case IMG_GIF:
					return imagegif($im);
					break;
				case IMG_JPG:
				case IMG_JPEG:
					return imagejpeg($im);
					break;
				case IMG_PNG:
					return imagepng($im);
					break;
				case IMG_WBMP:
					return imagewbmp($im);
					break;
				case IMG_XPM:
					return imagexbm($im);
					break;
			}
		}
		header('Content-type:'.image_type_to_mime_type(IMG_PNG).';');
		return imagepng(self::_getErrorRessource('Le format "'.$type.'" n\'est pas supporté.'));
	}
}
?>
<?php
/**
* CLASS UPLOAD
*
* Traite l'envoi de fichier en local ou FTP
*
* @example:
*         $path = '/';
*         $replaceOldFile = false;
*         $allowedExtensions = array('jpg', 'png', 'gif');
*         $sizeLimit = 4 * 1024 * 1024;
*     LOCAL:
*         echo FileUploader::saveUploadedFile($path, $replaceOldFile, $allowedExtensions, $sizeLimit);
*     FTP:
*         echo FileUploader::saveUploadedFileToFTP($ftp_stream, $path, $replaceOldFile, $allowedExtensions, $sizeLimit);
*/


/**
* Permet de traiter le fichier envoyé par XHR (XMLHttpRequest)
*/
class UploadedFileXhr {
	
	/**
	* Enregistre le fichier en local
	*
	* @param string $path -> Le chemin complet du fichier avec le filename
	* @return bool true si réussi
	*/
	public function save($path){
		$out = null;
		
		// Ouverture du flux "input" de PHP et création d'un fichier temp
		$input = fopen("php://input", "r");
		$temp = tmpfile();
		$realSize = stream_copy_to_stream($input, $temp);
		fclose($input);
		if( $realSize != $this->getSize() ){
			$out = false;
		}
		
		// Création du fichier final
		$target = fopen($path, "w");
		fseek($temp, 0, SEEK_SET);
		if( stream_copy_to_stream($temp, $target) > 0 ){
			$out = true;
		}
		fclose($target);
		
		return $out;
	}
	
	
	/**
	* Enregistre le fichier sur un serveur FTP
	*
	* @param resource $ftp_stream -> La ressource de connexion FTP
	* @param string   $path       -> Le chemin complet du dossier de destination
	* @param string   $filename   -> Le nom du fichier
	* @return true si réussi, sinon false
	*/
	public function saveFTP($ftp_stream, $path, $filename){
		$out = null;
		
		// Ouverture du flux "input" de PHP et création d'un fichier temp
		$input = fopen("php://input", "r");
		$temp = tmpfile();
		$realSize = stream_copy_to_stream($input, $temp);
		fclose($input);
		if( $realSize != $this->getSize() ){
			$out = false;
		}
		
		// Enregistre le fichier sur le FTP
		fseek($temp, 0, SEEK_SET);
		$out = ftp_fput($ftp_stream, $path.$filename, $temp, FTP_BINARY);
		
		return $out;
	}
	
	
	/**
	* Écrit la map dans le dossier "Maps" via le serveur
	*
	* @param resource $client   -> La ressource du client GbxRemote
	* @param string   $filename -> Le chemin vers le fichier à partir du dossier "Maps"
	*/
	public function writeMap($client, $filename){
		$out = true;
		
		// Ouverture du flux "input" de PHP et création d'un fichier temp
		$input = fopen("php://input", "r");
		$temp = tmpfile();
		$realSize = stream_copy_to_stream($input, $temp);
		fclose($input);
		if( $realSize != $this->getSize() ){
			$out = false;
		}
		if($out != false){
			fseek($temp, 0, SEEK_SET);
			$file = stream_get_contents($temp);
			$str64 = new IXR_Base64($file);
			
			if( !$client->query('WriteFile', $filename, $str64) ){
				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
			}
		}
		
		return $out;
	}
	
	
	/**
	* Ajoute ou insert une map à la liste du serveur
	*
	* @param resource $client   -> La ressource du client GbxRemote
	* @param string   $filename -> Le chemin vers le fichier
	* @param array    $queries  -> Requêtes à executer et le type d'ajout à la liste: array('insert' => 'InsertMap', 'add' => 'AddMap', 'type' => 'add')
	* @return true si réussi, sinon erreur texte
	*/
	public function saveMap($client, $filename, $queries){
		$out = true;
		
		if($queries['type'] == 'insert'){
			if( !$client->query($queries['insert'], $filename) ){
				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
			}
		}
		else{
			if( !$client->query($queries['add'], $filename) ){
				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le nom du fichier
	*/
	public function getName(){
		return $_GET['qqfile'];
	}
	
	
	/**
	* Récupère la taille du fichier
	*/
	public function getSize(){
		if( isset($_SERVER['CONTENT_LENGTH']) ){
			return (int)$_SERVER['CONTENT_LENGTH'];            
		}
		else{
			throw new Exception('Getting content length is not supported.');
		}
	}
}


/**
* Permet de traiter le fichier envoyé par Formulaire HTML (array $_FILES)
*/
class UploadedFileForm {
	
	/**
	* Enregistre le fichier en local
	*
	* @param string $path -> Le chemin complet du fichier avec le filename
	* @return bool true si réussi, sinon false
	*/
	public function save($path){
		if( !move_uploaded_file($_FILES['qqfile']['tmp_name'], $path) ){
			return false;
		}
		return true;
	}
	
	
	/**
	* Enregistre le fichier sur un serveur FTP
	*
	* @param resource $ftp_stream -> La ressource de connexion FTP
	* @param string   $path       -> Le chemin complet du dossier de destination
	* @param string   $filename   -> Le nom du fichier
	* @return true si réussi, sinon false
	*/
	public function saveFTP($ftp_stream, $path, $filename){
		return ftp_put($ftp_stream, $path.$filename, $_FILES['qqfile']['tmp_name'], FTP_BINARY);
	}
	
	
	/**
	* Écrit la map dans le dossier "Maps" via le serveur
	*
	* @param resource $client   -> La ressource du client GbxRemote
	* @param string   $filename -> Le chemin vers le fichier
	*/
	public function writeMap($client, $filename){
		$out = true;
		$str = file_get_contents($_FILES['qqfile']['tmp_name']);
		$str64 = new IXR_Base64($str);
		
		if( !$client->query('WriteFile', $filename, $str64) ){
			$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage().'opuet';
		}
		
		return $out;
	}
	
	
	/**
	* Ajoute ou insert une map à la liste du serveur
	*
	* @param resource $client   -> La ressource du client GbxRemote
	* @param string   $filename -> Le chemin vers le fichier
	* @param array    $queries           -> Requêtes à executer et le type d'ajout à la liste: array('insert' => 'InsertMap', 'add' => 'AddMap', 'type' => 'add')
	* @return true si réussi, sinon erreur texte
	*/
	public function saveMap($client, $filename, $queries){
		$out = true;
		
		if($queries['type'] == 'insert'){
			if( !$client->query($queries['insert'], $filename) ){
				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage().'insert';
			}
		}
		else{
			if( !$client->query($queries['add'], $filename) ){
				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage().'add';
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le nom du fichier
	*/
	public function getName(){
		return $_FILES['qqfile']['name'];
	}
	
	
	/**
	* Récupère la taille du fichier
	*/
	public function getSize(){
		return $_FILES['qqfile']['size'];
	}
}


/**
* Permet de gérer l'enregistrement du fichier uploadé par XHR ou Formulaire
*/
class FileUploader {
	private $allowedExtensions = array();
	private $sizeLimit = 10485760;
	private $file;
	
	function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){   
		// Ecrase les paramètres dans les variables de config
		$allowedExtensions = array_map("strtolower", $allowedExtensions);
		$this->allowedExtensions = $allowedExtensions;
		$this->sizeLimit = $sizeLimit;
		
		// Test si le serveur peut accepter la config
		$this->_checkServerSettings();
		
		// Test si il y a bien un fichier, si oui, on selectionne le type d'enregistrement (XHR ou Formulaire)
		if( isset($_GET['qqfile']) ){
			$this->file = new uploadedFileXhr();
		}
		else if( isset($_FILES['qqfile']) ){
			$this->file = new uploadedFileForm();
		}
		else{
			$this->file = false; 
		}
	}
	
	
	/**
	* Vérifie si le serveur peut accepter la taille max configurée
	*/
	private function _checkServerSettings(){
		$postSize = $this->_toBytes( ini_get('post_max_size') );
		$uploadSize = $this->_toBytes( ini_get('upload_max_filesize') );
		
		if( $postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit ){
			$size = max(1, $this->sizeLimit / 1024 / 1024) . 'Mo';
			die("{'error':'increase post_max_size and upload_max_filesize to $size'}");    
		}
	}
	
	
	/**
	* Convertie les Go, Mo ou Ko du php.ini en octets
	*/
	private function _toBytes($str){
		$val = trim($str);
		$last = strtolower($str[strlen($str)-1]);
		switch($last){
			case 'g': $val *= 1024;
			case 'm': $val *= 1024;
			case 'k': $val *= 1024;
		}
		return $val;
	}
	
	
	/**
	* Enregistre le fichier envoyé dans un dossier
	*
	* @param string   $uploadDirectory  -> Le chemin du dossier de destination
	* @param bool     $replaceOldFile   -> Remplacement des anciens fichiers qui ont le même nom ? Non par défaut
	* @param function $filenameFunction -> La fonction de traitement du filename
	* @return array('success' => true) ou array('error' => 'error message')
	*/
	public function handleUpload($uploadDirectory, $replaceOldFile = false, $filenameFunction = null){
		// Si on peut écrire dans le dossier de destination
		if( !is_writable($uploadDirectory) ){
			return array('error' => Utils::t('Server error. The upload destination folder isn\'t writable.'));
		}
		
		// Si il y a bien un fichier envoyé
		if( !$this->file ){
			return array('error' => Utils::t('No file was uploaded'));
		}
		
		// Récuperation de la taille du fichier et test si il n'est pas vide ou supérieur à la taille configurée
		$size = $this->file->getSize();
		if($size === 0){
			return array('error' => Utils::t('The file is empty.'));
			return array('error' => Utils::t('The file is empty.'));
		}
		if($size > $this->sizeLimit){
			return array('error' => Utils::t('The file size is too large.'));
		}
		
		// Récuperation du nom et de l'extension du fichier pour tester si l'extension est valide et si le nom du fichier n'existe pas déjà
		$pathinfo = pathinfo( $this->file->getName() );
		if($filenameFunction != null){
			$filename = $filenameFunction($pathinfo['filename']);
		}
		else{
			$filename = $pathinfo['filename'];
		}
		$ext = $pathinfo['extension'];
		if( $this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions) ){
			$these = implode(', ', $this->allowedExtensions);
			return array('error' => Utils::t('The file has invalid extension (allowed extensions:').' '.$these.').');
		}
		if( !$replaceOldFile ){
			// Pour chaque fichier, on test si il existe, si oui, on rajoute un nombre aléatoire de 10 à 99
			while( file_exists($uploadDirectory . $filename . '.' . $ext) ){
				$filename .= rand(10, 99);
			}
		}
		
		// Enregistrement du fichier
		if( $this->file->save($uploadDirectory . $filename . '.' . $ext) ){
			return array('success' => true);
		}
		else{
			return array('error' => Utils::t('The file was not uploaded. Upload has been cancelled or a server error occurred.'));
		}
	}
	
	
	/**
	* Enregistre le fichier envoyé dans un dossier sur un serveur FTP
	*
	* @param resource $ftp_stream       -> La ressource de connexion FTP
	* @param string   $uploadDirectory  -> Le chemin du dossier de destination
	* @param bool     $replaceOldFile   -> Remplacement des anciens fichiers qui ont le même nom ? Non par défaut
	* @param function $filenameFunction -> La fonction de traitement du filename
	* @return array('success' => true) ou array('error' => 'error message')
	*/
	public function handleUploadFTP($ftp_stream, $uploadDirectory, $replaceOldFile = false, $filenameFunction = null){
		// Si on peut écrire dans le dossier de destination
		if( ! @ftp_chdir($ftp_stream, $uploadDirectory) ){
			return array('error' => Utils::t('Server error. The upload destination folder isn\'t writable.'));
		}
		
		// Si il y a bien un fichier envoyé
		if( !$this->file ){
			return array('error' => Utils::t('No file was uploaded'));
		}
		
		// Récuperation de la taille du fichier et test si il n'est pas vide ou supérieur à la taille configurée
		$size = $this->file->getSize();
		if($size === 0){
			return array('error' => Utils::t('The file is empty.'));
		}
		if($size > $this->sizeLimit){
			return array('error' => Utils::t('The file size is too large.'));
		}
		
		// Récuperation du nom et de l'extension du fichier pour tester si l'extension est valide et si le nom du fichier n'existe pas déjà
		$pathinfo = pathinfo( $this->file->getName() );
		if($filenameFunction != null){
			$filename = $filenameFunction($pathinfo['filename']);
		}
		else{
			$filename = $pathinfo['filename'];
		}
		$ext = $pathinfo['extension'];
		if( $this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions) ){
			$these = implode(', ', $this->allowedExtensions);
			return array('error' => Utils::t('The file has invalid extension (allowed extensions:').' '.$these.').');
		}
		
		// Si il ne faut pas remplacer les anciens fichiers
		if( !$replaceOldFile ){
			// Fonction pour vérifier si le fichier existe sur le FTP
			function ftp_file_exists($ftp_stream, $uploadDirectory, $filename){
				$files = ftp_nlist($ftp_stream, $uploadDirectory);
				if( count($files) > 0){
					foreach($files as $file){
						if($uploadDirectory.$filename == $file){
							return true;
						}
					}
				}
				return false;
			}
			// Pour chaque fichier, on test si il existe, si oui, on rajoute un nombre aléatoire de 10 à 99
			while( ftp_file_exists($ftp_stream, $uploadDirectory, $filename.'.'.$ext) ){
				$filename .= rand(10, 99);
			}
		}
		
		// Enregistrement du fichier
		if( $this->file->saveFTP($ftp_stream, $uploadDirectory, $filename.'.'.$ext) ){
			return array('success' => true);
		}
		else{
			return array('error' => Utils::t('The file was not uploaded. Upload has been cancelled or a server error occurred.'));
		}
	}
	
	
	/**
	* Enregistre le fichier envoyé dans un dossier sur un serveur Maniaplanet
	*
	* @param resource $client           -> La ressource du client XMLRPC
	* @param string   $uploadDirectory  -> Le chemin du dossier de destination
	* @param bool     $replaceOldFile   -> Remplacement des anciens fichiers qui ont le même nom ? Non par défaut
	* @param function $filenameFunction -> La fonction de traitement du filename
	* @return array('success' => true) ou array('error' => 'error message')
	*/
	public function handleUploadManiaPlanetServer($client, $uploadDirectory, $queries, $filenameFunction = null){
		// Si le client est initialisé
		if (!$client->socket || $client->protocol == 0) {
			return array('error' => Utils::t('Client not initialized'));
		}
		
		// Si il y a bien un fichier envoyé
		if( !$this->file ){
			return array('error' => Utils::t('No file was uploaded'));
		}
		
		// Récuperation de la taille du fichier et test si il n'est pas vide ou supérieur à la taille configurée
		$size = $this->file->getSize();
		if($size === 0){
			return array('error' => Utils::t('The file is empty.'));
		}
		if($size > $this->sizeLimit){
			return array('error' => Utils::t('The file size is too large.'));
		}
		
		// Récuperation du nom et de l'extension du fichier pour tester si l'extension est valide et si le nom du fichier n'existe pas déjà
		$pathinfo = pathinfo( $this->file->getName() );
		if($filenameFunction != null){
			$filename = $filenameFunction($pathinfo['filename']);
		}
		else{
			$filename = $pathinfo['filename'];
		}
		$ext = $pathinfo['extension'];
		if( $this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions) ){
			return array('error' => Utils::t('The file has invalid extension (allowed extensions:').' '.implode(', ', $this->allowedExtensions).').');
		}
		
		// Enregistrement du fichier
		$error = false;
		$pathToFile = $uploadDirectory.$filename.'.'.$ext;
		if( file_exists($uploadDirectory) ){
			if( ($result = $this->file->save($pathToFile)) !== true ){
				$error = true;
			}
		}
		else{
			if( ($result = $this->file->writeMap($client, $pathToFile)) !== true ){
				$error = true;
			}
		}
		
		if(!$error){
			// Ajout/insert la map
			if( isset($_GET['type']) && $_GET['type'] != 'local' ){
				$out = $this->file->saveMap($client, $pathToFile, $queries);
			}
			// Envoi local seulement
			else{
				$out = true;
			}
		}
		else{
			// Erreur des fonctions save ou writeMap
			if($result){
				$out = $result;
			}
			else{
				$out = 'write error';
			}
		}
		
		if($out === true){
			return array('success' => true, 'out' => $out);
		}
		else{
			return array('error' => Utils::t('The file was not uploaded. Upload has been cancelled or a server error occurred.').' ('.$out.')');
		}
	}
	
	
	/**
	* Enregistre le fichier envoyé en local
	*
	* @param string   $uploadDirectory   -> Le chemin du dossier de destination
	* @param bool     $replaceOldFile    -> Remplacement des anciens fichiers qui ont le même nom ? Non par défaut
	* @param array    $allowedExtensions -> Les extensions autorisées : array('jpg', 'png', 'gif');
	* @param int      $sizeLimit         -> La taille limite d'envoi (égale ou inférieure à la configuration de PHP)
	* @param function $filenameFunction  -> La fonction de traitement du filename
	* @return array('success' => true) ou array('error' => 'error message')
	*/
	public static function saveUploadedFile($uploadDirectory, $replaceOldFile = false, $allowedExtensions = array(), $sizeLimit = 10485760, $filenameFunction = null){
		$uploader = new FileUploader($allowedExtensions, $sizeLimit);
		return $uploader->handleUpload($uploadDirectory, $replaceOldFile, $filenameFunction);
	}
	
	
	/**
	* Enregistre le fichier envoyé sur un serveur FTP
	*
	* @param resource $ftp_stream        -> La ressource de connexion FTP
	* @param string   $uploadDirectory   -> Le chemin du dossier de destination
	* @param bool     $replaceOldFile    -> Remplacement des anciens fichiers qui ont le même nom ? Non par défaut
	* @param array    $allowedExtensions -> Les extensions autorisées : array('jpg', 'png', 'gif');
	* @param int      $sizeLimit         -> La taille limite d'envoi (égale ou inférieure à la configuration de PHP)
	* @param function $filenameFunction  -> La fonction de traitement du filename
	* @return array('success' => true) ou array('error' => 'error message')
	*/
	public static function saveUploadedFileToFTP($ftp_stream, $uploadDirectory, $replaceOldFile = false, $allowedExtensions = array(), $sizeLimit = 10485760, $filenameFunction = null){
		$uploader = new FileUploader($allowedExtensions, $sizeLimit);
		return $uploader->handleUploadFTP($ftp_stream, $uploadDirectory, $replaceOldFile, $filenameFunction);
	}
	
	
	/**
	* Enregistre le fichier envoyé sur un serveur dédié Maniaplanet
	*
	* @param resource $client            -> La ressource du client XMLRPC
	* @param string   $uploadDirectory   -> Le chemin du dossier de destination
	* @param array    $queries           -> Requêtes à executer et le type d'ajout à la liste: array('insert' => 'InsertMap', 'add' => 'AddMap', 'type' => 'add')
	* @param array    $allowedExtensions -> Les extensions autorisées : array('jpg', 'png', 'gif');
	* @param int      $sizeLimit         -> La taille limite d'envoi (égale ou inférieure à la configuration de PHP)
	* @param function $filenameFunction  -> La fonction de traitement du filename
	* @return array('success' => true) ou array('error' => 'error message')
	*/
	public static function saveUploadedFileToManiaPlanetServer($client, $uploadDirectory, $queries, $allowedExtensions = array(), $sizeLimit = 10485760, $filenameFunction = null){
		$uploader = new FileUploader($allowedExtensions, $sizeLimit);
		return $uploader->handleUploadManiaPlanetServer($client, $uploadDirectory, $queries, $filenameFunction);
	}
}
?>
<?php
/*
* Classe utilitaire générale
*/
abstract class Utils {
	
	/**
	* Redirection
	*
	* @param bool   $auto  -> Mode automatique, redirige vers la page en cours
	* @param string $page  -> Page à rediriger
	* @param int    $sleep -> Temps en seconde à attendre avec d'exécuter la redirection
	*/
	public static function redirection($auto = true, $page = null, $sleep = 0){
		if( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != null){ $protocol = 'https'; }
		else{ $protocol = 'http'; }
		$host = $_SERVER['HTTP_HOST'];
		$uri  = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
		if($auto){
			$page = basename($_SERVER['PHP_SELF']);
			if($page == 'index.php'){
				$page = null;
			}
		}
		
		// Redirection
		if($sleep !== 0){
			header("Refresh: $sleep; URL=$protocol://$host$uri/$page");
		}
		else{
			header("Location: $protocol://$host$uri/$page");
		}
		exit;
	}
	
	
	/**
	* Remplace une url texte en url cliquable
	*
	* @param string $str -> La chaine de caractères contenant une ou plusieurs url
	* @param bool $bbcode -> Convertit en HTML par defaut, true pour le BBcode
	* @return la chaine de caractères avec les url remplacées
	*/
	public static function replaceTextURL($str, $bbcode = false){
		$regex = '$(?:https?|ftp)://(?:www\.|ssl\.)?[a-z0-9._%-]+(?:/[a-z0-9._/%-]*(?:\?[a-z0-9._/%-]+=[a-z0-9._/%+-]+(?:&(?:amp;)?[a-z0-9._/%-]+=[a-z0-9._/%+-]+)*)?)?(?:#[a-z0-9._-]*)?$i';
		
		if($bbcode){
			$code = '[url]$0[/url]';
		}
		else{
			$code = '<a href="$0">$0</a>';
		}
		
		return preg_replace($regex, $code, $str);
	}
	
	
	/**
	* Vérifie si l'adresse email est dans un format valide
	*
	* @param string $email -> L'adresse email à tester
	* @return bool
	*/
	public static function isValidEmail($email){
		$out = false;
		$regex = '#^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,5}$#';
		
		if( preg_match($regex, $email) ){
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Vérifie si le numero de téléphone est dans un format valide
	*
	* @param string $tel -> Le numero de téléphone à tester
	* @return bool
	*/
	public static function isValidTel($tel){
		$out = false;
		$regex = '#^0[0-9]([ .-]?[0-9]{2}){4}$#';
		
		if( preg_match($regex, $tel) ){
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Retourne l'image du Captcha
	*
	* @require showcaptcha.php dans un dossier "./includes/captcha/"
	*/
	public static function showCaptcha(){
		// Chaine de caractères pour créer le code
		$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
		$code = null;
		for($i = 0; $i < 4; $i++) {
			$code .= $chars[mt_rand(0, 35)];
		}
		// On stocke le code dans la session
		$_SESSION['captcha'] = $code;
		session_write_close();
		return '<img src="./includes/captcha/showcaptcha.php" height="40" width="145" alt="Impossible d\'afficher le code !" />';
	}
	
	
	/**
	* Lis les données d'un cookie
	*
	* @param string $cookie_name -> Le nom du cookie
	* @param int    $data_pos    -> La position de la donnée à retourner, null pour toutes les données
	* @return string si une position est choisie, sinon return array de toutes les données
	*/
	public static function readCookieData($cookie_name, $data_pos = null){
		$separator = '|';
		
		if( isset($_COOKIE[$cookie_name]) ){
			$out =  explode($separator, $_COOKIE[$cookie_name]);
			
			if( is_numeric($data_pos) ){
				if( isset($out[$data_pos]) && $out[$data_pos] != null){
					return $out[$data_pos];
				}
			}
			else{
				if($out[0] != null){
					return $out;
				}
			}
		}else{
			return null;
		}
	}
	
	
	/**
	* Ajoute des données dans un cookie
	*
	* @param string $cookieName   -> Le nom du cookie
	* @param array  $data         -> Les données du cookie
	* @param int    $cookieExpire -> Le nombre de jours avant que le cookie expire
	* @return true si l'écriture du cookie à réussi, sinon false
	*/
	public static function addCookieData($cookieName, $data, $cookieExpire = 15){
		$separator = '|';
		
		$newCookieData = null;
		for($i = 0; $i < count($data); $i++){
			if($i == count($data)-1){
				$newCookieData .= $data[$i];
			}
			else{
				$newCookieData .= $data[$i].$separator;
			}
		}
		
		if( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != null){ $isHttps = true; }
		else{ $isHttps = false; }
		if( setcookie($cookieName, $newCookieData, time()+60*60*24*$cookieExpire, '/', $isHttps) ){
			return true;
		}
		else{
			return false;
		}
	}
	
	
	/**
	* Récupère la langue du navigateur
	*
	* @param string $forceLang -> Forcer l'utilisation du langue
	* @return $_SESSION['lang']
	*/
	public static function getLang($forceLang = null){
		if($forceLang){
			$_SESSION['lang'] = $forceLang;
		}
		else{
			if( !isset($_SESSION['lang']) ){
				$_SESSION['lang'] = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
			}
		}
		
		return $_SESSION['lang'];
	}
	
	
	/**
	* Retourne la valeur du terme
	*
	* @param array $args -> Arugments dans la clé. Ex: t('key word n°!numero', array('!numero' => $numero) );
	*/
	public static function t($key, $args = array() ){
		global $translate;
		$out = $key;
		
		if( isset($_SESSION['lang']) && $_SESSION['lang'] !== 'en' ){
			if( isset($translate[$key]) ){
				$out = $translate[$key];
			}
		}
		
		if( count($args) > 0 ){
			$out = str_replace( array_keys($args), array_values($args), $out);
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le navigateur internet du visiteur
	*/
	public static function getBrowser(){
		$out = null;
		$http_user_agent = $_SERVER['HTTP_USER_AGENT'];
		
		if( strstr($http_user_agent, 'Firefox') ){ $out = 'Firefox'; }
		else if( strstr($http_user_agent, 'Chrome') ){ $out = 'Chrome'; }
		else if( strstr($http_user_agent, 'Opera') ){ $out = 'Opera'; }
		else if( strstr($http_user_agent, 'MSIE') ){ $out = 'IE'; }
		else if( strstr($http_user_agent, 'Safari') ){ $out = 'Safari'; }
		else if( strstr($http_user_agent, 'Konqueror') ){ $out = 'Konqueror'; }
		else if( strstr($http_user_agent, 'Netscape') ){ $out = 'Netscape'; }
		else{ $out = 'Others'; }
		
		return $out;
	}
	
	
	/**
	* Récupère le système d'exploitation du visiteur
	*/
	public static function getOperatingSystem(){
		$out = null;
		$http_user_agent = $_SERVER['HTTP_USER_AGENT'];
		
		if( strstr($http_user_agent, 'Win') ){ $out = 'Windows'; }
		else if( (strstr($http_user_agent, 'Mac')) || (strstr('PPC', $http_user_agent)) ){ $out = 'Mac'; }
		else if( strstr($http_user_agent, 'Linux') ){ $out = 'Linux'; }
		else if( strstr($http_user_agent, 'FreeBSD') ){ $out = 'FreeBSD'; }
		else if( strstr($http_user_agent, 'SunOS') ){ $out = 'SunOS'; }
		else if( strstr($http_user_agent, 'IRIX') ){ $out = 'IRIX'; }
		else if( strstr($http_user_agent, 'BeOS') ){ $out = 'BeOS'; }
		else if( strstr($http_user_agent, 'OS/2') ){ $out = 'OS/2'; }
		else if( strstr($http_user_agent, 'AIX') ){ $out = 'AIX'; }
		else{ $out = 'Others'; }
		
		return $out;
	}
	
	
	/**
	* Détermine si le serveur est sous Windows, par défaut Unix
	*
	* @return bool
	*/
	public static function isWinServer(){
		if( stripos(PHP_OS, 'WIN') === 0 ){
			return true;
		}
		else{
			return false;
		}
	}
	
	
	/**
	* Détermine si l'adresse ip du visiteur est dans le réseau local
	*
	* @param string $addr -> L'adresse IP à utiliser
	* @return bool
	*/
	public static function isLocalhostIP($addr = null){
		$out = false;
		
		$serverIPEx = explode('.', $_SERVER['SERVER_ADDR']);
		$serverIP = $serverIPEx[0].'.'.$serverIPEx[1].'.'.$serverIPEx[2];
		
		if($addr){
			$userIPEx = explode('.', $addr);
		}
		else{
			$userIPEx = explode('.', $_SERVER['REMOTE_ADDR']);
		}
		$userIP = $userIPEx[0].'.'.$userIPEx[1].'.'.$userIPEx[2];
		
		if($userIP === $userIP){
			$out = true;
		}
		
		return $out;
	}
}
?>
<?php
/**
* Class Zip
*
* Méthodes de traitement pour les archives ZIP
*/
class Zip extends ZipArchive {
	
	/**
	* Créer une archive ZIP
	*
	* @param string $filename -> Nom de l'archive
	* @param array  $struct   -> Tableau des données de l'archive :
	*  $struct = array(
	*    'dirname' => array(
	*       'dirname2' => array(
	*          'file3.txt'
	*        ),
	*        'file2.txt'
	*     ),
	*     'file1.txt'
	*  );
	* @return true si réussi, sinon false
	*/
	public function create($filename, $struct, &$errorMsg = null){
		$out = false;
		
		if( !file_exists($filename) ){
			$out = self::add($filename, $struct, $errorMsg);
		}
		else{
			$errorMsg = self::_getErrorMsg(ZIPARCHIVE::ER_EXISTS);
		}
		
		return $out;
	}
	
	
	/**
	* Ajoute les données de la structure dans une archive ZIP
	*
	* @param string $filename -> Nom de l'archive
	* @param array  $struct   -> Tableau des données de l'archive
	* @return true si réussi, sinon false
	*/
	public function add($filename, $struct, &$errorMsg = null){
		$out = false;
		$zip = new ZipArchive();
		
		if( $result = $zip->open($filename, ZIPARCHIVE::CREATE) ){
			self::_checkStructure($zip, $struct);
			$out = true;
			$zip->close();
		}
		else{
			$errorMsg = self::_getErrorMsg($result);
		}
		
		return $out;
	}
	
	
	/**
	* Extrait une archive dans un dossier
	*
	* @param string $filename -> Chemin de l'archive
	* @param string $path     -> Chemin d'extraction
	*/
	public function extract($filename, $path, &$errorMsg = null){
		$out = false;
		$zip = new ZipArchive();
		
		if( $result = $zip->open($filename) ){
			if( !$out = $zip->extractTo($path) ){
				$errorMsg = self::_getErrorMsg('ER_EXTRACT');
			}
			$zip->close();
		}
		else{
			$errorMsg = self::_getErrorMsg($result);
		}
		
		return $out;
	}
	
	
	/**
	* Liste et créer la structure des données
	*
	* @param object $object -> L'instance de ZipArchive
	* @param array  $struct -> Tableau des données de l'archive
	* @param string $path   -> Le chemin à partir de la racine de la structure
	*/
	private function _checkStructure($object, $struct, $path = null){
		if( count($struct) > 0 ){
			foreach($struct as $folder => $file){
				if( is_string($folder) ){
					$object->addEmptyDir($path.$folder);
					self::_checkStructure($object, $struct[$folder], $path.$folder.'/');
				}
				else{
					$filename = null;
					if( strstr($file, '/') ){
						$pathinfo = pathinfo($file);
						$filename = $pathinfo['basename'];
					}
					
					if($filename){
						$object->addFile($path.$file, $filename);
					}else{
						$object->addFile($path.$file);
					}
				}
			}
		}
	}
	
	
	/**
	* Retourne le message d'erreur de ZipArchive correspondant au code erreur
	*
	* @param int $errorCode -> Le code d'erreur
	* @return string
	*/
	private function _getErrorMsg($errorCode){
		$out = null;
		
		switch($errorCode){
			case ZIPARCHIVE::ER_EXISTS:
				$out = 'Le fichier existe déjà.';
				break;
			case ZIPARCHIVE::ER_INCONS:
				$out = 'L\'archive ZIP est inconsistante.';
				break;
			case ZIPARCHIVE::ER_INVAL:
				$out = 'Argument invalide.';
				break;
			case ZIPARCHIVE::ER_MEMORY:
				$out = 'Erreur de mémoire.';
				break;
			case ZIPARCHIVE::ER_NOENT:
				$out = 'Le fichier n\'existe pas.';
				break;
			case ZIPARCHIVE::ER_NOZIP:
				$out = 'N\'est pas une archive ZIP.';
				break;
			case ZIPARCHIVE::ER_OPEN:
				$out = 'Impossible d\'ouvrir le fichier.';
				break;
			case ZIPARCHIVE::ER_READ:
				$out = 'Erreur lors de la lecture.';
				break;
			case ZIPARCHIVE::ER_SEEK:
				$out = 'Erreur de position.';
				break;
			case 'ER_EXTRACT':
				$out = 'Erreur lors de l\'extraction.';
				break;
		}
		
		return $out;
	}
}
?>
<?php

/**
* Classe pour la gestion des niveaux admins
*/
class AdminServAdminLevel {
	
	/**
	* Constantes
	*/
	private static $DEFAULT_TYPE = array(
		'SuperAdmin' => array('SuperAdmin', 'Admin', 'User'),
		'Admin' => array('Admin', 'User'),
		'User' => array('User'),
	);
	private static $DEFAULT_ACCESS = array(
		'srvopts' => 'server_options',
		'gameinfos' => 'game_infos',
		'chat' => 'chat',
		'maps-list' => 'maps_list',
		'maps-local' => 'maps_local',
		'maps-upload' => 'maps_upload',
		'maps-order' => 'maps_order',
		'maps-matchset' => 'maps_matchsettings',
		'maps-creatematchset' => 'maps_create_matchsettings',
		'link_access_server',
		'plugins-list' => 'plugins_list',
		'guestban' => 'guest_ban',
	);
	private static $DEFAULT_PERMISSION = array(
		'speed_admin',
		'switch_server',
		'player_kick',
		'player_ban',
		'player_guest',
		'player_ignore',
		'player_forcetospectator',
		'player_forcetoplayer',
		'player_changeteam',
		'force_scores',
		'cancel_vote',
		'srvopts_general_name',
		'srvopts_general_comment',
		'srvopts_general_playerpassword',
		'srvopts_general_spectatorpassword',
		'srvopts_general_nbplayers',
		'srvopts_general_nbspectators',
		'srvopts_advanced',
		'srvopts_adminlevelpassword',
		'srvopts_importexport',
		'gameinfos_general_gamemode',
		'gameinfos_general_options',
		'gameinfos_general_warmup',
		'gameinfos_teams_options',
		'gameinfos_gamemode_options',
		'chat_sendmessage',
		'maps_list_moveaftercurrent',
		'maps_list_removetolist',
		'maps_local_add',
		'maps_local_insert',
		'maps_local_download',
		'maps_local_rename',
		'maps_local_move',
		'maps_local_delete',
		'maps_upload_add',
		'maps_upload_insert',
		'maps_upload_folder',
		'maps_matchsettings_save',
		'maps_matchsettings_load',
		'maps_matchsettings_add',
		'maps_matchsettings_insert',
		'maps_matchsettings_edit',
		'maps_matchsettings_delete',
		'folder_new',
		'folder_rename',
		'folder_move',
		'folder_delete',
		'guestban_addplayer',
		'guestban_removeplayer',
		'guestban_playlist_new',
		'guestban_playlist_save',
		'guestban_playlist_load',
		'guestban_playlist_delete',
	);
	private static $CONFIG_PATH = './config/';
	private static $CONFIG_FILENAME = 'adminlevel.cfg.php';
	private static $CONFIG_START_TEMPLATE = "<?php\nclass AdminLevelConfig {\n\tpublic static \$ADMINLEVELS = array(\n\t\t/********************* ADMINLEVELS CONFIGURATION *********************/\n\t\t\n";
	private static $CONFIG_END_TEMPLATE =  "\t);\n}\n?>";
	
	
	/**
	* Vérifie s'il y a bien une config de niveaux admins
	*
	* @param string $levelName -> Tester si le niveau admin est présent
	* @return bool
	*/
	public static function hasLevel($levelName = null) {
		$out = false;
		
		if (class_exists('AdminLevelConfig')) {
			$adminLevelList = AdminLevelConfig::$ADMINLEVELS;
			
			if (isset($adminLevelList) && !empty($adminLevelList)) {
				if ($levelName) {
					foreach ($adminLevelList as $adminLevelName => $adminLevelData) {
						if ($adminLevelName === $levelName) {
							$out = true;
							break;
						}
					}
				}
				else {
					$out = true;
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Vérifie s'il le niveau admin a bien l'accès à la page
	*
	* @param string $access    -> Nom de l'accès
	* @param string $levelName -> Nom du niveau admin
	* @return bool
	*/
	public static function hasAccess($access, $levelName = null) {
		$out = false;
		
		// Si l'accès demandé est le nom d'une page
		$defaultAccess = self::getDefaultAccess();
		if (array_key_exists($access, $defaultAccess)) {
			foreach ($defaultAccess as $pageName => $accessName) {
				if ($access == $pageName) {
					$access = $accessName;
					break;
				}
			}
		}
		if ($levelName === null && defined('USER_ADMINLEVEL')) {
			$levelName = USER_ADMINLEVEL;
		}
		$levelData = self::getData($levelName, 'access');
		if (!empty($levelData) && in_array($access, $levelData)) {
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Vérifie s'il le niveau admin a bien la permission d'utiliser une fonctionnalité
	*
	* @param mixed  $permission -> Nom de la permission ou tableau de plusieurs permissions
	* @param string $levelName  -> Nom du niveau admin
	* @param string $levelType  -> Type de niveau minimum à autoriser
	* @return bool
	*/
	public static function hasPermission($permission, $levelName = null, $levelType = null) {
		$out = false;
		if ($levelName === null && defined('USER_ADMINLEVEL')) {
			$levelName = USER_ADMINLEVEL;
		}
		
		if ($levelName) {
			if ($levelType !== null) {
				$levelData = self::getData($levelName, 'adminlevel');
				$levelTypeAuthorized = self::getDefaultType($levelData['type']);
				if (!in_array($levelType, $levelTypeAuthorized)) {
					return false;
				}
			}
			$levelData = self::getData($levelName, 'permission');
			
			if (!empty($levelData)) {
				if (is_array($permission)) {
					$result = array();
					foreach ($permission as $perm) {
						if (in_array($perm, $levelData)) {
							$result[] = true;
						}
						else {
							$result[] = false;
						}
					}
					if (in_array(true, $result)) {
						$out = true;
					}
				}
				else {
					if (in_array($permission, $levelData)) {
						$out = true;
					}
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère les niveaux par défaut ou renvoie les niveaux autorisés suivant le type
	*
	* @param string $type -> Type de niveau
	* @return array
	*/
	public static function getDefaultType($levelType = null){
		$out = array();
		
		if ($levelType === null) {
			$out = array_keys(self::$DEFAULT_TYPE);
		}
		else {
			foreach (self::$DEFAULT_TYPE as $defaultTypeLevel => $defaultAuthorizedLevel) {
				if ($levelType === $defaultTypeLevel) {
					$out = $defaultAuthorizedLevel;
					break;
				}
			}
		}
		
		return $out;
	}
	public static function getDefaultAccess(){
		return self::$DEFAULT_ACCESS;
	}
	public static function getDefaultPermission(){
		return self::$DEFAULT_PERMISSION;
	}
	
	
	/**
	* Récupère les données de configuration pour un niveau admin
	*
	* @param string $levelName -> Nom du niveau admin
	* @param string $fieldName -> Nom du champ de données à retourner
	* @return array
	*/
	public static function getData($levelName = null, $fieldName = 'all') {
		$out = array();
		if ($levelName === null && defined('USER_ADMINLEVEL')) {
			$levelName = USER_ADMINLEVEL;
		}
		
		if (self::hasLevel($levelName)) {
			$levelData = AdminLevelConfig::$ADMINLEVELS[$levelName];
			
			if ($fieldName != 'all') {
				if (isset($levelData[$fieldName])) {
					$out = $levelData[$fieldName];
				}
			}
			else {
				$out = $levelData;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la position du niveau admin dans le fichier de config
	*
	* @param string $levelName -> Nom du niveau admin
	* @return string
	*/
	public static function getId($levelName = null) {
		$id = 0;
		$levelList = self::getStaticList();
		if ($levelName === null && defined('USER_ADMINLEVEL')) {
			$levelName = USER_ADMINLEVEL;
		}
		
		// On cherche la position du niveau à partir de son nom
		if (!empty($levelList)) {
			foreach ($levelList as $levelListName) {
				if ($levelListName == $levelName) {
					break;
				}
				else {
					$id++;
				}
			}
		}
		
		// Si l'id = le nb total de levels -> pas trouvé
		return ($id == count($levelList)) ? -1 : $id;
	}
	
	
	/**
	* Récupère le type à partir du nom
	*
	* @param string $levelName -> Nom du niveau admin
	* @return string
	*/
	public static function getType($levelName = null) {
		$out = null;
		if ($levelName === null && defined('USER_ADMINLEVEL')) {
			$levelName = USER_ADMINLEVEL;
		}
		
		$levelData = self::getData($levelName, 'adminlevel');
		if (isset($levelData['type']) && $levelData['type'] != null) {
			$out = $levelData['type'];
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le nom à partir du type
	*
	* @param int $levelId -> Numéro de la position dans la config
	* @return string
	*/
	public static function getName($levelId) {
		$out = null;
		$levelList = self::getStaticList();
		
		if (!empty($levelList)) {
			$i = 0;
			foreach ($levelList as $levelListName) {
				if ($i == $levelId) {
					$out = $levelListName;
					break;
				}
				$i++;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Détermine si le niveau utilisateur est au minimum de type $levelType
	*
	* @param string $levelType -> Type de niveau admin minimum
	* @return bool
	*/
	public static function isType($levelType, $levelName = null) {
		$out = false;
		if ($levelName === null && defined('USER_ADMINLEVEL')) {
			$levelName = USER_ADMINLEVEL;
		}
		
		$levelData = self::getData($levelName, 'adminlevel');
		$levelTypeAuthorized = self::getDefaultType($levelData['type']);
		if (in_array($levelType, $levelTypeAuthorized)) {
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la liste des niveaux admins configurés pour le serveur courant
	*
	* @param string $server -> Nom du serveur
	* @return array
	*/
	public static function getServerList($serverName = null) {
		$out = array();
		if ($serverName === null && defined('SERVER_NAME')) {
			$serverName = SERVER_NAME;
		}
		
		if (AdminServServerConfig::hasServer($serverName)) {
			$levels = self::getStaticList();
			if (!empty($levels)) {
				foreach ($levels as $levelName) {
					$levelType = self::getType($levelName);
					foreach (ServerConfig::$SERVERS[$serverName]['adminlevel'] as $serverLevelType => $serverLevelTypeAccess) {
						if ($levelType === $serverLevelType) {
							if ($serverLevelType != null && $serverLevelTypeAccess != 'none') {
								if (self::userAllowed($levelName, $serverName)) {
									$out['levels'][] = $levelName;
								}
							}
						}
					}
				}
			}
		}
		
		$out['last'] = Utils::readCookieData('adminserv', 1);
		
		return $out;
	}
	
	
	/**
	* Récupère la liste des niveaux admins configurés
	*/
	public static function getStaticList(){
		$out = array();
		
		if (self::hasLevel()) {
			foreach (AdminLevelConfig::$ADMINLEVELS as $levelName => $levelData) {
				$out[] = $levelName;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Vérifie si l'ip de l'utilisateur est autorisé dans le niveau admin
	*
	* @param string $level  -> Nom du niveau admin
	* @param string $server -> Nom du serveur
	* @return bool
	*/
	public static function userAllowed($levelName, $serverName = null) {
		$out = false;
		if ($serverName === null && defined('SERVER_NAME')) {
			$serverName = SERVER_NAME;
		}
		
		if (AdminServServerConfig::hasServer($serverName)){
			$levelType = self::getType($levelName);
			if ($levelType) {
				$serverLevelTypeAccess = ServerConfig::$SERVERS[$serverName]['adminlevel'][$levelType];
				
				if (is_array($serverLevelTypeAccess)) {
					if (in_array($_SERVER['REMOTE_ADDR'], $serverLevelTypeAccess)) {
						$out = true;
					}
				}
				else {
					if ($serverLevelTypeAccess === 'all') {
						$out = true;
					}
					elseif ($serverLevelTypeAccess === 'none') {
						$out = false;
					}
					else {
						$out = Utils::isLocalhostIP();
					}
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Créer le template d'un niveau admin
	*
	* @param array $levelData -> assoc array(adminlevel => array(type), access, permission)
	*/
	public static function getTemplate($levelData){
		$out = "\t\t'".$levelData['name']."' => array(\n"
			."\t\t\t'adminlevel' => array(\n";
				foreach ($levelData['adminlevel'] as $adminlevelName => $adminlevelData) {
					$out .= "\t\t\t\t'$adminlevelName' => '$adminlevelData',\n";
				}
			$out .= "\t\t\t),\n"
			."\t\t\t'access' => array(\n";
				if (!empty($levelData['access'])) {
					foreach ($levelData['access'] as $accessName) {
						$out .= "\t\t\t\t'$accessName',\n";
					}
				}
			$out .= "\t\t\t),\n"
			."\t\t\t'permission' => array(\n";
				if (!empty($levelData['permission'])) {
					foreach ($levelData['permission'] as $permissionName) {
						$out .= "\t\t\t\t'$permissionName',\n";
					}
				}
			$out .= "\t\t\t),\n"
		."\t\t),\n";
		
		return $out;
	}
	
	
	/**
	* Sauvegarde le fichier de configuration des niveaux admins
	*
	* @param array $levelData -> assoc array(adminlevel => array(type), access, permission)
	* @param int   $editLevel -> Id du niveau à éditer
	* @param array $levelList -> Liste des niveaux de la config
	* @return bool or string error
	*/
	public static function saveConfig($levelData = array(), $editLevel = -1, $levelList = array()) {
		// Liste des niveaux
		$levels = (isset($levelList) && !empty($levelList)) ? $levelList : AdminLevelConfig::$ADMINLEVELS;
		
		// Template
		$fileTemplate = self::$CONFIG_START_TEMPLATE;
		$i = 0;
		foreach ($levels as $levelName => $levelValues) {
			// Édition
			if ($i == $editLevel && isset($levelData) && !empty($levelData)) {
				$fileTemplate .= self::getTemplate($levelData);
			}
			else {
				// Récupération des données des niveaux existant
				$getLevelsData = array(
					'name' => $levelName,
					'adminlevel' => $levelValues['adminlevel'],
					'access' => $levelValues['access'],
					'permission' => $levelValues['permission'],
				);
				
				// Ajout des données au template
				$fileTemplate .= self::getTemplate($getLevelsData);
			}
			$i++;
		}
		
		// Ajout d'un nouveau
		if ($editLevel === -1 && isset($levelData) && !empty($levelData)) {
			if (self::getId($levelData['name']) === -1) {
				$fileTemplate .= self::getTemplate($levelData);
			}
			else {
				return Utils::t('The admin level already exist! Change the name.');
			}
		}
		$fileTemplate .= self::$CONFIG_END_TEMPLATE;
		
		// Enregistrement
		return File::save(self::$CONFIG_PATH.self::$CONFIG_FILENAME, $fileTemplate, false);
	}
}
?>
<?php
define('ADMINSERV_TIMER', false);
define('ADMINSERV_VERSION', '2.1.1');

/**
* Classe pour le fonctionnement d'AdminServ
*/
class AdminServ {
	
	/**
	* Inclue les classes PHP
	*/
	public static function getClass(){
		$pathClass = AdminServConfig::$PATH_RESOURCES.'class/';
		require_once $pathClass.'GbxRemote.inc.php';
		require_once $pathClass.'gbxdatafetcher.inc.php';
		require_once $pathClass.'utils.class.php';
		require_once $pathClass.'tmnick.class.php';
		require_once $pathClass.'timedate.class.php';
		require_once $pathClass.'file.class.php';
		require_once $pathClass.'folder.class.php';
		require_once $pathClass.'str.class.php';
		require_once $pathClass.'upload.class.php';
		require_once $pathClass.'zip.class.php';
		
		$pathCore = AdminServConfig::$PATH_RESOURCES.'core/';
		require_once $pathCore.'adminlevel.php';
		require_once $pathCore.'cache.php';
		require_once $pathCore.'event.php';
		require_once $pathCore.'logs.php';
		require_once $pathCore.'plugin.php';
		require_once $pathCore.'server.php';
		require_once $pathCore.'sort.php';
		require_once $pathCore.'ui.php';
	}
	
	
	/**
	* Méthodes de debug
	*/
	public static function dsm($val){
		echo '<pre>';
		print_r($val);
		echo '</pre>';
	}
	public static function debug($globalValue = null){
		$const = get_defined_constants(true);
		
		return self::dsm(
			array(
				'GLOBALS' => ($globalValue) ? $GLOBALS[$globalValue] : $GLOBALS,
				'ADMINSERV' => $const['user']
			)
		);
	}
	
	/**
	* Erreurs et infos
	*/
	public static function error($text = null){
		global $client;
		// Tente de récupérer le message d'erreur du dédié
		if($text === null){
			$text = '['.$client->getErrorCode().'] '.Utils::t( $client->getErrorMessage() );
		}
		else {
			$text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
		}
		
		AdminServLogs::add('error', $text);
		unset($_SESSION['info']);
		$_SESSION['error'] = $text;
	}
	public static function info($text){
		$_SESSION['info'] = $text;
	}
	
	
	/**
	* Temps de chargement de page
	*/
	public static function startTimer(){
		global $timeStart;
		$timeStart = microtime(true);
	}
	public static function endTimer(){
		global $timeStart;
		$timeEnd = microtime(true);
		$time = $timeEnd - $timeStart;
		return number_format($time, 3);
	}
	
	
	/**
	* Vérifie la version de PHP
	*/
	public static function checkPHPVersion($version){
		if( !version_compare(PHP_VERSION, $version, '>=') ){
			echo '<b>This PHP version is not compatible with AdminServ.</b><br />Your PHP version: '. PHP_VERSION .'<br />PHP version required: '.$version;
			exit;
		}
	}
	
	
	/**
	* Vérifie les droits pour l'écriture/lecture des fichiers
	*
	* @param array $list -> Liste des fichiers à tester : array('path' => 777)
	* @return array
	*/
	public static function checkRights($list){
		if( count($list) > 0 ){
			foreach($list as $path => $minChmod){
				$result = Folder::checkRights($path, $minChmod);
				foreach($result as $grpName => $grpValues){
					foreach($grpValues['result'] as $bool){
						if(!$bool){
							self::error( Utils::t('This path was not required rights:').' '.$path.' ("'.$grpName.'" '.Utils::t('needs').' "'.$minChmod.'")');
							break;
						}
					}
				}
			}
		}
	}
	
	
	/**
	* Intialise le client du serveur courant
	*
	* @param bool $fullInit -> Intialisation complète ? oui par défaut.
	* Si non, ça ne recupère aucune info de base, seulement la connexion
	* au serveur dédié et son authentication.
	* @return bool
	*/
	public static function initialize($fullInit = true){
		global $client;
		$out = false;
		
		if( isset($_SESSION['adminserv']['sid']) ){
			// CONSTANTS
			define('USER_ADMINLEVEL', $_SESSION['adminserv']['adminlevel']);
			define('SERVER_ID', $_SESSION['adminserv']['sid']);
			define('SERVER_NAME', $_SESSION['adminserv']['name']);
			define('SERVER_ADDR', ServerConfig::$SERVERS[SERVER_NAME]['address']);
			define('SERVER_XMLRPC_PORT', ServerConfig::$SERVERS[SERVER_NAME]['port']);
			define('SERVER_MATCHSET', ServerConfig::$SERVERS[SERVER_NAME]['matchsettings']);
			define('SERVER_MAPS_BASEPATH', (isset(ServerConfig::$SERVERS[SERVER_NAME]['mapsbasepath'])) ? ServerConfig::$SERVERS[SERVER_NAME]['mapsbasepath'] : '');
			define('SERVER_ADMINLEVEL', serialize( ServerConfig::$SERVERS[SERVER_NAME]['adminlevel']) );
			
			// CONNEXION
			$client = new IXR_ClientMulticall_Gbx;
			if( !$client->InitWithIp(SERVER_ADDR, SERVER_XMLRPC_PORT, AdminServConfig::SERVER_CONNECTION_TIMEOUT) ){
				Utils::redirection(false, '?error='.urlencode( Utils::t('The server is not accessible.') ) );
			}
			else{
				if( !AdminServAdminLevel::userAllowed(USER_ADMINLEVEL) ){
					Utils::redirection(false, '?error='.urlencode( Utils::t('You are not allowed at this admin level') ) );
				}
				else{
					if( !$client->query('Authenticate', AdminServAdminLevel::getType(), $_SESSION['adminserv']['password']) ){
						Utils::redirection(false, '?error='.urlencode( Utils::t('The password doesn\'t match to the server.') ) );
					}
					else{
						if($fullInit){
							$client->addCall('SetApiVersion', array(date('Y-m-d')) );
							$client->addCall('GetVersion');
							$client->addCall('GetSystemInfo');
							$client->addCall('IsRelayServer');
							
							if( !$client->multiquery() ){
								self::error();
							}
							else{
								$queriesData = $client->getMultiqueryResponse();
								
								// Version
								$getVersion = $queriesData['GetVersion'];
								define('SERVER_VERSION_NAME', $getVersion['Name']);
								define('SERVER_VERSION', $getVersion['Version']);
								define('SERVER_BUILD', $getVersion['Build']);
								if(SERVER_VERSION_NAME == 'ManiaPlanet'){
									define('API_VERSION', $getVersion['ApiVersion']);
								}
								
								// SystemInfo
								$getSystemInfo = $queriesData['GetSystemInfo'];
								define('SERVER_LOGIN', $getSystemInfo['ServerLogin']);
								define('SERVER_PUBLISHED_IP', $getSystemInfo['PublishedIp']);
								define('SERVER_PORT', $getSystemInfo['Port']);
								define('SERVER_P2P_PORT', $getSystemInfo['P2PPort']);
								if(SERVER_VERSION_NAME == 'ManiaPlanet'){
									define('SERVER_TITLE', $getSystemInfo['TitleId']);
									define('IS_SERVER', $getSystemInfo['IsServer']);
									define('IS_DEDICATED', $getSystemInfo['IsDedicated']);
								}
								
								// Relay
								define('IS_RELAY', $queriesData['IsRelayServer']);
								
								// Protocole : tmtp ou maniaplanet
								if(SERVER_VERSION_NAME == 'ManiaPlanet'){
									TmNick::$linkProtocol = 'maniaplanet';
								}
								define('LINK_PROTOCOL', TmNick::$linkProtocol);
								
								// Mode d'affichage : detail ou simple
								if( isset($_SESSION['adminserv']['mode']['general']) ){
									define('USER_MODE_GENERAL', $_SESSION['adminserv']['mode']['general']);
								}
								else{
									define('USER_MODE_GENERAL', 'simple');
								}
								if( isset($_SESSION['adminserv']['mode']['maps']) ){
									define('USER_MODE_MAPS', $_SESSION['adminserv']['mode']['maps']);
								}
								else{
									define('USER_MODE_MAPS', 'simple');
								}
								
								// TmForever
								if(SERVER_VERSION_NAME == 'TmForever'){
									array_shift(ExtensionConfig::$GAMEMODES);
									$stuntsGameMode = array_pop(ExtensionConfig::$GAMEMODES);
									$CupGameMode = array_pop(ExtensionConfig::$GAMEMODES);
									ExtensionConfig::$GAMEMODES[4] = $stuntsGameMode;
									ExtensionConfig::$GAMEMODES[5] = $CupGameMode;
								}
								
								$out = true;
							}
						}
						else{
							$out = true;
						}
					}
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Retourne un lien protocol TM ou ManiaPlanet
	*
	* @param string $link -> Lien : #join=server_login ou /:manialink_name
	* @return string
	*/
	public static function getProtocolLink($link) {
		$out = null;
		$protocolName = 'maniaplanet';
		if (defined('LINK_PROTOCOL')) {
			$protocolName = LINK_PROTOCOL;
		}
		$protocolSeparator = '://';
		
		if (defined('SERVER_VERSION_NAME') && SERVER_VERSION_NAME == 'ManiaPlanet' && defined('SERVER_TITLE')) {
			$out = $protocolName.$protocolSeparator.$link.'@'.SERVER_TITLE;
		}
		else {
			$out = $protocolName.$protocolSeparator.$link;
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le nom du game mode
	*
	* @param int  $gameMode  -> La réponse de GetGameMode()
	* @param bool $getManual -> Forcer la récupération manuelle du nom à partir du numéro dans la config
	* @return string
	*/
	public static function getGameModeName($gameMode, $getManual = false){
		$out = Utils::t('No game mode available');
		
		if( class_exists('ExtensionConfig') && isset(ExtensionConfig::$GAMEMODES) && count(ExtensionConfig::$GAMEMODES) > 0 ){
			if($getManual && SERVER_VERSION_NAME == 'TmForever'){
				$gameMode--;
				if( isset(ExtensionConfig::$GAMEMODES[$gameMode]) ){
					$out = ExtensionConfig::$GAMEMODES[$gameMode];
				}
			}
			else{
				$out = ExtensionConfig::$GAMEMODES[$gameMode];
			}
		}
		
		return $out;
	}
	
	
	/**
	* Détermine si le nom du mode de jeu fourni en paramètre correspond au mode de jeu actuel
	*
	* @param string $gameModeName    -> Nom du mode de jeu à tester
	* @param int    $currentGameMode -> ID du mode de jeu courant. Si null, le mode de jeu courant est récupéré par le serveur
	* @return bool
	*/
	public static function isGameMode($gameModeName, $currentGameMode = null){
		global $client;
		$out = false;
		if($currentGameMode === null){
			$client->query('GetGameMode');
			$currentGameMode = $client->getResponse();
		}
		
		if($gameModeName == self::getGameModeName($currentGameMode) ){
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Vérifie si la configuration du serveur est compatible avec le mode équipe
	*
	* @params int    $gameMode   -> ID du mode de jeu
	* @params string $scriptName -> Nom du script si le mode de jeu est 0
	* @return bool
	*/
	public static function checkDisplayTeamMode($gameMode, $scriptName = null){
		$out = false;
		
		if($gameMode == 0 && SERVER_VERSION_NAME == 'ManiaPlanet' && class_exists('ExtensionConfig') && isset(ExtensionConfig::$TEAMSCRIPTS) && count(ExtensionConfig::$TEAMSCRIPTS) > 0 ){
			foreach(ExtensionConfig::$TEAMSCRIPTS as $teamScript){
				if( stristr($scriptName, $teamScript) ){
					$out = true;
					break;
				}
			}
		}
		else{
			if( self::isGameMode('Team', $gameMode) ){
				$out = true;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Formate le nom d'un script
	*
	* @param string $scriptName -> Le nom du script retourné par le serveur
	* @return string
	*/
	public static function formatScriptName($scriptName){
		$out = str_ireplace('.script.txt', '', $scriptName);
		$scriptNameEx = explode('\\', $out);
		$out = $scriptNameEx[count($scriptNameEx)-1];
		
		return $out;
	}
	
	
	/**
	* Récupère les informations du serveur actuel (map, serveur, stats, joueurs)
	*
	* @param string $sortBy -> Le tri à faire sur la liste
	* @return array
	*/
	public static function getCurrentServerInfo($sortBy = null){
		global $client;
		$out = array();
		
		// JEU
		if(SERVER_VERSION_NAME == 'TmForever'){
			$queryName = array(
				'getMapInfo' => 'GetCurrentChallengeInfo'
			);
		}
		else{
			$queryName = array(
				'getMapInfo' => 'GetCurrentMapInfo'
			);
		}
		
		// REQUÊTES
		$client->addCall($queryName['getMapInfo']);
		if( AdminServAdminLevel::isType('Admin') ){
			$client->addCall('GetMapsDirectory');
		}
		$client->addCall('GetGameMode');
		$client->addCall('GetServerName');
		$client->addCall('GetStatus');
		$client->addCall('GetCurrentCallVote');
		if( AdminServAdminLevel::isType('SuperAdmin') ){
			$client->addCall('GetNetworkStats');
		}
		$client->addCall('GetPlayerList', array(AdminServConfig::LIMIT_PLAYERS_LIST, 0, 1) );
		
		if( !$client->multiquery() ){
			$out['error'] = Utils::t('Client not initialized');
		}
		else{
			// DONNÉES DES REQUÊTES
			$queriesData = $client->getMultiqueryResponse();
			
			// GameMode
			$out['srv']['gameModeId'] = $queriesData['GetGameMode'];
			$out['srv']['gameModeName'] = self::getGameModeName($out['srv']['gameModeId']);
			$out['srv']['gameModeScriptName'] = null;
			if( self::isGameMode('Script', $out['srv']['gameModeId']) ){
				$client->query('GetModeScriptInfo');
				$getModeScriptInfo = $client->getResponse();
				if( isset($getModeScriptInfo['Name']) ){
					$out['srv']['gameModeScriptName'] = self::formatScriptName($getModeScriptInfo['Name']);
				}
			}
			$displayTeamMode = self::checkDisplayTeamMode($out['srv']['gameModeId'], $out['srv']['gameModeScriptName']);
			
			// CurrentMapInfo
			$currentMapInfo = $queriesData[$queryName['getMapInfo']];
			$out['map']['name'] = TmNick::toHtml($currentMapInfo['Name'], 10, true, false, '#999');
			$out['map']['uid'] = $currentMapInfo['UId'];
			$out['map']['author'] = $currentMapInfo['Author'];
			$out['map']['enviro'] = $currentMapInfo['Environnement'];
			
			// MapThumbnail
			$out['map']['thumb'] = null;
			if( isset($queriesData['GetMapsDirectory']) && $currentMapInfo['FileName'] != null){
				$mapFileName = $queriesData['GetMapsDirectory'].$currentMapInfo['FileName'];
				if( file_exists($mapFileName) ){
					if(SERVER_VERSION_NAME == 'TmForever'){
						$Gbx = new GBXChallengeFetcher($queriesData['GetMapsDirectory'].$currentMapInfo['FileName'], false, true);
					}
					else{
						$Gbx = new GBXChallMapFetcher(false, true);
						$Gbx->processFile($queriesData['GetMapsDirectory'].$currentMapInfo['FileName']);
					}
					
					$out['map']['thumb'] = base64_encode($Gbx->thumbnail);
				}
			}
			
			// CurrentCallVote
			$out['map']['callvote']['login'] = $queriesData['GetCurrentCallVote']['CallerLogin'];
			$out['map']['callvote']['cmdname'] = $queriesData['GetCurrentCallVote']['CmdName'];
			$out['map']['callvote']['cmdparam'] = $queriesData['GetCurrentCallVote']['CmdParam'];
			
			// TeamScores (mode team)
			if( self::isGameMode('Team', $out['srv']['gameModeId']) ){
				$client->query('GetCurrentRanking', 2, 0);
				$currentRanking = $client->getResponse();
				$out['map']['scores']['blue'] = $currentRanking[0]['Score'];
				$out['map']['scores']['red'] = $currentRanking[1]['Score'];
			}
			
			// ServerName
			$out['srv']['name'] = TmNick::toHtml($queriesData['GetServerName'], 10, true, false, '#999');
			
			// Status
			$out['srv']['status'] = $queriesData['GetStatus']['Name'];
			
			// NetworkStats
			if( isset($queriesData['GetNetworkStats']) && count($queriesData['GetNetworkStats']) > 0 ){
				$networkStats = $queriesData['GetNetworkStats'];
				$out['net']['uptime'] = TimeDate::secToStringTime($networkStats['Uptime'], false);
				$out['net']['nbrconnection'] = $networkStats['NbrConnection'];
				$out['net']['meanconnectiontime'] = TimeDate::secToStringTime($networkStats['MeanConnectionTime'], false);
				$out['net']['meannbrplayer'] = $networkStats['MeanNbrPlayer'];
				$out['net']['recvnetrate'] = $networkStats['RecvNetRate'];
				$out['net']['sendnetrate'] = $networkStats['SendNetRate'];
				$out['net']['totalreceivingsize'] = $networkStats['TotalReceivingSize'];
				$out['net']['totalsendingsize'] = $networkStats['TotalSendingSize'];
			}
			else{
				$out['net'] = null;
			}
			
			// PlayerList
			$playerList = $queriesData['GetPlayerList'];
			$countPlayerList = count($playerList);
			
			if( $countPlayerList > 0 ){
				$client->query('GetCurrentRanking', AdminServConfig::LIMIT_PLAYERS_LIST, 0);
				$rankingList = $client->GetResponse();
				$rankingKeyList = array(
					'Rank',
					'BestTime',
					'BestCheckpoints',
					'Score',
					'NbrLapsFinished',
					'LadderScore'
				);
				$i = 0;
				foreach($playerList as $player){
					// Nickname et Playerlogin
					$out['ply'][$i]['NickName'] = TmNick::toHtml(htmlspecialchars($player['NickName'], ENT_QUOTES, 'UTF-8'), 10, true);
					$out['ply'][$i]['Login'] = $player['Login'];
					
					// PlayerStatus
					if($player['SpectatorStatus'] != 0){ $playerStatus = Utils::t('Spectator'); }else{ $playerStatus = Utils::t('Player'); }
					$out['ply'][$i]['PlayerStatus'] = $playerStatus;
					
					// Others
					$out['ply'][$i]['PlayerId'] = $player['PlayerId'];
					$out['ply'][$i]['TeamId'] = $player['TeamId'];
					if($player['TeamId'] == 0){ $teamName = Utils::t('Blue'); }else if($player['TeamId'] == 1){ $teamName = Utils::t('Red'); }else{ $teamName = Utils::t('Spectator'); }
					$out['ply'][$i]['TeamName'] = $teamName;
					$out['ply'][$i]['SpectatorStatus'] = $player['SpectatorStatus'];
					
					// Rankings
					foreach($rankingKeyList as $rankName){
						if( isset($rankingList[$i][$rankName]) ){
							$out['ply'][$i][$rankName] = $rankingList[$i][$rankName];
						}
					}
					if($player['LadderRanking'] == -1){
						$player['LadderRanking'] = Utils::t('Not rated');
					}
					$out['ply'][$i]['LadderRanking'] = $player['LadderRanking'];
					$i++;
				}
			}
			else{
				$out['ply'] = Utils::t('No player');
			}
			
			
			// Nombre de joueurs
			if($countPlayerList > 1){
				$out['nbp'] = $countPlayerList.' '.Utils::t('players');
			}
			else{
				$out['nbp'] = $countPlayerList.' '.Utils::t('player');
			}
			
			
			// TRI
			if( is_array($out['ply']) && count($out['ply']) > 0 ){
				// Si on est en mode équipe, on tri par équipe
				if($displayTeamMode){
					uasort($out['ply'], 'AdminServSort::sortByRank');
					uasort($out['ply'], 'AdminServSort::sortByTeam');
				}
				else{
					switch($sortBy){
						case 'nickname':
							uasort($out['ply'], 'AdminServSort::sortByNickName');
							break;
						case 'ladder':
							uasort($out['ply'], 'AdminServSort::sortByLadderRanking');
							break;
						case 'login':
							uasort($out['ply'], 'AdminServSort::sortByLogin');
							break;
						case 'status':
							uasort($out['ply'], 'AdminServSort::sortByStatus');
							break;
						default:
							uasort($out['ply'], 'AdminServSort::sortByRank');
							uasort($out['ply'], 'AdminServSort::sortByStatus');
					}
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* @deprecated
	* Récupère le login du serveur principal à partir d'un serveur Relai
	*
	* @return string
	*/
	public static function getMainServerLoginFromRelay(){
		global $client;
		$out = null;
		
		if( AdminServAdminLevel::isType('Admin') ){
			if( !$client->query('GameDataDirectory') ){
				self::error();
			}
			else{
				// Récupération du login
				$out = null;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le nombre de joueurs présent sur le serveur
	*
	* @param bool $spectator -> Inclus les spectateurs dans le calcul
	* @return int
	*/
	public static function getNbPlayers($spectator = true){
		global $client;
		$out = 0;
		
		if( !$client->query('GetPlayerList', AdminServConfig::LIMIT_PLAYERS_LIST, 0, 1) ){
			self::error();
		}
		else{
			$playerList = $client->getResponse();
			$countPlayerList = count($playerList);
			
			if($spectator){
				$out = $countPlayerList;
			}
			else{
				if($countPlayerList > 0){
					foreach($playerList as $player){
						if($player['SpectatorStatus'] == 0){
							$out++;
						}
					}
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Administration rapide
	*
	* @param  string $cmd -> Le nom de la commande (PrevMap, RestartMap, NextMap ou ForceEndRound)
	* @return true si réussi, sinon un message d'erreur
	*/
	public static function speedAdmin($cmd){
		global $client;
		$out = true;
		
		// Méthode en fonction du jeu
		if($cmd != 'ForceEndRound'){
			if(SERVER_VERSION_NAME == 'TmForever'){
				$queries = array(
					'restartMap' => 'RestartChallenge',
					'nextMap' => 'NextChallenge',
					'getCurrentMapIndex' => 'GetCurrentChallengeIndex',
					'setNextMapIndex' => 'SetNextChallengeIndex'
				);
			}else{
				$queries = array(
					'restartMap' => 'RestartMap',
					'nextMap' => 'NextMap',
					'getCurrentMapIndex' => 'GetCurrentMapIndex',
					'setNextMapIndex' => 'SetNextMapIndex'
				);
			}
		}
		
		// Si c'est le mode Cup
		$isCupMode = false;
		if( self::isGameMode('Cup') ){
			$isCupMode = true;
		}
		
		// Suivant la commande demandée
		switch($cmd){
			case 'PrevMap':
				if( !$client->query($queries['getCurrentMapIndex']) ){
					$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
				}
				else{
					$currentMapIndex = $client->getResponse();
					if($currentMapIndex === 0){
						$nbMaps = self::getNbMaps( self::getMapList() );
						$prevMapIndex =  $nbMaps['nbm']['count'] - 1;
					}
					else{
						$prevMapIndex = $currentMapIndex - 1;
					}
					
					if( !$client->query($queries['setNextMapIndex'], $prevMapIndex) ){
						$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
					}
					else{
						self::speedAdmin('NextMap');
					}
				}
				break;
			case 'RestartMap':
				if( !$client->query($queries['restartMap'], $isCupMode) ){
					$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
				}
				break;
			case 'NextMap':
				if( !$client->query($queries['nextMap'], $isCupMode) ){
					$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
				}
				break;
			case 'ForceEndRound':
				if($isCupMode){
					if( !$client->query($queries['nextMap']) ){
						$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
					}
				}
				else{
					if( !$client->query('ForceEndRound') ){
						$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
					}
				}
				break;
			default:
				$out = Utils::t('Unknown command');
		}
		
		return $out;
	}
	
	
	/**
	* Récupère les options du serveur
	*
	* @global resource $client -> Le client doit être initialisé
	* @return array
	*/
	public static function getServerOptions(){
		global $client;
		$out = array();
		
		if(SERVER_VERSION_NAME == 'TmForever'){
			$client->addCall('GetServerOptions', array(1) );
		}
		else{
			$client->addCall('GetServerOptions');
		}
		$client->addCall('GetBuddyNotification', array('') );
		if(SERVER_VERSION_NAME == 'ManiaPlanet'){
			$client->addCall('AreHornsDisabled');
		}
		
		if( !$client->multiquery() ){
			self::error();
		}
		else{
			$queriesData = $client->getMultiqueryResponse();
			$out = $queriesData['GetServerOptions'];
			$out['Name'] = stripslashes($out['Name']);
			if($out['Name'] == null){
				$out['Name'] = SERVER_NAME;
			}
			$out['NameHtml'] = TmNick::toHtml($out['Name'], 10, false, false, '#666');
			$out['Comment'] = stripslashes($out['Comment']);
			$out['CommentHtml'] = TmNick::toHtml('$i'.nl2br($out['Comment']), 10, false, false, '#666');
			if($out['CurrentLadderMode'] !== 0){
				$out['CurrentLadderModeName'] = Utils::t('Forced'); 
			}
			else{
				$out['CurrentLadderModeName'] = Utils::t('Inactive');
			}
			if($out['CurrentVehicleNetQuality'] !== 0){
				$out['CurrentVehicleNetQualityName'] = Utils::t('High');
			}
			else{
				$out['CurrentVehicleNetQualityName'] = Utils::t('Fast');
			}
			$out['BuddyNotification'] = $queriesData['GetBuddyNotification'];
			if(SERVER_VERSION_NAME == 'ManiaPlanet'){
				$out['DisableHorns'] = $queriesData['AreHornsDisabled'];
			}
			else{
				$out['DisableHorns'] = null;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Retourne la structure pour l'enregistrement des options du serveur
	*
	* @return array
	*/
	public static function getServerOptionsStruct(){
		if(SERVER_VERSION_NAME == 'TmForever'){
			$keys = array(
				'allowMapDownload' => 'AllowChallengeDownload'
			);
		}
		else{
			$keys = array(
				'allowMapDownload' => 'AllowMapDownload'
			);
		}
		
		$out = array(
			'Name' => stripslashes($_POST['Name']),
			'Comment' => stripslashes($_POST['Comment']),
			'Password' => trim($_POST['Password']),
			'PasswordForSpectator' => trim($_POST['PasswordForSpectator']),
			'NextMaxPlayers' => intval($_POST['NextMaxPlayers']),
			'NextMaxSpectators' => intval($_POST['NextMaxSpectators']),
			'IsP2PUpload' => array_key_exists('IsP2PUpload', $_POST),
			'IsP2PDownload' => array_key_exists('IsP2PDownload', $_POST),
			'NextLadderMode' => intval($_POST['NextLadderMode']),
			'NextVehicleNetQuality' => intval($_POST['NextVehicleNetQuality']),
			'NextCallVoteTimeOut' => TimeDate::secToMillisec( intval($_POST['NextCallVoteTimeOut']) ),
			'CallVoteRatio' => (double)$_POST['CallVoteRatio'],
			$keys['allowMapDownload'] => array_key_exists('AllowMapDownload', $_POST),
			'AutoSaveReplays' => array_key_exists('AutoSaveReplays', $_POST),
			'HideServer' => (int)array_key_exists('HideServer', $_POST),
			'BuddyNotification' => array_key_exists('BuddyNotification', $_POST),
			
		);
		if(SERVER_VERSION_NAME == 'ManiaPlanet'){
			$out['ClientInputsMaxLatency'] = ($_POST['ClientInputsMaxLatency'] == 'more') ? $_POST['ClientInputsMaxLatencyValue'] : $_POST['ClientInputsMaxLatency'];
			$out['DisableHorns'] = array_key_exists('DisableHorns', $_POST);
		}
		
		return $out;
	}
	
	
	/**
	* Enregistre les options du serveur
	*
	* @param array $struct -> Structure contenant les champs demandés par la méthode SetServerOptions()
	*/
	public static function setServerOptions($struct){
		global $client;
		$out = false;
		
		if( !$client->query('SetServerOptions', $struct) ){
			self::error();
		}
		else{
			$client->addCall('SetHideServer', array($struct['HideServer']) );
			$client->addCall('SetBuddyNotification', array('', $struct['BuddyNotification']) );
			if(SERVER_VERSION_NAME == 'ManiaPlanet'){
				$client->addCall('SetClientInputsMaxLatency', array($struct['ClientInputsMaxLatency']) );
				$client->addCall('DisableHorns', array($struct['DisableHorns']) );
			}
			
			if( !$client->multiquery() ){
				self::error();
			}
			else{
				$out = true;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Exporte les options du serveur dans un fichier
	*
	* @param  string $file -> Chemin du fichier à écrire
	* @param  array  $data -> Structure des options du serveur à écrire
	* @return bool
	*/
	public static function exportServerOptions($file, $data){
		$out = false;
		
		$xml = new DOMDocument('1.0', 'utf-8');
		$xml->formatOutput = true;
		$srvopts = $xml->createElement('ServerOptions');
		$srvopts = $xml->appendChild($srvopts);
		foreach($data as $dataField => $dataValue){
			$srvoptsElement = $xml->createElement($dataField, $dataValue);
			$srvoptsElementAttribute = $xml->createAttribute('type');
			$srvoptsElementAttribute->value = Str::getValueType($dataValue);
			$srvoptsElement->appendChild($srvoptsElementAttribute);
			$srvoptsElement = $srvopts->appendChild($srvoptsElement);
		}
		
		if( $result = $xml->save($file) > 0 ){
			$out = true;
			self::info( Utils::t('Server options are exported in').' '.$file);
		}
		else{
			self::error( Utils::t('Unable to export server options') );
		}
		
		return $out;
	}
	
	
	/**
	* Importe les options du serveur depuis un fichier
	*
	* @param  string $file -> Chemin du fichier à lire
	* @return array
	*/
	public static function importServerOptions($file){
		global $client;
		$out = array();
		
		if( file_exists($file) ){
			$dom = new DOMDocument();
			$dom->load($file);
			$srvopts = $dom->childNodes->item(0);
			
			for($i = 0; $i < $srvopts->childNodes->length; $i++){
				$srvoptsElement = $srvopts->childNodes->item($i);
				if($srvoptsElement->nodeName != '#text'){
					$out[$srvoptsElement->nodeName] = Str::setValueType($srvoptsElement->nodeValue, $srvoptsElement->getAttribute('type') );
				}
			}
		}
		else{
			self::error( Utils::t('No such file or file is not readable').' : '.$file);
		}
		
		return $out;
	}
	
	
	/**
	* Récupère les informations de jeux
	*
	* @global resource $client -> Le client doit être initialisé
	* @return array
	*/
	public static function getGameInfos(){
		global $client;
		$out = array();
		
		// Jeu
		if(SERVER_VERSION_NAME == 'TmForever'){
			$queries = array(
				'CupRoundsPerMap' => 'GetCupRoundsPerChallenge',
			);
		}
		else{
			$queries = array(
				'CupRoundsPerMap' => 'GetCupRoundsPerMap',
			);
		}
		
		// Requêtes
		$client->addCall('GetGameInfos');
		$client->addCall('GetAllWarmUpDuration');
		$client->addCall('GetDisableRespawn');
		$client->addCall('GetForceShowAllOpponents');
		if(SERVER_VERSION_NAME == 'ManiaPlanet'){
			$client->addCall('GetScriptName');
		}
		$client->addCall('GetCupPointsLimit');
		$client->addCall($queries['CupRoundsPerMap']);
		$client->addCall('GetCupNbWinners');
		$client->addCall('GetCupWarmUpDuration');
		$client->addCall('GetRoundCustomPoints');
		
		if( !$client->multiquery() ){
			self::error();
		}
		else{
			$queriesData = $client->getMultiqueryResponse();
			
			// Game infos
			$currGamInf = $queriesData['GetGameInfos']['CurrentGameInfos'];
			$nextGamInf = $queriesData['GetGameInfos']['NextGameInfos'];
			
			// Nb de WarmUp
			$currGamInf['AllWarmUpDuration'] = $queriesData['GetAllWarmUpDuration']['CurrentValue'];
			$nextGamInf['AllWarmUpDuration'] = $queriesData['GetAllWarmUpDuration']['NextValue'];
			
			// Respawn
			$currGamInf['DisableRespawn'] = $queriesData['GetDisableRespawn']['CurrentValue'];
			$nextGamInf['DisableRespawn'] = $queriesData['GetDisableRespawn']['NextValue'];
			
			// ForceShowAllOpponents
			$currGamInf['ForceShowAllOpponents'] = $queriesData['GetForceShowAllOpponents']['CurrentValue'];
			$nextGamInf['ForceShowAllOpponents'] = $queriesData['GetForceShowAllOpponents']['NextValue'];
			
			// ScriptName
			$currGamInf['ScriptName'] = null;
			$nextGamInf['ScriptName'] = null;
			if(SERVER_VERSION_NAME == 'ManiaPlanet'){
				$currGamInf['ScriptName'] = $queriesData['GetScriptName']['CurrentValue'];
				$nextGamInf['ScriptName'] = $queriesData['GetScriptName']['NextValue'];
			}
			
			// Mode Cup
			$currGamInf['CupPointsLimit'] = $queriesData['GetCupPointsLimit']['CurrentValue'];
			$nextGamInf['CupPointsLimit'] = $queriesData['GetCupPointsLimit']['NextValue'];
			$currGamInf['CupRoundsPerMap'] = $queriesData[$queries['CupRoundsPerMap']]['CurrentValue'];
			$nextGamInf['CupRoundsPerMap'] = $queriesData[$queries['CupRoundsPerMap']]['NextValue'];
			$currGamInf['CupNbWinners'] = $queriesData['GetCupNbWinners']['CurrentValue'];
			$nextGamInf['CupNbWinners'] = $queriesData['GetCupNbWinners']['NextValue'];
			$currGamInf['CupWarmUpDuration'] = $queriesData['GetCupWarmUpDuration']['CurrentValue'];
			$nextGamInf['CupWarmUpDuration'] = $queriesData['GetCupWarmUpDuration']['NextValue'];
			
			// RoundCustomPoints
			$RoundCustomPoints = implode(',', $queriesData['GetRoundCustomPoints']);
			$currGamInf['RoundCustomPoints'] = $RoundCustomPoints;
			$nextGamInf['RoundCustomPoints'] = $RoundCustomPoints;
			
			// Retour
			$out['curr'] = $currGamInf;
			$out['next'] = $nextGamInf;
		}
		
		return $out;
	}
	
	
	/**
	* Retourne la structure pour l'enregistrement des informations de jeu
	*
	* @return array
	*/
	public static function getGameInfosStructFromPOST(){
		if($_POST['NextFinishTimeoutValue'] < 2){
			if($_POST['NextFinishTimeout'] == 0){ $FinishTimeout = 0; }
			else if($_POST['NextFinishTimeout'] == 1){ $FinishTimeout = 1; }
		}
		else{ $FinishTimeout = TimeDate::secToMillisec( intval($_POST['NextFinishTimeoutValue']) ); }
		if( array_key_exists('NextDisableRespawn', $_POST) === true ){ $DisableRespawn = false; }
		else{ $DisableRespawn = true; }
		if($_POST['NextForceShowAllOpponentsValue'] < 2){
			if($_POST['NextForceShowAllOpponents'] == 0){ $NextForceShowAllOpponents = 0; }
			else if($_POST['NextForceShowAllOpponents'] == 1){ $NextForceShowAllOpponents = 1; }
		}
		else{ $NextForceShowAllOpponents = intval($_POST['NextForceShowAllOpponentsValue']); }
		
		$out = array(
			'GameMode' => intval($_POST['NextGameMode']),
			'ChatTime' => TimeDate::secToMillisec( intval($_POST['NextChatTime'] - 8) ),
			'RoundsPointsLimit' => intval($_POST['NextRoundsPointsLimit']),
			'RoundCustomPoints' => intval($_POST['NextRoundCustomPoints']),
			'RoundsUseNewRules' => array_key_exists('NextRoundsUseNewRules', $_POST),
			'RoundsForcedLaps' => intval($_POST['NextRoundsForcedLaps']),
			'RoundsPointsLimitNewRules' => intval($_POST['NextRoundsPointsLimit']),
			'TimeAttackLimit' => TimeDate::secToMillisec( intval($_POST['NextTimeAttackLimit']) ),
			'TimeAttackSynchStartPeriod' => TimeDate::secToMillisec( intval($_POST['NextTimeAttackSynchStartPeriod']) ),
			'TeamPointsLimit' => intval($_POST['NextTeamPointsLimit']),
			'TeamMaxPoints' => intval($_POST['NextTeamMaxPoints']),
			'TeamUseNewRules' => array_key_exists('NextTeamUseNewRules', $_POST),
			'TeamPointsLimitNewRules' => intval($_POST['NextTeamPointsLimit']),
			'LapsNbLaps' => intval($_POST['NextLapsNbLaps']),
			'LapsTimeLimit' => TimeDate::secToMillisec( intval($_POST['NextLapsTimeLimit']) ),
			'FinishTimeout' => $FinishTimeout,
			'AllWarmUpDuration' => intval($_POST['NextAllWarmUpDuration']),
			'DisableRespawn' => $DisableRespawn,
			'ForceShowAllOpponents' => $NextForceShowAllOpponents,
			'CupPointsLimit' => intval($_POST['NextCupPointsLimit']),
			'CupRoundsPerMap' => intval($_POST['NextCupRoundsPerMap']),
			'CupNbWinners' => intval($_POST['NextCupNbWinners']),
			'CupWarmUpDuration' => intval($_POST['NextCupWarmUpDuration'])
		);
		if(SERVER_VERSION_NAME != 'TmForever'){
			$out += array('ScriptName' => $_POST['NextScriptName']);
		}
		
		return $out;
	}
	
	
	/**
	* Enregistre les infos sur les équipes
	* @param array $team1 -> (assoc) array(name, color (0 to 1), country)
	* @param array $team2
	* @return bool
	*/
	public static function setTeamInfo($team1, $team2){
		global $client;
		$out = false;
		
		if( !$client->query('SetTeamInfo', 'Unused', 0., 'World', $team1['name'], (double)$team1['color'], $team1['country'], $team2['name'], (double)$team2['color'], $team2['country']) ){
			AdminServ::error();
		}
		else{
			$_SESSION['adminserv']['teaminfo'] = array(
				'team1' => $team1,
				'team2' => $team2
			);
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Add chat line on server
	*
	* @param string $message       -> Text message
	* @param string $nickname      -> Nickname
	* @param string $color         -> Text color
	* @param string $destination   -> Message destination: server or player login
	* @param string $showAdminText -> Display "Admin" before the message
	* @return bool or text error
	*/
	public static function addChatServerLine($message, $nickname = null, $color = '$ff0', $destination = 'server', $showAdminText = false){
		global $client;
		$out = false;
		$admin = null;
		Utils::addCookieData('adminserv_user', array(AdminServUI::theme(), AdminServUI::lang(), $nickname, $color), AdminServConfig::COOKIE_EXPIRE);
		
		if($showAdminText){
			$admin = '$fffAdmin:';
		}
		
		if($nickname){
			$nickname = '$g$ff0'.TmNick::stripNadeoCode($nickname, array('$s') );
		}
		
		$nickname = '$s$ff0['.$admin.$nickname.'$z$s$ff0]$z';
		$message = $nickname.' '.$color.$message;
		$_SESSION['adminserv']['chat_dst'] = $destination;
		
		if($destination === 'server'){
			if( !$client->query('ChatSendServerMessage', $message) ){
				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
			}
			else{
				$out = true;
			}
		}
		else{
			if( !$client->query('ChatSendServerMessageToLogin', $message, $destination) ){
				$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
			}
			else{
				$out = true;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère les lignes du chat serveur
	*
	* @param bool $hideServerLines -> Masquer les lignes provenant d'un gestionnaire de serveur
	* @return string
	*/
	public static function getChatServerLines($hideServerLines = false){
		global $client;
		$out = null;
		
		if( !$client->query('GetChatLines') ){
			$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
		}
		else{
			$langCode = AdminServUI::lang();
			$chatLines = $client->getResponse();
			
			foreach($chatLines as $line){
				if( self::isServerLine($line) ){
					if($hideServerLines){
						unset($line);
					}
					else{
						$tradLines = array(
							'$99FThis round is a draw.',
							'$99FThe $<$00FBlue team$> wins this round.',
							'$99FThe $<$F00Red team$> wins this round.'
						);
						if( in_array($line, $tradLines) ){
							foreach($tradLines as $tradLine){
								if($line == $tradLine){
									if($langCode == 'en'){
										$line = '$999'.TmNick::toText( TmNick::stripNadeoCode($tradLine, array('$<', '$>')) );
									}
									else{
										$line = '$999'.TmNick::toText( Utils::t($tradLine) );
									}
									break;
								}
							}
						}
						else{
							if( strstr($line, '$fffAdmin:') ){
								$pattern = '$ff0]$z';
								$lineEx = explode($pattern, $line);
								$nickname = $lineEx[0].$pattern;
								$message = TmNick::toText( trim($lineEx[1]) );
								$line = $nickname.' $666'.$message;
							}
							else{
								$line = '$999'.TmNick::toText($line);
							}
						}
					}
				}
				else{
					$lineEx = explode('$>', $line);
					$nickname = TmNick::stripNadeoCode($lineEx[0], array('$s', '[$<') );
					$message = TmNick::toText( substr($lineEx[1], 2) );
					
					$line = '$s$ff0['.$nickname.'$g$ff0]$z $666'.$message;
				}
				
				if( isset($line) ){
					$out .= TmNick::toHtml($line, 10);
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Retourne true si la ligne est générée par le serveur
	*
	* @param string $line -> La ligne de la réponse GetChatLines
	* @return bool
	*/
	public static function isServerLine($line){
		$out = false;
		$char = substr(utf8_decode($line), 0, 1);
		
		if($char == '<' || $char == '/' || substr($line, 0, 4) == '$99F' || substr($line, 0, 12) == 'Invalid time' || $char == '?'){
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le chemin du dossier "Maps"
	*
	* @global resource $client -> Le client doit être initialisé
	* @return string
	*/
	public static function getMapsDirectoryPath(){
		global $client;
		$out = null;
		
		if(SERVER_VERSION_NAME == 'TmForever'){
			$queryName = 'GetTracksDirectory';
		}
		else{
			$queryName = 'GetMapsDirectory';
		}
		
		if( !$client->query($queryName) ){
			$out = '['.$client->getErrorCode().'] '.$client->getErrorMessage();
		}
		else{
			$out = Str::toSlash( $client->getResponse() );
			if( substr($out, -1, 1) != '/'){ $out .= '/'; }
			if(SERVER_MAPS_BASEPATH){
				$out .= Str::toSlash(SERVER_MAPS_BASEPATH);
				if( substr($out, -1, 1) != '/'){ $out .= '/'; }
			}
		}
		
		return $out;
	}
	
	
	/**
	* Retourne un tableau avec le nombre de maps et l'intitulé
	*
	* @param array $array -> La tableau contenant la liste des maps
	* @return array
	*/
	public static function getNbMaps($array){
		$out = array();
		
		if( isset($array['lst']) && is_array($array['lst']) ){
			$countMapsList = count($array['lst']);
		}
		else{
			$countMapsList = 0;
		}
		
		$out['nbm']['count'] = $countMapsList;
		if($countMapsList > 1){
			$out['nbm']['title'] = Utils::t('maps');
		}
		else{
			$out['nbm']['title'] = Utils::t('map');
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la liste des maps sur le serveur
	*
	* @global resource $client -> Le client doit être initialisé
	* @param  string   $sortBy -> Le tri à faire sur la liste
	* @return array
	*/
	public static function getMapList($sortBy = null){
		global $client;
		$out = array();
		
		// Méthodes
		if(SERVER_VERSION_NAME == 'TmForever'){
			$queryName = array(
				'mapList' => 'GetChallengeList',
				'mapIndex' => 'GetCurrentChallengeIndex'
			);
		}
		else{
			$queryName = array(
				'mapList' => 'GetMapList',
				'mapIndex' => 'GetCurrentMapIndex'
			);
		}
		
		// MAPSLIST
		if( !$client->query($queryName['mapList'], AdminServConfig::LIMIT_MAPS_LIST, 0) ){
			$out['error'] = Utils::t('Client not initialized');
		}
		else{
			$mapList = $client->getResponse();
			$countMapList = count($mapList);
			$client->query($queryName['mapIndex']);
			$out['cid'] = $client->getResponse();
			
			if( $countMapList > 0 ){
				$i = 0;
				foreach($mapList as $map){
					// Name
					$name = htmlspecialchars($map['Name'], ENT_QUOTES, 'UTF-8');
					$out['lst'][$i]['Name'] = TmNick::toHtml($name, 10, true);
					
					// Environnement
					$env = $map['Environnement'];
					if($env == 'Speed'){ $env = 'Desert'; }else if($env == 'Alpine'){ $env = 'Snow'; }
					$out['lst'][$i]['Environment'] = $env;
					
					// Autres
					$out['lst'][$i]['UId'] = $map['UId'];
					$out['lst'][$i]['FileName'] = $map['FileName'];
					$out['lst'][$i]['Author'] = $map['Author'];
					$out['lst'][$i]['GoldTime'] = TimeDate::format($map['GoldTime']);
					$out['lst'][$i]['CopperPrice'] = $map['CopperPrice'];
					if(SERVER_VERSION_NAME == 'ManiaPlanet'){
						$out['lst'][$i]['Type']['Name'] = self::formatScriptName($map['MapType']);
						$out['lst'][$i]['Type']['FullName'] = $map['MapType'];
						$out['lst'][$i]['Style']['Name'] = self::formatScriptName($map['MapStyle']);
						$out['lst'][$i]['Style']['FullName'] = $map['MapStyle'];
					}
					$i++;
				}
			}
			
			// Nombre de maps
			$out += self::getNbMaps($out);
			if($out['nbm']['count'] == 0){
				$out['lst'] = Utils::t('No map');
			}
			
			
			// TRI
			if($sortBy != null){
				if( is_array($out['lst']) && count($out['lst']) > 0 ){
					switch($sortBy){
						case 'name':
							uasort($out['lst'], 'AdminServSort::sortByName');
							break;
						case 'env':
							uasort($out['lst'], 'AdminServSort::sortByEnviro');
							break;
						case 'author':
							uasort($out['lst'], 'AdminServSort::sortByAuthor');
							break;
						case 'goldtime':
							uasort($out['lst'], 'AdminServSort::sortByGoldTime');
							break;
						case 'cost':
							uasort($out['lst'], 'AdminServSort::sortByPrice');
							break;
					}
				}
				$out['lst'] = array_values($out['lst']);
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la liste des maps sur le serveur et retourne un champ en particulier
	*
	* @global resource $client -> Le client doit être initialisé
	* @return array
	*/
	public static function getMapListField($field){
		global $client;
		$out = array();
		
		// Méthodes
		if(SERVER_VERSION_NAME == 'TmForever'){
			$queryName = array(
				'mapList' => 'GetChallengeList',
			);
		}
		else{
			$queryName = array(
				'mapList' => 'GetMapList',
			);
		}
		
		// Mapslist
		if( !$client->query($queryName['mapList'], AdminServConfig::LIMIT_MAPS_LIST, 0) ){
			$out['error'] = Utils::t('Client not initialized');
		}
		else{
			$mapList = $client->getResponse();
			$countMapList = count($mapList);
			if( $countMapList > 0 ){
				$i = 0;
				foreach($mapList as $map){
					switch($field){
						case 'Name':
							$name = htmlspecialchars($map['Name'], ENT_QUOTES, 'UTF-8');
							$out[] = TmNick::toHtml($name, 10, true);
							break;
						case 'Environment':
							$env = $map['Environnement'];
							if($env == 'Speed'){ $env = 'Desert'; }else if($env == 'Alpine'){ $env = 'Snow'; }
							$out[] = $env;
							break;
						case 'UId':
							$out[] = $map['UId'];
							break;
						case 'FileName':
							$out[] = $map['FileName'];
							break;
						case 'Author':
							$out[] = $map['Author'];
							break;
						case 'GoldTime':
							$out[] = TimeDate::format($map['GoldTime']);
							break;
						case 'CopperPrice':
							$out[] = $map['CopperPrice'];
							break;
						case 'MapType':
							$out[] = $map['MapType'];
							break;
						case 'MapStyle':
							$out[] = $map['MapStyle'];
							break;
					}
					$i++;
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la liste des maps en local à partir d'un chemin
	*
	* @param string $path   -> Le chemin du dossier à lister
	* @param string $sortBy -> Le tri à faire sur la liste
	* @return array
	*/
	public static function getLocalMapList($directory, $currentPath, $sortBy = null){
		global $client;
		$out = array();
		
		if( is_array($directory) ){
			if( !empty($directory['files']) ){
				// Récupération du cache existant
				$mapsDirectoryPath = self::getMapsDirectoryPath();
				$cache = new AdminServCache();
				$cacheKey = 'mapslist-'.Str::replaceChars($mapsDirectoryPath.$currentPath);
				$cacheMaps = $cache->get($cacheKey);
				
				// Fichiers
				$files = array();
				foreach($directory['files'] as $fileName => $fileValues){
					$dbExt = File::getDoubleExtension($fileName);
					if( in_array($dbExt, AdminServConfig::$MAP_EXTENSION) ){
						$files[$fileName] = $fileValues;
					}
				}
				
				// Suppression du cache en trop
				$cacheOverFiles = array_diff_key($cacheMaps, $files);
				if( !empty($cacheOverFiles) ){
					foreach($cacheOverFiles as $fileName => $fileValues){
						if( isset($cacheMaps[$fileName]) ){
							unset($cacheMaps[$fileName]);
						}
					}
					$cache->set($cacheKey, $cacheMaps);
				}
				
				// Ajout des fichiers manquant dans le cache
				$cacheMissingFiles = array_diff_key($files, $cacheMaps);
				if( !empty($cacheMissingFiles) ){
					// Path
					$path = $mapsDirectoryPath.$currentPath;
					
					// Création du cache
					foreach($cacheMissingFiles as $file => $values){
						// Données
						$processFile = utf8_decode($file);
						if(SERVER_VERSION_NAME == 'TmForever'){
							$Gbx = new GBXChallengeFetcher($path.$processFile);
						}
						else{
							$Gbx = new GBXChallMapFetcher();
							$Gbx->processFile($path.$processFile);
						}
						
						// Name
						$filename = $Gbx->name;
						if($filename == 'read error'){
							$filename = str_ireplace('.'.$dbExt, '', $file);
						}
						$name = htmlspecialchars($filename, ENT_QUOTES, 'UTF-8');
						$out['lst'][$file]['Name'] = TmNick::toHtml($name, 10, true);
						
						// Environnement
						$env = $Gbx->envir;
						if($env == 'read error'){ $env = null; }
						if($env == 'Speed'){ $env = 'Desert'; }else if($env == 'Alpine'){ $env = 'Snow'; }
						$out['lst'][$file]['Environment'] = $env;
						
						// Autres
						$out['lst'][$file]['FileName'] = $currentPath.$file;
						$uid = $Gbx->uid;
						if($uid == 'read error'){ $uid = null; }
						$out['lst'][$file]['UId'] = $uid;
						$author = $Gbx->author;
						if($author == 'read error'){ $author = null; }
						$out['lst'][$file]['Author'] = $author;
						$out['lst'][$file]['Recent'] = $values['recent'];
						
						// MapType
						$mapType = $Gbx->mapType;
						if($mapType == null && $Gbx->typeName != null){
							$mapType = $Gbx->typeName;
						}
						$out['lst'][$file]['Type']['Name'] = self::formatScriptName($mapType);
						$out['lst'][$file]['Type']['FullName'] = $mapType;
					}
					
					// Mise à jour du cache
					if( !empty($cacheMaps) ){
						$out['lst'] = array_merge($cacheMaps, $out['lst']);
					}
					$cache->set($cacheKey, $out['lst']);
				}
				else{
					$out['lst'] = $cacheMaps;
				}
				
				// Maps on server?
				$currentMapsListUId = null;
				if(AdminServConfig::LOCAL_GET_MAPS_ON_SERVER){
					$currentMapsListUId = self::getMapListField('UId');
				}
				foreach($out['lst'] as &$file){
					$file['OnServer'] = false;
					if($currentMapsListUId){
						if( in_array($file['UId'], $currentMapsListUId) ){
							$file['OnServer'] = true;
						}
					}
				}
				
				// Nombre de maps
				$out += self::getNbMaps($out);
				if($out['nbm']['count'] == 0){
					$out['lst'] = Utils::t('No map');
				}
				else{
					// TRIS
					if($sortBy != null){
						switch($sortBy){
							case 'filename':
								uasort($out['lst'], 'AdminServSort::sortByFileName');
								break;
							case 'name':
								uasort($out['lst'], 'AdminServSort::sortByName');
								break;
							case 'env':
								uasort($out['lst'], 'AdminServSort::sortByEnviro');
								break;
							case 'type':
								uasort($out['lst'], 'AdminServSort::sortByType');
								break;
							case 'author':
								uasort($out['lst'], 'AdminServSort::sortByAuthor');
								break;
						}
					}
				}
			}
			else{
				$out += self::getNbMaps($out);
				$out['lst'] = Utils::t('No map');
			}
		}
		// Retour des erreurs de la méthode read
		else{
			$out = $directory;
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la liste des matchsettings en local à partir d'un chemin
	*
	* @param string $path -> Le chemin du dossier à lister
	* @return array
	*/
	public static function getLocalMatchSettingList($directory, $currentPath){
		$out = array();
		
		if( is_array($directory) ){
			if( !empty($directory['files']) ){
				$mapsDirectoryPath = self::getMapsDirectoryPath();
				
				foreach($directory['files'] as $file => $values){
					if( in_array(File::getExtension($file), AdminServConfig::$MATCHSET_EXTENSION) ){
						$matchsetData = self::getMatchSettingsData($mapsDirectoryPath.$currentPath.$file, array('maps'));
						$matchsetNbmCount = 0;
						if( isset($matchsetData['maps']) ){
							$matchsetNbmCount = count($matchsetData['maps']);
						}
						$matchsetNbmTitle = ($matchsetNbmCount > 1) ? Utils::t('maps') : Utils::t('map');
						
						$out['lst'][$file]['Name'] = substr($file, 0, -4);
						$out['lst'][$file]['FileName'] = $currentPath.$file;
						$out['lst'][$file]['Nbm'] = $matchsetNbmCount.' '.$matchsetNbmTitle;
						$out['lst'][$file]['Mtime'] = $values['mtime'];
						$out['lst'][$file]['Recent'] = $values['recent'];
					}
				}
			}
			
			// Nombre de matchsettings
			if( isset($out['lst']) && is_array($out['lst']) ){
				$out['nbm']['count'] = count($out['lst']);
				$out['nbm']['title'] = ($out['nbm']['count'] > 1) ? Utils::t('matchsettings') : Utils::t('matchsetting');
			}
			else{
				$out['nbm']['count'] = 0;
				$out['nbm']['title'] = Utils::t('matchsetting');
			}
			if($out['nbm']['count'] == 0){
				$out['lst'] = Utils::t('No matchsetting');
			}
		}
		else{
			// Retour des erreurs de la méthode read
			$out = $directory;
		}
		
		return $out;
	}
	
	
	/**
	* Enregistre la sélection du MatchSettings en session
	*
	* @param array $maps -> Le tableau de maps à ajouter à la sélection
	*/
	public static function saveMatchSettingSelection($maps = array() ){
		// Liste des maps
		$out = array();
		if( isset($_SESSION['adminserv']['matchset_maps_selected']) ){
			$mapsSelected = $_SESSION['adminserv']['matchset_maps_selected'];
			if( isset($mapsSelected['lst']) && is_array($mapsSelected['lst']) && count($mapsSelected['lst']) > 0 ){
				foreach($mapsSelected['lst'] as $id => $values){
					$out['lst'][] = $values;
				}
			}
		}
		if( isset($maps['lst']) && is_array($maps['lst']) && count($maps['lst']) > 0 ){
			foreach($maps['lst'] as $id => $values){
				$out['lst'][] = $values;
			}
		}
		if( isset($out['lst']) && count($out['lst']) > 0 ){
			$out['lst'] = array_unique($out['lst'], SORT_REGULAR);
		}
		
		// Nombre de maps
		$out += self::getNbMaps($out);
		if($out['nbm']['count'] == 0){
			$out['lst'] = Utils::t('No map');
		}
		
		// Mise à jour de la session
		$_SESSION['adminserv']['matchset_maps_selected'] = $out;
	}
	
	
	/**
	* Enregistre un MatchSettings
	*
	* @param string $filename -> L'url du dossier dans lequel le MatchSettings sera crée
	* @param array  $struct   -> La structure du MatchSettings avec ses données
	* $struct = Array
	* (
	*  [gameinfos] => Array
	*   (
	*    [game_mode] => 0
	*    etc...
	*   )
	*  [hotseat] => Array()
	*  [filter] => Array()
	*  [startindex] => 1
	*  [map] => Array
	*   (
	*    [8bDoQMwzUllV0D9eu7hSth3rQs6] => name.Map.Gbx
	*    etc...
	*   )
	* )
	* @return true si réussi, sinon une erreur
	*/
	public static function saveMatchSettings($filename, $struct){
		$out = false;
		
		if(SERVER_VERSION_NAME == 'TmForever'){
			$mapField = 'challenge';
		}
		else{
			$mapField = 'map';
		}
		
		$xml = new DOMDocument('1.0', 'utf-8');
		$xml->formatOutput = true;
		$playlist = $xml->createElement('playlist');
		$playlist = $xml->appendChild($playlist);
		
		// GameInfos, Hotseat, Filter
		$structFields = array(
			'gameinfos',
			'hotseat',
			'filter'
		);
		foreach($structFields as $strucField){
			if( isset($struct[$strucField]) && !empty($struct[$strucField]) ){
				$node = $xml->createElement($strucField);
				$node = $playlist->appendChild($node);
				foreach($struct[$strucField] as $field => $value){
					$childNode = $xml->createElement($field, $value);
					$childNode = $node->appendChild($childNode);
				}
			}
		}
		
		// Script settings
		if( isset($struct['scriptsettings']) && !empty($struct['scriptsettings']) ){
			$scriptsettings = $xml->createElement('mode_script_settings');
			$scriptsettings = $playlist->appendChild($scriptsettings);
			foreach($struct['scriptsettings'] as $settingParams){
				$setting = $xml->createElement('setting');
				$setting = $scriptsettings->appendChild($setting);
				if( !empty($settingParams) ){
					foreach($settingParams as $paramKey => $paramValue){
						$param = $xml->createAttribute($paramKey);
						$param->value = $paramValue;
						$setting->appendChild($param);
					}
				}
			}
		}
		
		// Maps
		$startindex = $xml->createElement('startindex', $struct['startindex']);
		$startindex = $playlist->appendChild($startindex);
		if( isset($struct[$mapField]) && !empty($struct[$mapField]) ){
			foreach($struct[$mapField] as $dataIdent => $dataFile){
				$map = $xml->createElement($mapField);
				$map = $playlist->appendChild($map);
				$file = $xml->createElement('file', $dataFile);
				$file = $map->appendChild($file);
				if(SERVER_VERSION_NAME == 'TmForever'){
					$ident = $xml->createElement('ident', $dataIdent);
					$ident = $map->appendChild($ident);
				}
			}
		}
		
		if( !$xml->save($filename) ){
			$out = Utils::t('Saving XML file error');
		}
		else{
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Extrait les données d'un MatchSettings et renvoi un tableau
	*
	* @param string $filename -> L'url du MatchSettings
	* @param array  $list     -> Liste des champs à retourner
	* @return array
	*/
	public static function getMatchSettingsData($filename, $list = array('gameinfos', 'hotseat', 'filter', 'scriptsettings', 'maps') ){
		$out = array();
		$xml = null;
		
		if( file_exists($filename) ){
			$xml = new DOMDocument('1.0', 'utf-8');
			$xml->load($filename);
		}
		
		if($xml){
			// Gameinfos
			if( in_array('gameinfos', $list) ){
				$fields = array(
					'game_mode' => 'GameMode',
					'chat_time' => 'ChatTime',
					'finishtimeout' => 'FinishTimeout',
					'allwarmupduration' => 'AllWarmUpDuration',
					'disablerespawn' => 'DisableRespawn',
					'forceshowallopponents' => 'ForceShowAllOpponents',
					'rounds_pointslimit' => 'RoundsPointsLimit',
					'rounds_custom_points' => 'RoundCustomPoints',
					'rounds_usenewrules' => 'RoundsUseNewRules',
					'rounds_forcedlaps' => 'RoundsForcedLaps',
					'rounds_pointslimitnewrules' => 'RoundsPointsLimitNewRules',
					'team_pointslimit' => 'TeamPointsLimit',
					'team_maxpoints' => 'TeamMaxPoints',
					'team_usenewrules' => 'TeamUseNewRules',
					'team_pointslimitnewrules' => 'TeamPointsLimitNewRules',
					'timeattack_limit' => 'TimeAttackLimit',
					'timeattack_synchstartperiod' => 'TimeAttackSynchStartPeriod',
					'laps_nblaps' => 'LapsNbLaps',
					'laps_timelimit' => 'LapsTimeLimit',
					'cup_pointslimit' => 'CupPointsLimit',
					'cup_roundsperchallenge' => 'CupRoundsPerMap',
					'cup_nbwinners' => 'CupNbWinners',
					'cup_warmupduration' => 'CupWarmUpDuration',
				);
				if(SERVER_VERSION_NAME != 'TmForever'){
					$fields['script_name'] = 'ScriptName';
				}
				
				foreach($fields as $fieldXML => $fieldName){
					$fieldList = $xml->getElementsByTagName($fieldXML);
					if($fieldList->length > 0){
						$out['gameinfos'][$fieldName] = $fieldList->item(0)->nodeValue;
					}
				}
			}
			
			// Hotseat
			if( in_array('hotseat', $list) ){
				$fields = array(
					'game_mode' => 'GameMode',
					'time_limit' => 'TimeLimit',
					'rounds_count' => 'RoundsCount',
				);
				
				foreach($fields as $fieldXML => $fieldName){
					$fieldList = $xml->getElementsByTagName($fieldXML);
					if($fieldList->length > 0){
						$out['hotseat'][$fieldName] = $fieldList->item(0)->nodeValue;
					}
				}
			}
			
			// Filter
			if( in_array('filter', $list) ){
				$fields = array(
					'is_lan' => 'IsLan',
					'is_internet' => 'IsInternet',
					'is_solo' => 'IsSolo',
					'is_hotseat' => 'IsHotseat',
					'sort_index' => 'SortIndex',
					'random_map_order' => 'RandomMapOrder',
					'force_default_gamemode' => 'ForceDefaultGameMode',
				);
				
				foreach($fields as $fieldXML => $fieldName){
					$fieldList = $xml->getElementsByTagName($fieldXML);
					if($fieldList->length > 0){
						$out['filter'][$fieldName] = $fieldList->item(0)->nodeValue;
					}
				}
			}
			
			// Script Settings
			if( in_array('scriptsettings', $list) ){
				$scriptsettings = $xml->getElementsByTagName('setting');
				if($scriptsettings->length > 0){
					$i = 0;
					foreach($scriptsettings as $setting){
						if( $setting->hasAttributes() ){
							foreach($setting->attributes as $attName => $attrNode) {
								$out['scriptsettings'][$i][$attName] = $attrNode->value;
							}
						}
						$i++;
					}
				}
			}
			
			// Maps
			if( in_array('maps', $list) ){
				$fieldStartIndex = $xml->getElementsByTagName('startindex');
				if($fieldStartIndex->length > 0){
					$out['StartIndex'] = $fieldStartIndex->item(0)->nodeValue;
				}
				
				$mapsField = (SERVER_VERSION_NAME == 'TmForever') ? 'challenge' : 'map';
				$fieldMaps = $xml->getElementsByTagName($mapsField);
				
				foreach($fieldMaps as $map){
					$ident = null;
					$fieldIdent = $map->getElementsByTagName('ident');
					if($fieldIdent->length > 0){
						$ident = $fieldIdent->item(0)->nodeValue;
					}
					$file = null;
					$fieldFile = $map->getElementsByTagName('file');
					if($fieldFile->length > 0){
						$file = $fieldFile->item(0)->nodeValue;
					}
					
					if($ident){
						$out['maps'][$ident] = $file;
					}
					else{
						$out['maps'][] = $file;
					}
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Met en forme les données des maps à partir d'un MatchSettings
	*
	* @global resource $client -> Le client doit être initialisé
	* @param  array    $maps   -> Le tableau extrait du matchsettings : assoc array(ident => filename)
	* @return array
	*/
	public static function getMapListFromMatchSetting($maps){
		global $client;
		$out = array();
		$path = self::getMapsDirectoryPath();
		$countMapList = count($maps);
		
		if($countMapList > 0){
			$i = 0;
			foreach($maps as $mapUId => $mapFileName){
				if( in_array(File::getDoubleExtension($mapFileName), AdminServConfig::$MAP_EXTENSION) ){
					// Données
					if(SERVER_VERSION_NAME == 'TmForever'){
						$Gbx = new GBXChallengeFetcher($path.Str::toSlash($mapFileName));
					}
					else{
						$Gbx = new GBXChallMapFetcher();
						$Gbx->processFile($path.Str::toSlash($mapFileName));
					}
					
					// Name
					$name = htmlspecialchars($Gbx->name, ENT_QUOTES, 'UTF-8');
					$out['lst'][$i]['Name'] = TmNick::toHtml($name, 10, true);
					
					// Environnement
					$env = $Gbx->envir;
					if($env == 'Speed'){ $env = 'Desert'; }else if($env == 'Alpine'){ $env = 'Snow'; }
					$out['lst'][$i]['Environment'] = $env;
					
					// Autres
					$out['lst'][$i]['FileName'] = $mapFileName;
					$out['lst'][$i]['UId'] = $Gbx->uid;
					$out['lst'][$i]['Author'] = $Gbx->author;
					$i++;
				}
			}
		}
		
		// Nombre de maps
		$out += self::getNbMaps($out);
		if($out['nbm']['count'] == 0){
			$out['lst'] = Utils::t('No map');
		}
		
		return $out;
	}
	
	
	/**
	* Extrait les données d'une playlist (blacklist ou guestlist)
	*
	* @param string $filename -> L'url de la playlist
	* @return array
	*/
	public static function getPlaylistData($filename){
		$out = array();
		
		$xml = null;
		if( file_exists($filename) ){
			$xml = new DOMDocument('1.0', 'utf-8');
			$xml->load($filename);
		}
		
		if($xml){
			$root = $xml->documentElement;
			$out['type'] = $root->nodeName;
			$players = $xml->getElementsByTagName($root->nodeName);
			foreach($players as $player){
				$login = $player->getElementsByTagName('login');
				if($login->length > 0){
					$out['logins'][] = $login->item(0)->nodeValue;
				}
			}
		}
		
		return $out;
	}
}
?>
<?php

/**
* Classe pour la gestion du cache
*/
class AdminServCache {
	private $folder;
	
	/**
	* Initialisation du cache
	*/
	function __construct(){
		$this->folder = AdminServConfig::$PATH_RESOURCES.'cache/';
		
		if( !file_exists($this->folder) ){
			Folder::create($this->folder);
		}
	}
	
	
	/**
	* Enregistre la valeur dans un fichier
	*
	* @param string $key   -> Clef du cache
	* @param array  $value -> Valeur à enregistrer
	* @return bool
	*/
	public function set($key, $value){
		$out = false;
		$file = $this->folder . $key . '.json';
		$data = json_encode($value);
		
		if( file_exists($file) ){
			if( File::save($file, $data, false) ){
				$out = true;
			}
		}
		else{
			if( File::save($file) ){
				self::set($key, $value);
			}
		}
		
		$error = self::getErrorMsg('set');
		if($error){
			$out = false;
			AdminServ::error($error);
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la valeur depuis un fichier
	*
	* @param string $key -> Clef du cache à récupérer
	* @return array()
	*/
	public function get($key){
		$out = array();
		$file = $this->folder . $key . '.json';
		
		if( file_exists($file) ){
			$data = file_get_contents($file);
			$out = json_decode($data, true);
		}
		
		$error = self::getErrorMsg('get');
		if($error){
			$out = array();
			AdminServ::error($error);
		}
		
		return $out;
	}
	
	
	/**
	* Supprime un fichier de cache
	*
	* @param string $key -> Clef du cache à supprimer
	* @return bool
	*/
	public function delete($key){
		$out = false;
		$file = $this->folder . $key . '.json';
		
		if( file_exists($file) ){
			if( ($result = File::delete($file)) !== true ){
				AdminServ::error($result);
			}
			else{
				$out = true;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le message d'erreur lors de l'encodage/décodage du JSON
	*/
	public static function getErrorMsg($type){
		switch( json_last_error() ){
			case JSON_ERROR_DEPTH:
				return 'CACHE ('.$type.') - Profondeur maximale atteinte';
				break;
			case JSON_ERROR_STATE_MISMATCH:
				return 'CACHE ('.$type.') - Inadéquation des modes ou underflow';
				break;
			case JSON_ERROR_CTRL_CHAR:
				return 'CACHE ('.$type.') - Erreur lors du contrôle des caractères';
				break;
			case JSON_ERROR_SYNTAX:
				return 'CACHE ('.$type.') - Erreur de syntaxe ; JSON malformé';
				break;
			case JSON_ERROR_UTF8:
				return 'CACHE ('.$type.') - Caractères UTF-8 malformés, probablement une erreur d\'encodage';
				break;
		}
	}
}
?>
<?php

/**
* Classe pour la gestion des événements
*/
class AdminServEvent {
	
	/**
	* Retourne les arguments d'AdminServ
	*/
	public static function getArgs(){
		global $args;
		
		if( isset($_GET['p']) ){
			define('USER_PAGE', htmlspecialchars($_GET['p']) );
		}
		else{
			if( isset($_SESSION['adminserv']['check_password']) || isset($_SESSION['adminserv']['get_password']) ){
				define('USER_PAGE', 'servers-online-config');
			}
			else{
				define('USER_PAGE', 'index');
			}
		}
		
		if( isset($_GET['c']) ){ $args['category'] = addslashes( htmlspecialchars($_GET['c']) ); }else{ $args['category'] = null; }
		if( isset($_GET['view']) ){ $args['view'] = addslashes( htmlspecialchars($_GET['view']) ); }else{ $args['view'] = null; }
		if( isset($_GET['i']) ){ $args['index'] = intval($_GET['i']); }else{ $args['index'] = -1; }
		if( isset($_GET['id']) ){ $args['id'] = intval($_GET['id']); }else{ $args['id'] = -1; }
		if( isset($_GET['d']) ){ $args['directory'] = addslashes( urldecode($_GET['d']) ); }else{ $args['directory'] = null; }
		if( isset($_GET['th']) ){ $args['theme'] = addslashes($_GET['th']); }else{ $args['theme'] = null; }
		if( isset($_GET['lg']) ){ $args['lang'] = addslashes($_GET['lg']); }else{ $args['lang'] = null; }
	}
	
	
	/**
	* Permet de changer de serveur
	*/
	public static function switchServer(){
		if( isset($_GET['switch']) && $_GET['switch'] != null ){
			$_SESSION['adminserv']['sid'] = AdminServServerConfig::getServerId($_GET['switch']);
			$_SESSION['adminserv']['name'] = $_GET['switch'];
			unset($_SESSION['adminserv']['teaminfo']);
			Utils::addCookieData('adminserv', array($_SESSION['adminserv']['sid'], Utils::readCookieData('adminserv', 1)), AdminServConfig::COOKIE_EXPIRE);
			
			if(USER_PAGE && USER_PAGE != 'index'){
				Utils::redirection(false, '?p='.USER_PAGE);
			}
			else{
				Utils::redirection();
			}
		}
	}
	
	
	/**
	* Vérifie si on est connecté au serveur
	*/
	public static function isLoggedIn(){
		$out = false;
		
		if( isset($_SESSION['adminserv']['sid']) && isset($_SESSION['adminserv']['password']) && isset($_SESSION['adminserv']['adminlevel']) && !isset($_GET['error']) ){
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Déconnexion
	*/
	public static function logout(){
		if( isset($_GET['error']) || isset($_GET['logout']) ){
			$adminservPath = $_SESSION['adminserv']['path'];
			session_unset();
			session_destroy();
			session_start();
			$_SESSION['adminserv']['path'] = $adminservPath;
			if( isset($_GET['logout']) ){
				Utils::redirection(false);
			}
		}
	}
}
?>
<?php

/**
* Classe pour le traitement des logs AdminServ
*/
class AdminServLogs {
	/**
	* Globales
	*/
	public static $LOGS_PATH = './logs/';
	
	/**
	* Initialise les logs (vérification des droits, création des fichiers)
	* @return bool
	*/
	public static function initialize(){
		$out = false;
		$error = null;
		
		if( in_array(true, AdminServConfig::$LOGS) ){
			if( file_exists(self::$LOGS_PATH) ){
				if( is_writable(self::$LOGS_PATH) ){
					$out = true;
				}
				else{
					$error = Utils::t('The folder "logs" is not writable.');
				}
			}
			else{
				$error = Utils::t('The folder "logs" does not exist.');
			}
		}
		
		if($out){
			if( count(AdminServConfig::$LOGS) > 0 ){
				foreach(AdminServConfig::$LOGS as $file => $activate){
					$path = self::$LOGS_PATH.$file.'.log';
					if($activate && !file_exists($path) ){
						if( File::save($path) !== true ){
							$error = Utils::t('Unable to create log file:').' '.$file.'.';
							$out = false;
							break;
						}
					}
				}
			}
		}
		
		if($error){
			if($_SESSION['error'] != null){
				$_SESSION['error'] .= '<br />'.$error;
			}
			else{
				$_SESSION['error'] = $error;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Ajoute un log au fichier correspondant
	*
	* @param string $type -> Type de log : access, action, etc
	* @param string $str  -> Ligne de log à écrire
	* @return bool
	*/
	public static function add($type, $str){
		$out = false;
		$type = strtolower($type);
		if( defined('USER_PAGE') ){ $userPage = USER_PAGE; }else{ $userPage = 'index'; }
		if( defined('SERVER_NAME') ){ $serverName = '['.utf8_decode(SERVER_NAME).'] '; }else{ $serverName = null; }
		$str = '['.date('d/m/Y H:i:s').'] ['.$_SERVER['REMOTE_ADDR'].'] : '.$serverName.'['.$userPage.'] '.utf8_decode($str)."\n";
		$path = self::$LOGS_PATH.$type.'.log';
		
		if( file_exists($path) ){
			if( File::save($path, utf8_encode($str) ) !== true ){
				$error = Utils::t('Unable to add log in file:').' '.$type.'.';
				if($_SESSION['error'] != null){
					$_SESSION['error'] .= '<br />'.$error;
				}
				else{
					$_SESSION['error'] = $error;
				}
			}
			else{
				$out = true;
			}
		}
		
		return $out;
	}
}
?>
<?php

/**
* Classe pour la gestion des plugins
*/
class AdminServPlugin {
	
	/**
	* Tente de récupérer une config des plugins à partir d'un autre fichier
	*/
	public static function setPluginsList(){
		$otherPluginsList = AdminServConfig::PLUGINS_LIST;
		
		if($otherPluginsList){
			if( file_exists($otherPluginsList) ){
				include_once $otherPluginsList;
				
				if( isset($PLUGINS) ){
					if(AdminServConfig::PLUGINS_LIST_TYPE == 'add'){
						ExtensionConfig::$PLUGINS = array_merge(ExtensionConfig::$PLUGINS, $PLUGINS);
					}
					else{
						ExtensionConfig::$PLUGINS = $PLUGINS;
					}
				}
				else{
					AdminServ::error( Utils::t('Variable "$PLUGINS" not found.') );
				}
			}
			else{
				AdminServ::error( Utils::t('Cannot include another plugins config file.') );
			}
		}
	}
	
	
	/**
	* Détermine s'il y a au moins un plugin disponible
	*
	* @param string $pluginName -> Test un plugin en particulier
	* @return bool
	*/
	public static function hasPlugin($pluginName = null){
		$out = false;
		
		if( class_exists('ExtensionConfig') ){
			if( isset(ExtensionConfig::$PLUGINS) && count(ExtensionConfig::$PLUGINS) > 0 ){
				foreach(ExtensionConfig::$PLUGINS as $plugin){
					$pluginConfig = self::getConfig($plugin);
					if( ($pluginConfig['game'] == SERVER_VERSION_NAME || $pluginConfig['game'] == 'all') && AdminServAdminLevel::isType($pluginConfig['adminlevel']) ){
						if($pluginName){
							if($pluginName == $plugin){
								$out = true;
							}
						}
						else{
							$out = true;
						}
					}
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le plugin courant
	*
	* @return pluginName
	*/
	public static function getCurrent(){
		$out = null;
		
		if( defined('USER_PAGE') ){
			$pageEx = explode('-', USER_PAGE);
			if( count($pageEx) > 0 && isset($pageEx[0]) && $pageEx[0] == 'plugins' ){
				if( isset($pageEx[1]) && $pageEx[1] != 'list' ){
					$out = $pageEx[1];
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la config du plugin grâce au fichier config.ini
	*
	* @param string $pluginName  -> Le nom du dossier plugin
	* @param string $returnField -> Retourner un champ en particulier
	* @return array ou string si le 2ème paramètre est spécifié
	*/
	public static function getConfig($pluginName = null, $returnField = null){
		$out = null;
		if($pluginName === null){
			$pluginName = USER_PLUGIN;
		}
		$path = AdminServConfig::$PATH_PLUGINS .$pluginName.'/config.ini';
		
		if( file_exists($path) ){
			$ini = parse_ini_file($path);
			if($returnField && isset($ini[$returnField]) ){
				$out = $ini[$returnField];
			}
			else{
				$out = $ini;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Retourne une liste html pour le menu des plugins
	*
	* @return html
	*/
	public static function getMenuList(){
		$out = null;
		$pluginsList = array();
		if( count(ExtensionConfig::$PLUGINS) > 0 ){
			foreach(ExtensionConfig::$PLUGINS as $plugin){
				$pluginInfos = self::getConfig($plugin);
				if( ($pluginInfos['game'] == 'all' || $pluginInfos['game'] == SERVER_VERSION_NAME) && AdminServAdminLevel::isType($pluginInfos['adminlevel']) ){
					$pluginsList[$plugin] = $pluginInfos;
				}
			}
		}
		
		if( count($pluginsList) > 0 ){
			$out = '<nav class="vertical-nav">'
				.'<ul>';
					foreach($pluginsList as $plugin => $infos){
						$out .= '<li><a '; if(self::getCurrent() == $plugin){ $out .= 'class="active" '; } $out .= 'href="?p=plugins-'.$plugin.'" title="'.Utils::t('Version').' : '.$infos['version'].'">'.$infos['name'].'</a></li>';
					}
				$out .= '</ul>'
			.'</nav>';
		}
		
		return $out;
	}
	
	
	/**
	* Compte le nombre de plugins installés
	*
	* @return array
	*/
	public static function countPlugins(){
		$out = array();
		$pluginsList = array();
		if( self::hasPlugin() ){
			foreach(ExtensionConfig::$PLUGINS as $plugin){
				$pluginInfos = self::getConfig($plugin);
				if($pluginInfos['game'] == 'all' || $pluginInfos['game'] == SERVER_VERSION_NAME){
					$pluginsList[] = $plugin;
				}
			}
		}
		
		$out['count'] = count($pluginsList);
		if($out['count'] > 1){
			$out['title'] = Utils::t('plugins installed');
		}
		else{
			$out['title'] = Utils::t('plugin installed');
		}
		
		return $out;
	}
	
	
	/**
	* Inclue les fichiers pour le rendu d'un plugin
	*
	* @param string $pluginName -> Le nom du dossier plugin
	* @return html
	*/
	public static function renderPlugin($pluginName = null) {
		global $client, $translate, $args;
		if($pluginName === null){
			$pluginName = USER_PLUGIN;
		}
		
		// Tente de récupérer les plugins d'une autre config
		self::setPluginsList();
		
		// Création du rendu du plugin
		$pluginPath = AdminServConfig::$PATH_PLUGINS .$pluginName.'/';
		$scriptFile = $pluginPath.'script.php';
		$viewFile = $pluginPath.'view.php';
		if (file_exists($scriptFile) && file_exists($viewFile)) {
			// Process
			require_once $scriptFile;
			
			// Terminate client
			if (isset($client) && $client->socket != null) {
				$client->Terminate();
			}
			
			// Header
			AdminServUI::getHeader();
			
			// Content
			echo '<section class="plugins hasMenu">'
				.'<section class="cadre left menu">'
					.self::getMenuList()
				.'</section>'
				
				.'<section class="cadre right">'
					.'<h1>'.self::getConfig($pluginName, 'name').'</h1>';
					require_once $viewFile;
				echo '</section>'
			.'</section>';
			
			// Footer
			AdminServUI::getFooter();
			
			AdminServLogs::add('access', 'Plugin: '.$pluginName);
		}
		else {
			AdminServ::error( Utils::t('Plugin error: script.php or view.php file is missing.') );
			AdminServUI::getHeader();
			AdminServUI::getFooter();
		}
	}
	
	
	/**
	* Récupère le chemin du dossier plugin
	*
	* @param string $pluginName -> Le nom du dossier plugin
	* @return string
	*/
	public static function getPluginPath($pluginName = null){
		$out = null;
		if($pluginName === null){
			$pluginName = USER_PLUGIN;
		}
		$path = AdminServConfig::$PATH_PLUGINS;
		
		if($path && $pluginName){
			$out = $path.$pluginName.'/';
		}
		
		return $out;
	}
}
?>
<?php

/**
* Classe pour la gestion de la configuration serveur
*/
class AdminServServerConfig {
	
	/**
	* Constantes
	*/
	private static $CONFIG_PATH = './config/';
	private static $CONFIG_FILENAME = 'servers.cfg.php';
	private static $CONFIG_START_TEMPLATE = "<?php\nclass ServerConfig {\n\tpublic static \$SERVERS = array(\n\t\t/********************* SERVER CONFIGURATION *********************/\n\t\t\n";
	private static $CONFIG_END_TEMPLATE =  "\t);\n}\n?>";
	
	
	/**
	* Détermine si il y a au moins un serveur disponible
	*
	* @param string $serverName -> Tester si le serveur est présent
	* @return bool
	*/
	public static function hasServer($serverName = null){
		$out = false;
		
		if (class_exists('ServerConfig')) {
			$serverList = ServerConfig::$SERVERS;
			
			if (isset($serverList) && !empty($serverList) && !isset($serverList['new server name']) && !isset($serverList[''])) {
				if ($serverName) {
					foreach ($serverList as $serverListName => $serverListData) {
						if ($serverListName === $serverName) {
							$out = true;
							break;
						}
					}
				}
				else {
					$out = true;
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère les données d'un serveur
	*
	* @param string $serverName -> Le nom du serveur dans la config
	* @return array
	*/
	public static function getServer($serverName){
		$out = null;
		
		if( self::hasServer() ){
			if( isset(ServerConfig::$SERVERS[$serverName]) ){
				$out = ServerConfig::$SERVERS[$serverName];
			}
			else{
				$out = Utils::t('This server does not exist');
			}
		}
		else{
			$out = Utils::t('No server available');
		}
		
		return $out;
	}
	
	
	/**
	* Retourne l'identifiant du serveur dans la config
	*
	* @param  string $serverName -> Le nom du serveur dans la config
	* @return int
	*/
	public static function getServerId($serverName){
		$id = 0;
		$servers = ServerConfig::$SERVERS;
		$countServers = count($servers);
		
		// On cherche la position du serveur à partir de son nom
		if( $countServers > 0 ){
			foreach($servers as $server_name => $server_values){
				if($server_name == $serverName){
					break;
				}
				else{
					$id++;
				}
			}
		}
		
		// Si l'id = le nb total de serveur -> pas trouvé
		if($id == $countServers ){
			return -1;
		}
		else{
			return $id;
		}
	}
	
	
	/**
	* Retourne le nom du serveur dans la config
	*
	* @param  int $serverId -> L'id du serveur dans la config
	* @return string
	*/
	public static function getServerName($serverId){
		$out = null;
		$servers = ServerConfig::$SERVERS;
		
		if( count($servers) > 0 ){
			$i = 0;
			foreach($servers as $serverName => $serverValues){
				if($i == $serverId){
					$out = $serverName;
					break;
				}
				else{
					$i++;
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Créer le template d'un serveur
	*
	* @param array $serverData -> assoc array(name, address, port, mapsbasepath, matchsettings, adminlevel => array(SuperAdmin, Admin, User));
	*/
	public static function getServerTemplate($serverData){
		$out = "\t\t'".$serverData['name']."' => array(\n"
			."\t\t\t'address'\t\t=> '".$serverData['address']."',\n"
			."\t\t\t'port'\t\t\t=> ".$serverData['port'].",\n"
            ."\t\t\t'ds_pw'\t\t\t=> '".$serverData['ds_pw']."',\n"
			."\t\t\t'mapsbasepath'\t=> '".$serverData['mapsbasepath']."',\n"
			."\t\t\t'matchsettings'\t=> '".$serverData['matchsettings']."',\n"
			."\t\t\t'adminlevel'\t=> array(";
			$adminlevelId = 0;
			$adminlevelCount = count($serverData['adminlevel']);
			foreach($serverData['adminlevel'] as $admLvlId => $admLvlValue){
				$out .= "'$admLvlId' => ";
				if( is_array($serverData['adminlevel'][$admLvlId]) ){
					$out .= "'".implode("', '", str_replace(' ', '', $serverData['adminlevel'][$admLvlId]))."'";
				}
				else{
					$out .= "'".$serverData['adminlevel'][$admLvlId]."'";
				}
				
				if($adminlevelId < $adminlevelCount-1){
					$out .= ', ';
				}
				$adminlevelId++;
			}
		$out .= ")\n\t\t),\n";
		
		return $out;
	}
	
	
	/**
	* Sauvegarde le mot de passe de la configuration serveur
	*
	* @param string $filename -> Le chemin vers le fichier de config
	* @param string $password -> Le mot de passe à écrire
	* @return true or text error
	*/
	public static function savePasswordConfig($filename, $password){
		$out = false;
		$seek = null;
		
		// Récupération du pointeur
		$search = 'const PASSWORD = \'';
		$seek = File::getSeekFromString($filename, $search, true);
		
		// Écriture dans le fichier
		if($seek !== null){
			if( ($result = File::saveAtSeek($filename, $password, $seek)) !== true ){
				$out = $result;
			}
			else{
				$out = true;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Sauvegarde le fichier de configuration des serveurs
	*
	* @param array $serverData -> assoc array(name, address, port, matchsettings, adminlevel => array(SuperAdmin, Admin, User));
	* @param int   $editServer -> Id du serveur à éditer
	* @param array $serverList -> Liste des serveurs de la config
	* @return bool or string error
	*/
	public static function saveServerConfig($serverData = array(), $editServer = -1, $serverList = array() ){
		// Liste des serveurs
		if( isset($serverList) && count($serverList) > 0 ){
			$servers = $serverList;
		}else{
			$servers = ServerConfig::$SERVERS;
		}
		
		// Template
		$fileTemplate = self::$CONFIG_START_TEMPLATE;
		$i = 0;
		foreach($servers as $serverName => $serverValues){
			// Édition
			if($i == $editServer && isset($serverData) && count($serverData) > 0 ){
				$fileTemplate .= self::getServerTemplate($serverData);
			}
			else{
				// Récupération des données des serveurs existant
				$getServerValues = array(
					'name' => $serverName,
					'address' => $serverValues['address'],
					'port' => $serverValues['port'],
                    'ds_pw' => $serverValues['ds_pw'],
					'mapsbasepath' => isset($serverValues['mapsbasepath']) ? $serverValues['mapsbasepath'] : '',
					'matchsettings' => $serverValues['matchsettings'],
					'adminlevel' => array()
				);
				foreach($serverValues['adminlevel'] as $admLvlId => $admLvlValue){
					$getServerValues['adminlevel'][$admLvlId] = $admLvlValue;
				}
				
				// Ajout des données au template
				$fileTemplate .= self::getServerTemplate($getServerValues);
			}
			$i++;
		}
		
		// Ajout d'un nouveau
		if($editServer === -1 && isset($serverData) && count($serverData) > 0 ){
			if( self::getServerId($serverData['name']) === -1 ){
				$fileTemplate .= self::getServerTemplate($serverData);
			}
			else{
				return Utils::t('The server already exist! Change the name.');
			}
		}
		$fileTemplate .= self::$CONFIG_END_TEMPLATE;
		
		// Enregistrement
		return File::save(self::$CONFIG_PATH.self::$CONFIG_FILENAME, $fileTemplate, false);
	}
}

?>
<?php

/**
* Classe pour le traitement des tris AdminServ
*/
class AdminServSort {
	
	
	public static function sortByNickName($a, $b){
		$a = TmNick::toText($a['NickName']);
		$b = TmNick::toText($b['NickName']);
		
		if($a == $b){
			return 0;
		}
		return ($a < $b) ? -1 : 1;
	}
	public static function sortByLadderRanking($a, $b){
		if($a['LadderRanking'] == $b['LadderRanking']){
			return 0;
		}
		return ($a['LadderRanking'] < $b['LadderRanking']) ? -1 : 1;
	}
	public static function sortByLogin($a, $b){
		if($a['Login'] == $b['Login']){
			return 0;
		}
		return ($a['Login'] < $b['Login']) ? -1 : 1;
	}
	public static function sortByStatus($a, $b){
		if($a['SpectatorStatus'] == $b['SpectatorStatus']){
			return 0;
		}
		return ($a['SpectatorStatus'] < $b['SpectatorStatus']) ? -1 : 1;
	}
	public static function sortByTeam($a, $b){
		if($a['TeamId'] == 0){
			$a['TeamId'] = 'blue';
		}else if($a['TeamId'] == 1){
			$a['TeamId'] = 'red';
		}else{
			$a['TeamId'] = 'spectator';
		}
		if($b['TeamId'] == 0){
			$b['TeamId'] = 'blue';
		}else if($b['TeamId'] == 1){
			$b['TeamId'] = 'red';
		}else{
			$b['TeamId'] = 'spectator';
		}
		
		if($a['TeamId'] == $b['TeamId']){
			return 0;
		}
		return ($a['TeamId'] < $b['TeamId']) ? -1 : 1;
	}
	
	/* Maps-list */
	public static function sortByFileName($a, $b){
		if($a['FileName'] == $b['FileName']){
			return 0;
		}
		return ($a['FileName'] < $b['FileName']) ? -1 : 1;
	}
	public static function sortByName($a, $b){
		$a = strip_tags($a['Name']);
		$b = strip_tags($b['Name']);
		
		if($a == $b){
			return 0;
		}
		return ($a < $b) ? -1 : 1;
	}
	public static function sortByEnviro($a, $b){
		if($a['Environment'] == 'Speed'){
			$a['Environment'] = 'Desert';
		}
		if($b['Environment'] == 'Speed'){
			$b['Environment'] = 'Desert';
		}
		if($a['Environment'] == 'Alpine'){
			$a['Environment'] = 'Snow';
		}
		if($b['Environment'] == 'Alpine'){
			$b['Environment'] = 'Snow';
		}
		
		if($a['Environment'] == $b['Environment']){
			return 0;
		}
		return ($a['Environment'] < $b['Environment']) ? -1 : 1;
	}
	public static function sortByType($a, $b){
		if($a['Type']['Name'] == $b['Type']['Name']){
			return 0;
		}
		return ($a['Type']['Name'] < $b['Type']['Name']) ? -1 : 1;
	}
	public static function sortByAuthor($a, $b){
		$a = strtolower($a['Author']);
		$b = strtolower($b['Author']);
		
		if($a == $b){
			return 0;
		}
		return ($a < $b) ? -1 : 1;
	}
	public static function sortByGoldTime($a, $b){
		if($a['GoldTime'] == $b['GoldTime']){
			return 0;
		}
		return ($a['GoldTime'] < $b['GoldTime']) ? -1 : 1;
	}
	public static function sortByPrice($a, $b){
		if($a['CopperPrice'] == $b['CopperPrice']){
			return 0;
		}
		return ($a['CopperPrice'] < $b['CopperPrice']) ? -1 : 1;
	}
	public static function sortByRank($a, $b){
		if($a['Rank'] == $b['Rank']){
			return 0;
		}
		return ($a['Rank'] < $b['Rank']) ? -1 : 1;
	}
}
?>
<?php

/**
* Classe pour l'interface d'AdminServ
*/
class AdminServUI {
	
	/**
	* Récupère le titre de l'application
	*
	* @param string $type -> Retourner "str" ou "html"
	* @return string
	*/
	public static function getTitle($type = 'str'){
		$out = null;
		$title = AdminServConfig::TITLE;
		if(!$title){
			$title = 'Admin,Serv';
		}
		
		if($type == 'html'){
			if( strstr($title, ',') ){
				$out = str_replace(',', '<span class="title-color">', $title).'</span>';
			}
			else{
				$out = $title;
			}
		}
		else{
			$out = str_replace(',', '', $title);
		}
		
		return $out;
	}
	
	
	/**
	* Vérifie s'il y a bien une config de theme
	*/
	public static function hasTheme(){
		$out = false;
		
		if( class_exists('ExtensionConfig') && isset(ExtensionConfig::$THEMES) && count(ExtensionConfig::$THEMES) > 0 ){
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le thème courant ou
	*
	* @param string $setTheme -> Utiliser un autre thème
	* @return $_SESSION['theme']
	*/
	public static function theme($setTheme = null){
		$saveCookie = false;
		
		if($setTheme){
			$_SESSION['theme'] = $setTheme;
			$saveCookie = true;
		}
		else{
			if( !isset($_SESSION['theme']) ){
				if( isset($_COOKIE['adminserv_user']) ){
					$_SESSION['theme'] = Utils::readCookieData('adminserv_user', 0);
				}
				else{
					if(AdminServConfig::DEFAULT_THEME){
						$_SESSION['theme'] = AdminServConfig::DEFAULT_THEME;
					}
					else{
						$_SESSION['theme'] = 'red';
					}
					$saveCookie = true;
				}
			}
		}
		
		if($saveCookie){
			$cookieData = array(
				$_SESSION['theme'],
				self::lang(),
				Utils::readCookieData('adminserv_user', 2),
				Utils::readCookieData('adminserv_user', 3)
			);
			
			Utils::addCookieData('adminserv_user', $cookieData, AdminServConfig::COOKIE_EXPIRE);
		}
		
		if($setTheme){
			if(USER_PAGE == 'index'){
				Utils::redirection();
			}
			else{
				Utils::redirection(false, '?p='.USER_PAGE);
			}
		}
		
		return strtolower($_SESSION['theme']);
	}
	
	
	/**
	* Récupère la couleur définie dans le thème
	*
	* @param int $indexColor -> Index de la couleur à récupérer
	* @return string code hexa
	*/
	public static function getThemeColor($indexColor = 0){
		$out = null;
		
		if( self::hasTheme() && ($theme = self::theme()) ){
			if( isset(ExtensionConfig::$THEMES[$theme]) && isset(ExtensionConfig::$THEMES[$theme][$indexColor]) ){
				$out = ExtensionConfig::$THEMES[$theme][$indexColor];
			}
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la liste des thèmes
	*/
	public static function getThemeList($currentTheme = array() ){
		$out = null;
		$list = array();
		if( self::hasTheme() ){
			$list = ExtensionConfig::$THEMES;
		}
		$countList = count($list);
		
		// Page courante
		if(USER_PAGE && USER_PAGE != 'index'){
			$param = '?p='.USER_PAGE .'&amp;th=';
		}
		else{
			$param = '?th=';
		}
		
		if( $countList > 0 ){
			$out .= '<ul>';
			// S'il y a un thème courant, on le place en 1er
			if( count($currentTheme) > 0 ){
				$currentThemeName = key($currentTheme);
				$currentThemeColor = current($currentTheme);
				unset($list[$currentThemeName]);
				$out .= '<li><a tabindex="-1" class="theme-color" style="background-color: '.$currentThemeColor[0].';" href="'.$param.$currentThemeName.'" title="'.Utils::t( ucfirst($currentThemeName) ).'"></a></li>';
			}
			foreach($list as $name => $color){
				$out .= '<li><a tabindex="-1" class="theme-color" style="background-color: '.$color[0].';" href="'.$param.$name.'" title="'.Utils::t( ucfirst($name) ).'"></a></li>';
			}
			$out .= '</ul>';
		}
		
		return $out;
	}
	
	
	/**
	* Vérifie s'il y a bien une config de langue
	*/
	public static function hasLang(){
		$out = false;
		
		if( class_exists('ExtensionConfig') && isset(ExtensionConfig::$LANG) && count(ExtensionConfig::$LANG) > 0 ){
			$out = true;
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la langue courante
	*
	* @param string $setLang -> Forcer l'utilisation de la langue
	* @return $_SESSION['lang']
	*/
	public static function lang($setLang = null){
		global $translate;
		$saveCookie = false;
		
		if($setLang){
			$_SESSION['lang'] = $setLang;
			$saveCookie = true;
		}
		else{
			if( !isset($_SESSION['lang']) ){
				if( isset($_COOKIE['adminserv_user']) ){
					$_SESSION['lang'] = Utils::readCookieData('adminserv_user', 1);
				}
				else{
					if( AdminServConfig::DEFAULT_LANGUAGE == 'auto' ){
						$_SESSION['lang'] = 'en';
						$autoLangCode = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
						if( self::hasLang() ){
							if( in_array($autoLangCode, ExtensionConfig::$LANG) ){
								$_SESSION['lang'] = $autoLangCode;
							}
						}
					}
					else{
						if(AdminServConfig::DEFAULT_LANGUAGE){
							$_SESSION['lang'] = AdminServConfig::DEFAULT_LANGUAGE;
						}
						else{
							$_SESSION['lang'] = 'en';
						}
					}
					$saveCookie = true;
				}
			}
		}
		
		if($saveCookie){
			$cookieData = array(
				self::theme(),
				$_SESSION['lang'],
				Utils::readCookieData('adminserv_user', 2),
				Utils::readCookieData('adminserv_user', 3)
			);
			
			Utils::addCookieData('adminserv_user', $cookieData, AdminServConfig::COOKIE_EXPIRE);
		}
		
		if($setLang){
			if(USER_PAGE == 'index'){
				Utils::redirection();
			}
			else{
				Utils::redirection(false, '?p='.USER_PAGE);
			}
		}
		
		$langCode = strtolower($_SESSION['lang']);
		$langFile = AdminServConfig::$PATH_RESOURCES .'lang/'.$langCode.'.php';
		if( file_exists($langFile) ){
			require_once $langFile;
		}
		
		return $langCode;
	}
	
	
	/**
	* Récupère la liste des langues
	*/
	public static function getLangList($currentLang = array() ){
		$out = null;
		$list = array();
		if( self::hasLang() ){
			$list = ExtensionConfig::$LANG;
		}
		$countList = count($list);
		
		// Page courante
		if(USER_PAGE && USER_PAGE != 'index'){
			$param = '?p='.USER_PAGE .'&amp;lg=';
		}
		else{
			$param = '?lg=';
		}
		
		// Liste de toutes les langues
		if( $countList > 0 ){
			$out .= '<ul>';
			// S'il y a une langue courante, on la place en 1er
			if( count($currentLang) > 0 ){
				$currentLangCode = key($currentLang);
				$currentLangName = current($currentLang);
				unset($list[$currentLangCode]);
				$out .= '<li><a tabindex="-1" class="lang-flag" style="background-image: url('. AdminServConfig::$PATH_RESOURCES .'images/lang/'.$currentLangCode.'.png);" href="'.$param.$currentLangCode.'" title="'.$currentLangName.'"></a></li>';
			}
			foreach($list as $code => $name){
				$out .= '<li><a tabindex="-1" class="lang-flag" style="background-image: url('. AdminServConfig::$PATH_RESOURCES .'images/lang/'.$code.'.png);" href="'.$param.$code.'" title="'.$name.'"></a></li>';
			}
			$out .= '</ul>';
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le header/footer du site
	*/
	public static function getHeader(){
		global $args;
		
		if( !isset($GLOBALS['body_class']) ){
			$GLOBALS['body_class'] = null;
		}
		if(USER_PAGE != 'servers-online-config' && !self::isPageType('config') ){
			if( defined('SERVER_NAME') ){
				$GLOBALS['page_title'] = SERVER_NAME;
				$GLOBALS['body_class'] .= ' not-front';
			}
			else{
				$GLOBALS['body_class'] .= ' front';
			}
		}
		else{
			$GLOBALS['body_class'] .= ' config';
		}
		if( defined('USER_PAGE') && USER_PAGE ){
			$GLOBALS['body_class'] .= ' section-'.USER_PAGE;
		}
		if( defined('CURRENT_PLUGIN') && CURRENT_PLUGIN ){
			$GLOBALS['body_class'] .= ' plugin-'.CURRENT_PLUGIN;
		}
		$GLOBALS['body_class'] = trim($GLOBALS['body_class']);
		
		require_once AdminServConfig::$PATH_RESOURCES . 'templates/header.tpl.php';
	}
	public static function getFooter(){
		require_once AdminServConfig::$PATH_RESOURCES . 'templates/footer.tpl.php';
	}
	
	
	/**
	* Récupère le CSS/JS du site
	*/
	public static function getCss(){
		$path = AdminServConfig::$PATH_RESOURCES .'css/';
		$out = '<link rel="stylesheet" href="'.$path.'fileuploader.css" />'."\n\t\t"
		.'<link rel="stylesheet" href="'.$path.'global.css" />'."\n\t\t"
		.'<!--[if IE]><link rel="stylesheet" href="'.$path.'ie.css" /><![endif]-->'."\n\t\t";
		if( defined('USER_THEME') && USER_THEME ){
			$out .= '<link rel="stylesheet" href="'.$path.'jqueryui/'. USER_THEME .'.css" />'."\n\t\t"
			.'<link rel="stylesheet" href="'.$path.'theme.php?th='. USER_THEME .'" />'."\n\t\t";
		}
		$out .= '<link rel="stylesheet" media="screen and (max-width: 1000px) and (min-width: 335px)" href="'.$path.'mobile.css" />'."\n";
		
		return $out;
	}
	public static function getJS(){
		$path = AdminServConfig::$PATH_RESOURCES .'js/';
		$out = '<script src="'.$path.'jquery.js"></script>'."\n\t\t"
		.'<script src="'.$path.'jquery-ui.js"></script>'."\n\t\t"
		.'<script src="'.$path.'colorpicker.js"></script>'."\n\t\t"
		.'<script src="'.$path.'fileuploader.js"></script>'."\n\t\t"
		.'<script src="'.$path.'adminserv_funct.js"></script>'."\n\t\t"
		.'<script src="'.$path.'adminserv_event.js"></script>'."\n";
		
		return $out;
	}
	
	
	/**
	* Récupère la liste des serveurs configurés
	*
	* @return string
	*/
	public static function getServerList(){
		$out = null;
		
		if( class_exists('ServerConfig') && AdminServServerConfig::hasServer() ){
			if( isset($_GET['server']) && $_GET['server'] != null ){
				$currentServerId = intval($_GET['server']);
			}
			else{
				$currentServerId = Utils::readCookieData('adminserv', 0);
			}
			
			foreach(ServerConfig::$SERVERS as $server => $values){
				$selected = (AdminServServerConfig::getServerId($server) == $currentServerId) ? ' selected="selected"' : null;
				$out .= '<option value="'.$server.'"'.$selected.'>'.$server.'</option>';
			}
		}
		else{
			$out = '<option value="null">'.Utils::t('No server available').'</option>';
		}
		
		return $out;
	}
	
	
	/**
	* Récupère la liste des modes de jeu
	*
	* @param int $currentGameMode -> Le mode de jeu à sélectionner
	* @return string
	*/
	public static function getGameModeList($currentGameMode = null){
		$out = null;
		
		if( class_exists('ExtensionConfig') && isset(ExtensionConfig::$GAMEMODES) && count(ExtensionConfig::$GAMEMODES) > 0 ){
			foreach(ExtensionConfig::$GAMEMODES as $gameModeId => $gameModeName){
				$selected = ($gameModeId == $currentGameMode) ? ' selected="selected"' : null;
				$out .= '<option value="'.$gameModeId.'"'.$selected.'>'.$gameModeName.'</option>';
			}
		}
		else{
			$out = '<option value="null">'.Utils::t('No game mode available').'</option>';
		}
		
		return $out;
	}
	
	
	/**
	* Récupère le formulaire pour un champ
	*
	* @param array  $gameinfos -> Informations de jeu courantes et suivantes
	* @param string $name      -> Le nom du champ affiché dans un label
	* @param string $id        -> L'id du champ du tableau GameInfos
	* @return string HTML
	*/
	public static function getGameInfosField($gameinfos, $name, $id){
		global $data;
		$data['gameInfosField'] = array(
			'gameInfos' => $gameinfos,
			'name' => $name,
			'id' => $id
		);
		
		self::getTemplate('gameinfos-field');
		unset($data['gameInfosField']);
	}
	
	
	/**
	* Récupère la liste des joueurs
	*
	* @param string $currentPlayerLogin -> Le login joueur à sélectionner
	* @return string
	*/
	public static function getPlayerList($currentPlayerLogin = null){
		global $client;
		$out = '<option value="null">'.Utils::t('No player available').'</option>';
		
		if( !$client->query('GetPlayerList', AdminServConfig::LIMIT_PLAYERS_LIST, 0, 1) ){
			AdminServ::error();
		}
		else{
			$playerList = $client->getResponse();
			if( count($playerList) > 0 ){
				$out = null;
				foreach($playerList as $player){
					if($currentPlayerLogin == $player['Login']){ $selected = ' selected="selected"'; }
					else{ $selected = null; }
					$out .= '<option value="'.$player['Login'].'"'.$selected.'>'.TmNick::toText($player['NickName']).'</option>';
				}
			}
		}
		
		return $out;
	}
	
	
	/**
	* Retourne le menu pour les pages maps
	*
	* @return template html
	*/
	public static function getMapsMenuList(){
		global $data, $args;
		$list = ExtensionConfig::$MAPSMENU;
		$excludeLocalPage = array('maps-local', 'maps-matchset', 'maps-creatematchset');
		if( !IS_LOCAL ){
			foreach($excludeLocalPage as $page){
				unset($list[$page]);
			}
		}
		
		$data += array(
			'menuList' => $list,
		);
		self::getTemplate('maps-menu');
	}
	
	
	/**
	* Récupère la liste des dossiers du répertoire "Maps"
	*
	* @require class "Folder"
	*
	* @param string $path        -> Le chemin du dossier "Maps"
	* @param string $currentPath -> Le chemin à partir de "Maps"
	* @param bool   $showOptions -> Afficher les options (nouveau, renommer, déplacer, supprimer)
	* @return template maps-directorylist
	*/
	public static function getMapsDirectoryList($directory, $currentPath = null, $showOptions = true){
		global $data;
		
		if (class_exists('Folder')) {
			$data += array(
				'folders' => array(),
				'currentPath' => $currentPath,
				'parentPath' => null,
				'showOptions' => $showOptions,
			);
			
			// Liste des dossiers
			if (is_array($directory)) {
				// Dossier parent
				if ($currentPath) {
					$params = null;
					$parentPathEx = explode('/', $currentPath);
					array_pop($parentPathEx);
					array_pop($parentPathEx);
					if (!empty($parentPathEx)) {
						$parentPath = null;
						foreach ($parentPathEx as $part) {
							$parentPath .= $part.'/';
						}
						$data['parentPath'] = $parentPath;
					}
				}
				
				// Dossiers
				if (!empty($directory['folders'])) {
					$data['folders'] = $directory['folders'];
				}
				
				// Template
				self::getTemplate('maps-directorylist');
			}
			else{
				AdminServ::error($directory);
			}
		}
		else{
			AdminServ::error('Class "Folder" not exists');
		}
	}
	
	
	/**
	* Ititialise une page en back office
	*/
	public static function initBackPage() {
		global $client, $data, $args;
		
		// Pages list
		$pagesList = array(
			'general',
			'srvopts',
			'gameinfos',
			'chat',
			'plugins-list',
			'guestban',
		);
		$pagesList = array_merge($pagesList, array_keys(ExtensionConfig::$MAPSMENU) );
		$firstPage = array_shift($pagesList);
		
		// Render page
		if (in_array(USER_PAGE, $pagesList)) {
			$pageKey = array_search(USER_PAGE, $pagesList);
			if (AdminServAdminLevel::hasAccess($pagesList[$pageKey])) {
				self::renderPage($pagesList[$pageKey]);
			}
			else {
				$data = array(
					'errorTitle' => Utils::t('Erreur d\'accès à la page'),
					'errorMessage' => Utils::t('Vous n\'avez pas les droits requis pour accéder à cette page. Veuillez contacter votre administrateur.'),
				);
				self::renderPage('page-error');
			}
		}
		else {
			if (self::isPageType('config')) {
				session_unset();
				session_destroy();
				Utils::redirection(false, './config/');
			}
			elseif (USER_PLUGIN) {
				AdminServPlugin::renderPlugin();
			}
			else {
				self::renderPage($firstPage);
			}
		}
	}
	
	
	/**
	* Ititialise une page en front office
	*/
	public static function initFrontPage() {
		// Render page
		if (self::isPageType('config')) {
			$pageTitle = 'Configuration';
			$pageName = USER_PAGE;
		}
		else {
			$pageTitle = 'Connection';
			$pageName = 'connection';
		}
		$GLOBALS['page_title'] = Utils::t($pageTitle);
		self::renderPage($pageName);
	}
	
	
	/**
	* Inclue les fichiers pour le rendu d'une page
	*/
	public static function renderPage($pageName) {
		global $client, $data, $args;
		
		// Preprocess
		if (strstr($pageName, '-')) {
			$pageNameEx = explode('-', $pageName);
			$pagePreprocess = AdminServConfig::$PATH_RESOURCES.'process/'.$pageNameEx[0].'.preprocess.php';
			if (file_exists($pagePreprocess)) {
				require_once $pagePreprocess;
			}
		}
		
		// Process
		$pageProcess = AdminServConfig::$PATH_RESOURCES.'process/'.$pageName.'.php';
		if (file_exists($pageProcess)) {
			require_once $pageProcess;
		}
		
		// Terminate client
		if (isset($client) && $client->socket != null) {
			$client->Terminate();
		}
		
		// Header
		self::getHeader();
		
		// Template
		self::getTemplate($pageName);
		
		// Footer
		self::getFooter();
		
		AdminServLogs::add('access', (isset($GLOBALS['page_title'])) ? $GLOBALS['page_title'] : $pageName);
	}
	
	
	/**
	* Vérifie si la page est du type demandé
	*
	* @param string $pageType -> Type de page à tester (config, plugin)
	* @return bool
	*/
	public static function isPageType($pageType, $pageName = USER_PAGE){
		$out = false;
		
		if (strstr($pageName, '-')) {
			$pageNameEx = explode('-', $pageName);
			if ($pageNameEx[0] === $pageType) {
				$out = true;
			}
		}
		
		return $out;
	}
	
	
	/**
	* Inclue un fichier template
	*
	* @param string $templateName -> Nom du fichier template sans les extensions
	* @return template HTML ou null si le template n'existe pas
	*/
	public static function getTemplate($templateName){
		global $data, $args;
		
		$tplFile = AdminServConfig::$PATH_RESOURCES.'templates/'.$templateName.'.tpl.php';
		if (file_exists($tplFile)) {
			require $tplFile;
		}
	}
}
?>
/* Global DisplayServ-------------------------------*/.ds-servers-list {	margin: 0;	padding: 0;	-webkit-transition: all .2s ease-in-out;	-moz-transition: all .2s ease-in-out;	-o-transition: all .2s ease-in-out;	transition: all .2s ease-in-out;}.ds-servers-list .ds-server {	position: relative;	list-style: none;	margin: 10px 0;	padding: 10px;	min-height: 160px;	overflow: hidden;	background: #fff;	border: 1px solid #ddd;	-webkit-border-radius: 3px;	-moz-border-radius: 3px;	-o-border-radius: 3px;	border-radius: 3px;}.ds-servers-list .ds-server-join-wrap {	position: absolute;	bottom: -35px;	right: 0;	padding: 0 10px;	background: rgba(0, 0, 0, .75);	-webkit-border-radius: 3px 0 0;	-moz-border-radius: 3px 0 0;	-o-border-radius: 3px 0 0;	border-radius: 3px 0 0;	-webkit-transition: all .2s ease-in-out;	-moz-transition: all .2s ease-in-out;	-o-transition: all .2s ease-in-out;	transition: all .2s ease-in-out;}.ds-servers-list.loading .ds-server-join-wrap {	display: none !important;}.ds-servers-list .ds-server:hover .ds-server-join-wrap {	bottom: 0;}.ds-servers-list .ds-server-join-wrap ul {	margin: 0;	padding: 0;}.ds-servers-list .ds-server-join-wrap ul li {	display: block;	float: left;	list-style: none;	padding: 5px 0 7px;}.ds-servers-list .ds-server-join-wrap ul li + li {	margin-left: 10px;	padding-left: 10px;	border-left: 1px solid #555;}.ds-servers-list .ds-server-join-wrap ul li a {	color: #fff;	font-family: Helvetica, Arial, sans-serif;	font-size: 12px;	text-decoration: none;}.ds-servers-list .ds-server-join-wrap ul li a:hover {	border-bottom: 1px solid #eee;}.ds-servers-list.loading {	opacity: .5;}.ds-servers-list table {	width: 100%;	border-spacing: 0;}.ds-servers-list .ds-header th {	color: #5e9cd5;	font-family: Helvetica, Arial, sans-serif;	font-size: 14px;	font-weight: bold;	min-height: 20px;	font-variant: small-caps;	text-align: left;}.ds-servers-list .ds-header .ds-server-join {	border-left: 1px dotted #636363;	padding-left: 10px;}.ds-servers-list .ds-header .ds-server-join a {	color: #5e9cd5;	font-size: 10px;	font-variant: normal;	text-decoration: none;}.ds-servers-list .ds-header .ds-server-join a:hover {	text-decoration: underline;}.ds-servers-list .ds-content {	margin-top: 10px;	color: #666;	font-family: Helvetica, Arial, sans-serif;	font-size: 12px;}.ds-servers-list .ds-content ul {	margin: 0;	padding: 0;}.ds-servers-list .ds-content ul li {	padding: 0;	list-style: none;	line-height: 18px;}.ds-servers-list .ds-server-currentmap img {	margin-bottom: -3px;}.ds-servers-list .ds-space {	height: 10px;}.ds-servers-list .ds-space td {	border: 1px dotted #ccc;	border-width: 1px 0 0;	height: 10px;}.ds-servers-list tr,.ds-servers-list td,.ds-servers-list th,.ds-servers-list tr:hover,.ds-servers-list td:hover,.ds-servers-list th:hover {	background: none;	cursor: default;}.ds-servers-list td {	vertical-align: top;	text-align: left;}.ds-servers-list .ds-servers-players-list {	height: 125px;	overflow-x: hidden;	overflow-y: auto;}.ds-servers-list .ds-servers-players-list td {	border: 1px solid #f7f7f7;	border-width: 0 0 1px;}.ds-servers-list .ds-servers-players-list td.no-player {	text-align: center;	border: 0;	font-style: italic;}.ds-servers-list .ds-content .ds-part-left {	color: #888;	padding-right: 10px;	border-right: 1px dotted #636363;	text-align: right;	width: 17%;	min-width: 100px;}.ds-servers-list .ds-content .ds-part-middle {	padding-left: 10px;	width: 33%;	min-width: 100px;}.ds-servers-list .ds-content .ds-part-right {	width: 50%;}@media (max-width: 580px) {	.ds-servers-list .ds-header th.middle,	.ds-servers-list .ds-content .ds-part-left {		display: none;	}}@media (max-width: 380px) {	.ds-servers-list .ds-header th.middle,	.ds-servers-list .ds-header th.last,	.ds-servers-list .ds-content .ds-part-left,	.ds-servers-list .ds-content .ds-part-right {		display: none;	}}.ds-servers-list.max-width-580 .ds-header th.middle,.ds-servers-list.max-width-580 .ds-content .ds-part-left,.ds-servers-list.max-width-380 .ds-header th.middle,.ds-servers-list.max-width-380 .ds-header th.last,.ds-servers-list.max-width-380 .ds-content .ds-part-left,.ds-servers-list.max-width-380 .ds-content .ds-part-right {	display: none;}/* Couleurs GameMode & Jeux----------------------------- */.rounds {	color: #ffcc11;}.timeattack {	color: #d1321e;}.team {	color: #aabb00;}.laps {	color: #88aa11;}.stunts {	color: #5600da;}.cup {	color: #ff8c11;}.script,.other {	color: #444;}.maniaplanet {	color: #2277cc;}.tmforever {	color: #ad0000;}.team_-1,.team_0,.team_1 {	display: block;	float: left;	width: 7px;	height: 16px;	margin-right: 5px;	opacity: .8;}.team_-1 {	background: #000;}.team_0 {	background: #00f;}.team_1 {	background: #f00;}/* TmNick------------------------ */.tmnick_global {	font-style: normal;	font-weight: none;	letter-spacing: 0;}.tmnick_normal { letter-spacing: 0; }.tmnick_short { letter-spacing: -1px; }.tmnick_wide { letter-spacing: 2px; }.tmnick_raz { font-style: normal; font-weight: none; letter-spacing: 0; }.tmnick_italic { font-style: italic; }.tmnick_bold { font-weight: bold; letter-spacing: 1px; }.tmnick_upper { text-transform: uppercase; }.tmnick_shadowed { text-shadow: 1px 1px 1px #444; }a.tmnick_internallink, a.tmnick_internallink:visited {	color: inherit;	text-decoration: none;	border-bottom: thin solid Black;}a.tmnick_internallink:hover {	color: inherit;	text-decoration: none;	border-bottom: thin solid Blue;}a.tmnick_internallink_withlogin, a.tmnick_internallink_withlogin:visited  {	color: inherit;	text-decoration: none;	border-bottom: thin solid #f0e68c;}a.tmnick_internallink_withlogin:hover {	color: inherit;	text-decoration: none;	border-bottom: thin solid Gold;}a.tmnick_externallink, a.tmnick_externallink:visited {	color: inherit;	text-decoration: none;	border-bottom: thin solid Black;}a.tmnick_externallink:hover {	color: inherit;	text-decoration: none;	border-bottom: thin solid Orange;}
.qq-uploader {	position: relative;	width: 100%;	min-height: 120px;}.qq-upload-button {	position: absolute !important;	top: 90px;	width: 150px;	padding: 7px 0;	color: #fff;	font-variant: small-caps;	text-align: center;	background: #888;	border-right: 4px solid #ccc;	-webkit-border-radius: 3px;	-moz-border-radius: 3px;	-ms-border-radius: 3px;	-o-border-radius: 3px;	border-radius: 3px;}.qq-upload-button-hover {	background: #5e9cd5;}.qq-upload-button-focus {	outline: 1px dotted black}.qq-upload-drop-area {	display: block !important;	position: absolute;	top: 0;	left: 0;	z-index: 2;	width: 150px;	height: 82px;	text-align: center;	background: url("../images/32/blue_arrow_down.png") no-repeat center 85% #888;	border-right: 4px solid #ccc;	-webkit-border-radius: 3px;	-moz-border-radius: 3px;	-ms-border-radius: 3px;	-o-border-radius: 3px;	border-radius: 3px;}.qq-upload-drop-area span {	display: block;	position: absolute;	top: 7%;	width: 100%;	color: #fff;	font-size: 1em;	font-variant: small-caps;	cursor: default;}.qq-upload-drop-area-active {	background-color: #3182C0;}.qq-upload-list {	margin: 10px 0 0 170px;	padding: 0;	list-style: none outside none;}.qq-upload-list li {	margin: 0;	padding: 0;	line-height: 15px;	font-size: 1em;}.qq-upload-file,.qq-upload-spinner,.qq-upload-size,.qq-upload-cancel,.qq-upload-failed-text {	margin-right: 7px;}.qq-upload-file {	display: inline-block;	width: 160px;}.qq-upload-spinner {	display: inline-block;	position: relative;	width: 100px;	height: 15px;	vertical-align: text-bottom;	border: 1px solid #ddd;}.qq-progress-bar {	position: absolute;	top: 0;	left: 0;	height: 15px;	background: #3182c0;}.qq-upload-size,.qq-upload-cancel {	display: inline-block !important;	width: 68px;	font-size: .9em;	text-align: center;}.qq-upload-cancel {	margin-bottom: 2px;	padding: 2px 5px;	color: #999;	font-variant: small-caps;	text-decoration: none;	border: 1px solid #ddd;	-webkit-border-radius: 3px;	-moz-border-radius: 3px;	-ms-border-radius: 3px;	-o-border-radius: 3px;	border-radius: 3px;}.qq-upload-cancel:hover {	color: #fff;	background: #3182c0;	border-color: #3182c0;}.qq-upload-failed-text {	display: none;}.qq-upload-fail .qq-upload-failed-text {	display: inline;}
/* Global AdminServ
-------------------------------*/
html {
	font-size: 100%;
}
body {
	margin: 0;
	padding: 0;
	color: #666;
	font-family: Helvetica, Arial, "Trebuchet MS", Verdana, Tahoma, Sans-Serif;
	font-size: .8em;
	background: #f2f2f2;
}
a img {
	border: 0;
}
label {
	cursor: pointer;
}
label span {
	font-size: .8em;
}
ul {
	margin: 0;
	padding: 0;
}
li {
	list-style: none;
}
[hidden="hidden"] {
	display: none;
}
.fleft {
	float: left;
}
.fright {
	float: right;
}
.alignleft {
	text-align: left;
}
.aligncenter {
	text-align: center;
}
.alignright {
	text-align: right;
}
.loading {
	opacity: .5;
}


/* Taille du site
-------------------------------*/
#header-inner,
#nav-inner,
#connection-inner,
#content-inner,
#footer-inner {
	width: 1000px;
	margin: 0 auto;
	position: relative;
}


/* Header
-------------------------------*/
header {
	background: #555;
}
#header-inner {
	height: 74px;
}

/* Logo - Titre */
.logo-title {
	float: left;
}
.logo-title a {
	display: block;
	text-decoration: none;
}
.logo-title a:hover #title {
	color: #eee;
}
#logo {
	float: left;
	padding: 10px 10px 0;
}
.title-subtitle {
	float: left;
	font-family: "Trebuchet MS", Arial, Sans-serif;
	font-weight: bold;
}
#title {
	float: left;
	margin-top: 8px;
	line-height: 45px;
	color: #ddd;
	font-size: 3.7em;
	letter-spacing: -2px;
	-webkit-transition: color .2s ease-in-out;
	-moz-transition: color .2s ease-in-out;
	-ms-transition: color .2s ease-in-out;
	-o-transition: color .2s ease-in-out;
	transition: color .2s ease-in-out;
}
#title .title-color {
	color: #5e9cd5;
}
#subtitle {
	clear: both;
	float: left;
	color: #eee;
	font-size: .9em;
}

/* SpeedAdmin */
.speed-admin {
	float: right;
	margin-right: 78px;
}
.speed-admin ul {
	padding: 3px 4px;
	width: 89px;
	background: #484848;
	overflow: hidden;
	-webkit-border-radius: 0 0 5px 5px;
	-moz-border-radius: 0 0 5px 5px;
	-ms-border-radius: 0 0 5px 5px;
	-o-border-radius: 0 0 5px 5px;
	border-radius: 0 0 5px 5px;
}
.speed-admin li + li a {
	margin-left: 3px;
}
.speed-admin li a {
	display: block;
	float: left;
	width: 20px;
	height: 20px;
	text-indent: -9999px;
	background-repeat: no-repeat;
}
.speed-admin li a:hover {
	background-position: 0 -20px;
}
.speed-admin li .locked {
	cursor: default;
	background-position: 0 -40px;
}
.speed-admin li .prev {
	background-image: url("../images/16/bt_arrow_fastprev.png");
}
.speed-admin li .restart {
	background-image: url("../images/16/bt_refresh.png");
}
.speed-admin li .next {
	background-image: url("../images/16/bt_arrow_fastnext.png");
}
.speed-admin li .endround {
	background-image: url("../images/16/bt_arrow_last.png");
}

/* Theme - lang */
.theme-lang {
	float: right;
}
.theme-lang div {
	position: absolute;
	top: 0;
	right: 0;
	z-index: 10;
	padding: 4px;
	height: 12px;
	background: #444;
	overflow: hidden;
	-webkit-border-radius: 0 0 5px 5px;
	-moz-border-radius: 0 0 5px 5px;
	-ms-border-radius: 0 0 5px 5px;
	-o-border-radius: 0 0 5px 5px;
	border-radius: 0 0 5px 5px;
	-webkit-transition: height .2s;
	-moz-transition: height .2s;
	-ms-transition: height .2s;
	-o-transition: height .2s;
	transition: height .2s;
}
#theme {
	right: 30px;
}
.theme-lang li {
	margin-bottom: 5px;
}
.theme-lang a {
	display: block;
	width: 16px;
	height: 11px;
	opacity: .75;
	-webkit-border-radius: 1px;
	-moz-border-radius: 1px;
	-ms-border-radius: 1px;
	-o-border-radius: 1px;
	border-radius: 1px;
	-webkit-transition: all .2s;
	-moz-transition: all .2s;
	-ms-transition: all .2s;
	-o-transition: all .2s;
	transition: all .2s;
}
.theme-lang a:hover {
	opacity: 1;
}

/* Switch Server */
.switch-server {
	position: absolute;
	top: 40px;
	right: 3px;
	z-index: 5;
}
#switchServerList {
	padding: 2px 3px;
	width: 172px;
	color: #ddd;
	background: #555;
	border-color: #888;
	-webkit-transition: background .3s ease-in-out;
	-moz-transition: background .3s ease-in-out;
	-o-transition: background .3s ease-in-out;
	transition: background .3s ease-in-out;
	-webkit-box-shadow: 4px 0 0 rgba(255, 255, 255, .2);
	-moz-box-shadow: 4px 0 0 rgba(255, 255, 255, .2);
	-ms-box-shadow: 4px 0 0 rgba(255, 255, 255, .2);
	-o-box-shadow: 4px 0 0 rgba(255, 255, 255, .2);
	box-shadow: 4px 0 0 rgba(255, 255, 255, .2);
}
#switchServerList:hover {
	background: #444;
}

/* Ligne de couleur */
#header-color-line {
	background: #5e9cd5;
	height: 10px;
}


/* Navigation
-------------------------*/
.horizontal-nav,
#connection {
	padding-bottom: 15px;
	background: #f2f2f2;
}
#connection-inner,
.menu-principal {
	clear: both;
	padding: 5px 0 9px;
	background: #fff;
	border: 1px solid #ddd;
	border-width: 0 1px 1px;
	overflow: hidden;
	-webkit-border-radius: 0 0 5px 5px;
	-moz-border-radius: 0 0 5px 5px;
	-ms-border-radius: 0 0 5px 5px;
	-o-border-radius: 0 0 5px 5px;
	border-radius: 0 0 5px 5px;
}
.menu-principal .menu-left {
	float: left;
	padding-left: 5px;
}
.menu-principal .menu-right {
	float: right;
	padding-right: 5px;
}
.menu-principal li {
	float: left;
	margin: 0 2px;
}
.menu-principal a {
	display: block;
}


/* Connexion
-------------------------------*/
#connection-inner {
	padding: 0 5px;
}
#connection-inner .connection-label,
.section-servers-online-config fieldset .connection-label {
	float: left;
	padding: 5px 0;
	width: 89%;
}
#connection-inner label {
	margin-left: 4px;
}
#as_server {
	width: 32%;
	margin: 1px 10px 0 0;
}
#as_password {
	width: 18%;
	margin: 1px 10px 0 0;
}
#as_adminlevel {
	width: 15%;
	margin: 1px 0 0;
}
#connection-inner .connection-login,
.section-servers-online-config fieldset .connection-login {
	float: right;
	padding: 0 5px 0 10px;
	height: 38px;
	border-left: 1px solid #f5f5f5;
}
#connection-inner .connection-login input,
.section-servers-online-config fieldset .connection-login input {
	margin-top: 5px;
}
.section-servers-online-config fieldset {
	margin: 30px 5px;
	width: 513px;
}
.section-servers-online-config .no-server fieldset {
	width: 450px;
}
.section-servers-online-config fieldset legend {
	margin-bottom: 5px;
}
.section-servers-online-config fieldset .connection-label {
	width: auto;
}
.section-servers-online-config  fieldset .connection-cancel {
	float: right;
	margin-top: 4px;
	padding: 5px 10px 5px 0;
}
.section-servers-online-config #checkPassword,
.section-servers-online-config #savePassword {
	width: 200px;
	height: 20px;
}




/* Erreurs - infos
-------------------------------*/
#error,
#info {
	position: absolute;
	top: 50px;
	left: 230px;
	z-index: 1004;
	padding: 5px;
	width: 500px;
	min-height: 20px;
	font-size: 1.2em;
	text-align: center;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-ms-border-radius: 5px;
	-o-border-radius: 5px;
	border-radius: 5px;
	-webkit-box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
	-moz-box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
	-ms-box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
	-o-box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
	box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
}
#error {
	z-index: 1005;
	color: #fff;
	background-color: #d1321e;
}
#info {
	color: #222;
	background-color: #f4f398;
}


/* Bouttons - Input
-------------------------------*/
.button {
	padding: 3px 5px;
	font-size: .95em;
	font-variant: small-caps;
	background-color: #fff;
	border: 1px solid;
	border-bottom: 0;
	cursor: pointer;
	-webkit-border-radius: 3px;
	-moz-border-radius: 3px;
	-ms-border-radius: 3px;
	-o-border-radius: 3px;
	border-radius: 3px;
}
a.button {
	text-decoration: none;
}
.button.light,
.button.dark {
	-webkit-box-shadow: 0 4px 0 #5e9cd5;
	-moz-box-shadow: 0 4px 0 #5e9cd5;
	-ms-box-shadow: 0 4px 0 #5e9cd5;
	-o-box-shadow: 0 4px 0 #5e9cd5;
	box-shadow: 0 4px 0 #5e9cd5;
}
.button.light:hover,
.button.light.active,
.button.dark:hover,
.button.dark.active {
	-webkit-box-shadow: 0 4px 0 #ddd;
	-moz-box-shadow: 0 4px 0 #ddd;
	-ms-box-shadow: 0 4px 0 #ddd;
	-o-box-shadow: 0 4px 0 #ddd;
	box-shadow: 0 4px 0 #ddd;
	-webkit-transition: background .3s ease-in-out;
	-moz-transition: background .3s ease-in-out;
	-ms-transition: background .3s ease-in-out;
	-o-transition: background .3s ease-in-out;
	transition: background .3s ease-in-out;
	-webkit-transition: border .2s ease-in-out;
	-moz-transition: border .2s ease-in-out;
	-ms-transition: border .2s ease-in-out;
	-o-transition: border .2s ease-in-out;
	transition: border .2s ease-in-out;
}
.button.light {
	color: #999;
	background-color: #fff;
	border-color: #ddd;
}
.button.light:hover,
.button.light.active {
	color: #fff;
	background-color: #666;
	border-color: #666;
}
.button.dark {
	color: #fff;
	background-color: #666;
	border-color: #666;
}
.button.dark:hover,
.button.dark.active {
	color: #999;
	background-color: #fff;
	border-color: #fff;
}
.save input.button {
	margin: 0 10px 5px 0;
	width: 150px;
}

input.text,
textarea,
select {
	color: #777;
	padding: 3px 5px;
	background: #f9f9f9;
	border: 1px solid #ddd;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-ms-border-radius: 5px;
	-o-border-radius: 5px;
	border-radius: 5px;
	-webkit-box-shadow: 4px 0 0 rgba(0, 0, 0, .1);
	-moz-box-shadow: 4px 0 0 rgba(0, 0, 0, .1);
	-ms-box-shadow: 4px 0 0 rgba(0, 0, 0, .1);
	-o-box-shadow: 4px 0 0 rgba(0, 0, 0, .1);
	box-shadow: 4px 0 0 rgba(0, 0, 0, .1);
}
input.text:hover,
input.text:focus,
textarea:hover,
textarea:focus,
select:hover,
select:focus {
	color: #444;
	background: #fff;
	-webkit-transition: background .3s ease-in-out;
	-moz-transition: background .3s ease-in-out;
	-ms-transition: background .3s ease-in-out;
	-o-transition: background .3s ease-in-out;
	transition: background .3s ease-in-out;
	-webkit-transition: color .2s ease-in-out;
	-moz-transition: color .2s ease-in-out;
	-ms-transition: color .2s ease-in-out;
	-o-transition: color .2s ease-in-out;
	transition: color .2s ease-in-out;
}
textarea {
	font-family: "MS Trebuchet", Arial, Sans-Serif;
	font-size: 1.05em;
}
input[type="checkbox"],
input[type="radio"] {
	display: block;
	cursor: pointer;
}
input[type="checkbox"].inline {
	display: inline;
	margin: -2px 7px 0 0;
	vertical-align: middle;
}
input[disabled="disabled"],
input[readonly="readonly"] {
	cursor: default;
}
input[readonly="readonly"]:focus,
input[readonly="readonly"]:hover {
	color: #777;
	background: #f9f9f9;
}
input.width1,
textarea.width1,
select.width1 {
	width: 86%;
}
select.width1 {
	width: 96%;
}
input.width2,
textarea.width2 {
	width: 80%;
}
select.width2 {
	width: 84.75%;
}
input.width3,
textarea.width3,
select.width3 {
	width: 95%;
}


/* Fielset
-------------------------------*/
fieldset {
	margin: 10px 5px;
	background: #fff;
	border: 1px solid #ddd;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-ms-border-radius: 5px;
	-o-border-radius: 5px;
	border-radius: 5px;
}
fieldset legend {
	padding: 0 5px;
	font-weight: bold;
	font-variant: small-caps;
	background: #f5f5f5;
	border: 1px solid #ddd;
	border-width: 1px 1px 0;
	-webkit-border-radius: 5px 5px 0 0;
	-moz-border-radius: 5px 5px 0 0;
	-ms-border-radius: 5px 5px 0 0;
	-o-border-radius: 5px 5px 0 0;
	border-radius: 5px 5px 0 0;
	-webkit-box-shadow: 0 3px #5e9cd5;
	-moz-box-shadow: 0 3px #5e9cd5;
	-ms-box-shadow: 0 3px #5e9cd5;
	-o-box-shadow: 0 3px #5e9cd5;
	box-shadow: 0 3px #5e9cd5;
}
fieldset legend img {
	margin: 2px 3px -5px 0;
	opacity: .8;
}


/* Titres
-------------------------------*/
h1 {
	margin: 0 0 10px;
	line-height: 22px;
	color: #fff;
	font-size: 1.2em;
	font-variant: small-caps;
	text-indent: 10px;
	text-shadow: 1px 1px 3px #777;
	background: #5e9cd5;
	border-bottom: 1px solid #ddd;
	-webkit-border-radius: 2px 2px 2px 6px;
	-moz-border-radius: 2px 2px 2px 6px;
	-ms-border-radius: 2px 2px 2px 6px;
	-o-border-radius: 2px 2px 2px 6px;
	border-radius: 2px 2px 2px 6px;
	-webkit-box-shadow: -4px 0 0 #ddd;
	-moz-box-shadow: -4px 0 0 #ddd;
	-ms-box-shadow: -4px 0 0 #ddd;
	-o-box-shadow: -4px 0 0 #ddd;
	box-shadow: -4px 0 0 #ddd;
}
h2 {
	display: block;
	margin: 20px 0 10px;
	color: #5e9cd5;
	font-size: .9em;
	text-indent: 10px;
	text-transform: uppercase;
	border-bottom: 1px solid #ddd;
}
h3 {
	display: block;
	margin: 10px 0 5px;
	color: #5e9cd5;
	font-size: .9em;
	text-indent: 2px;
	border-bottom: 1px dotted #ccc;
}
.title-detail {
	position: absolute;
	top: 14px;
	right: 10px;
	color: #fff;
	font-size: .9em;
}
.title-detail li {
	float: left;
	padding: 0 6px 0 7px;
	height: 15px;
	border-right: 1px solid #eee;
}
.title-detail li.last {
	border: 0;
}
.title-detail a {
	color: #fff;
	text-decoration: none;
}
.title-detail a:hover {
	text-decoration: underline;
	text-shadow: 1px 1px 5px #777;
}
.title-detail input[type="checkbox"] {
	float: right;
	margin: 1px 0 0;
}


/* Tableaux
---------------------*/
table {
	width: 100%;
	border-spacing: 0;
}
th {
	color: #d1321e;
	font-size: .9em;
	font-weight: normal;
	font-variant: small-caps;
	background: #f5f5f5;
}
th a {
	color: #d1321e;
	text-decoration: none;
}
th a:hover {
	text-decoration: underline;
}
.thleft {
	-webkit-border-radius: 5px 0 0 5px;
	-moz-border-radius: 5px 0 0 5px;
	-ms-border-radius: 5px 0 0 5px;
	-o-border-radius: 5px 0 0 5px;
	border-radius: 5px 0 0 5px;
}
.thright {
	-webkit-border-radius: 0 5px 5px 0;
	-moz-border-radius: 0 5px 5px 0;
	-ms-border-radius: 0 5px 5px 0;
	-o-border-radius: 0 5px 5px 0;
	border-radius: 0 5px 5px 0;
}
tr {
	height: 20px;
}
tr.table-separation {
	height: 5px !important;
}
tr.no-line {
	font-style: italic;
	text-align: center;
}
tr.no-line:hover,
tr.table-separation {
	background: none !important;
	cursor: auto !important;
}
tbody tr.recent {
	background: #f7f59e;
}
tbody tr:hover {
	width: 100%;
	background: #f5f5f5;
	border: 1px solid #eee;
	cursor: pointer;
}
tbody tr.current,
tbody tr.current:hover {
	background: #f7f59e;
	border: 0;
	cursor: default;
}
tbody tr.selected {
	background: #d9e8ff;
}
.section-index .cadre.left tbody tr:hover,
fieldset tbody tr:hover {
	background: none;
	border: 0;
	cursor: default;
}
td {
	text-align: center;
}
td.imgleft {
	text-align: left;

}
td.imgleft img,
td.imgcenter img {
	margin: 0 5px -3px;
	opacity: .8;
}
td.checkbox {
	width: 22px;
}
td.key {
	padding: 0 9px;
	width: 170px;
	color: #888;
	text-align: right;
}
td.value {
	padding-left: 9px;
	text-align: left;
	border-left: 1px dotted #636363;
}
td.info {
	color: #aaa;
	font-size: .9em;
	font-style: italic;
	text-align: left;
}
td .detailModeTd {
	display: block;
	font-size: .7em;
}


/* Option de lignes selectionnées
-------------------------------*/
.options {
	position: relative;
	margin-top: 15px;
	padding: 6px 10px 0;
	min-height: 24px;
	background: #888;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-ms-border-radius: 5px;
	-o-border-radius: 5px;
	border-radius: 5px;
	-webkit-box-shadow: -4px 0 0 #444;
	-moz-box-shadow: -4px 0 0 #444;
	-ms-box-shadow: -4px 0 0 #444;
	-o-box-shadow: -4px 0 0 #444;
	box-shadow: -4px 0 0 #444;
}
.options.form {
	overflow: hidden;
}
.options input {
	margin-right: 5px;
	font-size: .9em;
}
.options .nb-line {
	color: #fff;
	text-transform: lowercase;
}
.selected-files-label {
	display: block;
}
.selected-files-label span {
	color: #fff;
	font-size: 1em;
	text-align: right;
	cursor: default;
}
.selected-files-label.locked span {
	color: #bbb;
	border-color: #bbb;
}
.selected-files-label span.selected-files-title {
	font-style: italic;
	border-bottom: 1px solid #ddd;
}
.selected-files-label span.selected-files-count {
	padding-left: 3px;
}
.selected-files-label.optHover span,
.selected-files-label:hover span,
.selected-files-label.locked:hover .selected-files-option {
	display: none;
}
.selected-files-label.optHover .selected-files-option,
.selected-files-label:hover .selected-files-option {
	display: block;
}
.selected-files-label.optHover .button.active {
	-webkit-box-shadow: 0 8px 0 #ddd;
	-moz-box-shadow: 0 8px 0 #ddd;
	-ms-box-shadow: 0 8px 0 #ddd;
	-o-box-shadow: 0 8px 0 #ddd;
	box-shadow: 0 8px 0 #ddd;
	-webkit-border-radius: 3px 3px 0 0;
	-moz-border-radius: 3px 3px 0 0;
	-ms-border-radius: 3px 3px 0 0;
	-o-border-radius: 3px 3px 0 0;
	border-radius: 3px 3px 0 0;
}
.selected-files-label.locked:hover span {
	display: inline;
}
.selected-files-option {
	display: none;
	position: absolute;
	top: -18px;
	right: -25px;
	padding: 25px;
	text-align: right;
}
.options-checkbox {
	margin-left: 10px;
	padding-left: 20px;
	border-left: 3px solid #5e9cd5;
}
.options-checkbox li {
	margin-bottom: 6px;
}
.options-checkbox .disabled label {
	color: #aaa;
}
.option-form {
	clear: both;
	margin: 32px 0 10px;
	padding: 5px;
	background: rgba(255, 255, 255, .5);
	-webkit-border-radius: 4px;
	-moz-border-radius: 4px;
	-ms-border-radius: 4px;
	-o-border-radius: 4px;
	border-radius: 4px;
}
.option-form li {
	line-height: 32px;
}
.option-form li span {
	display: block;
	float: left;
	margin-top: 6px;
}
.option-form li .rename-map-name {
	padding: 0 5px;
	width: 39%;
	height: 22px;
	line-height: 22px;
	color: #ddd;
	text-align: right;
	background: #555;
	overflow: hidden;
	-webkit-border-radius: 3px 0 0 3px;
	-moz-border-radius: 3px 0 0 3px;
	-ms-border-radius: 3px 0 0 3px;
	-o-border-radius: 3px 0 0 3px;
	border-radius: 3px 0 0 3px;
}
.option-form li .rename-map-arrow {
	margin-right: 6px;
	width: 0;
	height: 0;
	border-top: 11px solid transparent;
	border-bottom: 11px solid transparent;
	border-left: 11px solid #555;
}
.option-form input.text {
	height: 20px;
	border: 0;
	-webkit-border-radius: 3px 0 0 3px;
	-moz-border-radius: 3px 0 0 3px;
	-ms-border-radius: 3px 0 0 3px;
	-o-border-radius: 3px 0 0 3px;
	border-radius: 3px 0 0 3px;
}
.option-form .form-input-submit {
	margin: 8px 0 4px;
	padding-top: 5px;
	text-align: right;
	border-top: 1px solid #ddd;
}
#form-move-map label,
#moveFolderForm label {
	display: block;
	margin: 12px 0 -2px 5px;
	padding: 5px;
	width: 95.6%;
	color: #ddd;
	background: #555;
	-webkit-border-radius: 3px 3px 0 0;
	-moz-border-radius: 3px 3px 0 0;
	-ms-border-radius: 3px 3px 0 0;
	-o-border-radius: 3px 3px 0 0;
	border-radius: 3px 3px 0 0;
}
#form-move-map select {
	width: 99%;
}
#renameFolderForm.option-form input.text {
	margin-top: 6px;
	height: auto;
	border: 1px solid #ddd;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-ms-border-radius: 5px;
	-o-border-radius: 5px;
	border-radius: 5px;
}
#renameFolderForm.option-form li .rename-map-name {
	height: 24px;
}
#renameFolderForm.option-form li .rename-map-arrow {
	border-top-width: 12px;
	border-bottom-width: 12px;
	border-left-width: 12px;
}
#moveFolderForm label {
	width: 94.6%;
	margin-left: 6px;
}
#moveFolderForm select {
	width: 100%;
	font-size: 13.3333px;
}

/* Option de type radio en ligne
---------------------------------*/
.options-radio-inline {
	margin-bottom: 30px;
	overflow: hidden;
}
.options-radio-inline li {
	display: block;
	float: left;
	padding: 5px;
	width: 177px;
	background: #eee;
	border: 1px solid #ddd;
	cursor: pointer;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-ms-border-radius: 5px;
	-o-border-radius: 5px;
	border-radius: 5px;
	-webkit-transition: all .2s;
	-moz-transition: all .2s;
	-ms-transition: all .2s;
	-o-transition: all .2s;
	transition: all .2s;
}
.options-radio-inline li:hover,
.options-radio-inline li.selected {
	background: #d9e8ff;
}
.options-radio-inline li +li {
	margin-left: 20px;
}
.options-radio-inline li input {
	float: left;
	margin: 0 0 0 8px;
	height: 32px;
}
.options-radio-inline li .name {
	float: left;
	margin-left: 9%;
	width: 70%;
	font-size: .8em;
}
.options-radio-inline li .name span {
	display: block;
	font-size: 1.2em;
	font-weight: bold;
}
.options-radio-inline li .icon {
	float: right;
}
.options-radio-inline li .icon .ui-icon {
	width: 14px;
	height: 14px;
	border: 1px solid transparent;
}
.options-radio-inline li .icon .ui-icon.active,
.options-radio-inline li .icon .ui-icon:hover {
	background-color: #ddd;
	border-color: #ccc;
	-webkit-border-radius: 3px;
	-moz-border-radius: 3px;
	-ms-border-radius: 3px;
	-o-border-radius: 3px;
	border-radius: 3px;
}


/* Contenu
-------------------------------*/
#content {
	clear: both;
	min-height: 559px;
}
.cadre {
	position: relative;
	margin-bottom: 25px;
	padding: 10px;
	background: #fff;
	border: 1px solid #ddd;
	overflow: hidden;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-ms-border-radius: 5px;
	-o-border-radius: 5px;
	border-radius: 5px;
}
.cadre.left {
	float: left;
	z-index: 10;
	width: 48%;
	-webkit-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
	-moz-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
	-ms-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
	-o-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
	box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
}
.cadre.right {
	float: right;
	z-index: 5;
	margin-left: -10px;
	padding-left: 20px;
	width: 47.5%;
	background: #fefefe;
	border-color: #dfdfdf;
}
.cadre.left.menu {
	width: 15%;
}
.cadre.middle.folders {
	float: left;
	z-index: 7;
	margin-left: -10px;
	padding-left: 18px;
	width: 17%;
	-webkit-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
	-moz-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
	-ms-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
	-o-box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
	box-shadow: 1px 0 3px rgba(0, 0, 0, .05);
}
.hasMenu .cadre.right {
	width: 80.5%;
}
.hasMenu.hasFolders .cadre.right {
	width: 61%;
}

.content {
	margin: 0 0 20px;
	background: #f9f9f9;
	border: 2px solid #f6f6f6;
	overflow: hidden;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-ms-border-radius: 5px;
	-o-border-radius: 5px;
	border-radius: 5px;
}
.content.last {
	margin: 0;
}
.content p {
	margin: 12px;
}
.content p a {
	color: #666;
	text-decoration: none;
	border-bottom: 1px solid #5e9cd5;
}
.content p a:hover {
	border: 0;
}


/* Footer
----------------------------*/
footer {
	clear: both;
	height: 50px;
	background: -webkit-linear-gradient(top, #f7f7f7 0%, #f2f2f2 100%);
	background: -moz-linear-gradient(top, #f7f7f7 0%, #f2f2f2 100%);
	background: -ms-linear-gradient(top, #f7f7f7 0%, #f2f2f2 100%);
	background: -o-linear-gradient(top, #f7f7f7 0%, #f2f2f2 100%);
	background: linear-gradient(top, #f7f7f7 0%, #f2f2f2 100%);
	border-top: 3px solid #eee;
}
#footer-inner {
	padding-top: 10px;
	color: #aaa;
	font-size: .8em;
	text-align: center;
}
#footer-inner a {
	color: #aaa;
	text-decoration: none;
}
#footer-inner a:hover {
	text-decoration: underline;
}


/* Page Config
---------------------- */
.section-config-addserver table .key {
	width: 200px;
}
.section-config-addserver table .value {
	width: 340px;
}
.section-config-addserver input.width3 {
	width: 90%;
}
.section-config-password input.width3 {
	width: 30%;
}
.section-config-servers table tbody tr,
.section-config-adminlevel table tbody tr {
	height: 22px;
}
.section-config-servers table tbody tr input,
.section-config-adminlevel table tbody tr input {
	margin-bottom: 4px;
}
.section-config-addlevel input.width3 {
	width: 29.4%;
}
.section-config-addlevel select {
	width: 31%;
}
.adminlevelSortableList td.value {
	padding: 0 20px;
	width: 40%;
	vertical-align: top;
}
.adminlevelSortableList .ui-sortable {
	position: relative;
	padding: 2px;
	min-height: 200px;
	background: #f9f9f9;
	border: 2px solid #f6f6f6;
	-webkit-border-radius: 3px;
	-moz-border-radius: 3px;
	-ms-border-radius: 3px;
	-o-border-radius: 3px;
	border-radius: 3px;
}
.adminlevelSortableList .ui-sortable:after {
	content: "";
	position: absolute;
	top: 90px;
	right: -20px;
	z-index: 5;
	width: 0;
	height: 0;
	border-style: solid;
	border-width: 10px 10px 10px 0;
	border-color: transparent #ccc transparent transparent;
}
.adminlevelSortableList #selectedAccess.ui-sortable:after,
.adminlevelSortableList #selectedPermission.ui-sortable:after {
	right: auto;
	left: -20px;
	border-width: 10px 0 10px 10px;
	border-color: transparent transparent transparent #ccc;
}
.adminlevelSortableList .ui-sortable li {
	margin: 0;
	padding: 3px 5px;
	min-height: 14px;
}


/* Page General
---------------------- */
.current_map {
	float: left;
	width: 70%;
}
#map_enviro img {
	margin: 0 0 -3px 5px;
}
#map_thumbnail {
	position: absolute;
	top: 0;
	right: 0;
	padding: 8px;
	min-width: 128px;
	min-height: 128px;
	background: #fff;
	border: 1px solid #ddd;
	border-width: 0 0 1px 1px;
	-webkit-border-radius: 0 5px;
	-moz-border-radius: 0 5px;
	-ms-border-radius: 0 5px;
	-o-border-radius: 0 5px;
	border-radius: 0 5px;
}
#map_thumbnail img {
	display: block;
	width: 128px;
}
#map_currentcallvote {
	display: block;
	width: 157%;
	height: 35px;
	line-height: 35px;
}
#CancelVote {
	float: right;
	margin-top: 3px;
}
#map_teamscore {
	display: block;
	padding: 5px 0 4px 9px;
	width: 160%;
	height: 28px;
}
#map_teamscore span {
	margin-top: 6px;
}
#map_teamscore .text {
	float: left;
	margin-top: 2px;
	width: 15%;
	text-align: center;
}
#ScoreTeamBlue {
	margin-right: 25px;
}
#ForceScores {
	float: right;
}
#playerlist {
	min-height: 433px;
}
.section-index .cadre.left {
	min-height: 511px;
}
.section-index .selected-files-option {
	top: auto;
	bottom: -25px;
	width: 50%;
}
.section-index .isTeamGameMode .selected-files-option {
	width: 75%;
}
.section-index .options input {
	margin-top: 10px;
}
.section-index .scriptName {
	color: #888;
	font-size: .85em;
}


/* Page Server options
---------------------- */
.section-srvopts tr,
.section-gameinfos tr {
	height: 30px;
}
.srvopts_general .serverComment textarea {
	height: 102px;
}
.srvopts_general .serverComment .key {
	padding-top: 5px;
	vertical-align: top;
}
.section-srvopts tr td.key:first-child {
	width: 22%;
}
.section-srvopts tr td.value.col2,
.section-srvopts tr td.key.col3 {
	width: 100px;
}
.section-srvopts .preview {
	padding: 5px 0 0 10px;
	width: 40%;
	text-align: left;
	vertical-align: top;
}
#CallVoteRatio {
	width: 12%;
}
.section-srvopts .srvopts_changeauthpassword select,
.section-srvopts .srvopts_changeauthpassword .text {
	float: left;
	width: 19.7%;
}
.section-srvopts .srvopts_changeauthpassword .changeauthpassword-arrow {
	display: block;
	float: left;
	margin: 6px 10px 6px 15px;
	width: 0;
	height: 0;
	border-style: solid;
	border-width: 7px 0 7px 20px;
	border-color: transparent transparent transparent rgba(0, 0, 0, .2);
}
.section-srvopts .returnDefaultValue {
	line-height: 12px;
	color: #aaa;
	font-size: .85em;
}
.section-srvopts .returnDefaultValue:hover {
	color: #888;
	text-decoration: none;
}
#ClientInputsMaxLatency,
#callVoteRatioDisabled {
	margin: 1px 12px 0 0;
	width: 22%;
}
#ClientInputsMaxLatencyValue,
#CallVoteRatio {
	margin: 1px 12px 0 0;
	width: 20.4%;
}
.srvopts_importexport input,
.srvopts_importexport select {
	float: left;
}
.srvopts_importexport input[type="radio"] {
	height: 21px;
}
.srvopts_importexport #srvoptsImportName,
.srvopts_importexport #srvoptsExportName {
	margin-left: 10px;
}


/* Page Game infos
---------------------- */
.section-gameinfos td.key,
.section-gameinfos td.value {
	width: 27%;
}
.section-gameinfos .preview,
.section-maps-creatematchset .preview {
	text-align: left;
}
.section-gameinfos .preview a,
.section-maps-creatematchset .preview a {
	display: block;
	line-height: 12px;
	color: #aaa;
	font-size: .85em;
}
.section-gameinfos .preview a:hover,
.section-maps-creatematchset .preview a:hover {
	color: #888;
	text-decoration: none;
}
.section-gameinfos .content.gameinfos {
	min-height: 500px;
}
#getScriptSettingsDialog {
	color: #666;
	font-size: .95em;
}
#getScriptSettingsDialog tr:hover,
#getScriptSettingsDialog td:hover {
	background: none;
	cursor: default;
}
#getScriptSettingsDialog td.key {
	width: 170px;
}
#getScriptSettingsDialog td.value {
	width: auto;
}
#dialogScriptSettings thead tr {
	height: 20px;
}
#dialogScriptSettings tbody td {
	border-bottom: 1px solid #f5f5f5;
}
#dialogScriptSettings tbody td.first {
	padding: 0 9px;
	width: 170px;
	text-align: right;
	border-right: 1px dotted #636363;
}
#dialogScriptSettings tbody td.middle {
	padding-left: 10px;
	width: 200px;
	text-align: left;
}
#dialogScriptSettings tbody td.last {
	font-style: italic;
	text-align: left;
}


/* Page Chat
---------------------- */
.section-chat #chat {
	min-height: 432px;
}
.section-chat #chat .tmnick_global {
	display: block;
	line-height: 17px;
	overflow: hidden;
}
.section-chat .options {
	padding: 6px 10px;
}
.section-chat .options input.text,
.section-chat .options select {
	float: left;
	margin-right: 20px;
	height: 20px;
	color: #aaa;
	border: 0;
	-webkit-border-radius: 3px 0 0 3px;
	-moz-border-radius: 3px 0 0 3px;
	-ms-border-radius: 3px 0 0 3px;
	-o-border-radius: 3px 0 0 3px;
	border-radius: 3px 0 0 3px;
	-webkit-box-shadow: 4px 0 0 #b0b0b0;
	-moz-box-shadow: 4px 0 0 #b0b0b0;
	-ms-box-shadow: 4px 0 0 #b0b0b0;
	-o-box-shadow: 4px 0 0 #b0b0b0;
	box-shadow: 4px 0 0 #b0b0b0;
}
.section-chat .options input.text:hover,
.section-chat .options select:hover,
.section-chat .options input.text:focus,
.section-chat .options select:focus {
	color: inherit;
}
.section-chat .options select {
	padding: 5px 5px 3px;
	height: 26px;
	font-size: .9em;
}
.section-chat #chatColor,
.section-chat #chatDestination,
.section-chat #chatSend {
	width: 12%;
}
.section-chat #chatNickname {
	width: 15%;
}
.section-chat #chatMessage {
	width: 38%;
}
.section-chat #chatSend {
	margin: 0;
}

/* Page Maps
----------------------- */
.menu .vertical-nav li a,
.folders .folder-list li a {
	display: block;
	padding: 8px 10px;
	height: auto;
	line-height: 14px;
	color: #888;
	font-size: 1.1em;
	font-weight: bold;
	font-variant: small-caps;
	text-decoration: none;
	border-bottom: 1px solid #d9e8ff;
	-webkit-border-radius: 2px;
	-moz-border-radius: 2px;
	-ms-border-radius: 2px;
	-o-border-radius: 2px;
	border-radius: 2px;
}
.menu .vertical-nav li:last-child a {
	border: 0;
}
.menu .vertical-nav li a.active,
.menu .vertical-nav li a:hover {
	color: #fff;
	background: #5e9cd5;
}

/* Dossiers */
.folders .title-detail {
	right: 15px;
	font-size: .8em;
}
.folders .folder-list {
	margin-bottom: 16px;
}
.folders .folder-list li a {
	padding: 6px 10px;
	border-bottom-color: #f4f398;
}
.folders .folder-list li a.active,
.folders .folder-list li a:hover {
	background: #f7f6b6;
}
.folders .folder-list li a .dir-name {
	font-size: .8em;
	font-variant: normal;
}
.folders .folder-list li a .dir-info {
	float: right;
	font-size: .8em;
	font-weight: normal;
}
.folders .folder-list li a img {
	margin: 0 7px -3px 0;
}
.folders .folder-list .no-result {
	padding: 8px 0;
	font-style: italic;
	text-align: center;
}
.path {
	width: 400px;
	text-align: right;
	white-space: nowrap;
	overflow: hidden;
}
/* Nouveau dossier */
#form-new-folder {
	display: block;
	margin: 6px 0;
}
#form-new-folder[hidden=hidden] {
	display: none !important;
}
#form-new-folder input.text {
	margin-right: 8px;
	width: 105px;
	height: 17px;
	vertical-align: top;
}
#form-new-folder input.button {
	padding: 2px;
}
/* Option de dossier */
.folders .option-folder-list h3 {
	cursor: pointer;
}
.folders .option-folder-list .arrow-down,
.folders .option-folder-list .arrow-up {
	display: block;
	float: right;
	margin: 5px 10px 0 0;
	width: 0;
	height: 0;
	border-style: solid;
}
.folders .option-folder-list .arrow-down {
	border-width: 5px 5px 0 5px;
	border-color: #5e9cd5 transparent transparent transparent;
}
.folders .option-folder-list .arrow-up {
	border-width: 0 5px 5px 5px;
	border-color: transparent transparent #5e9cd5 transparent;
}
.folders .option-folder-list li {
	margin-bottom: 1px;
}
.folders .option-folder-list a {
	display: block;
	padding-left: 30px;
	background-repeat: no-repeat;
	background-position: 5px center;
	border: 0;
}
.folders .option-folder-list a:hover {
	background-color: #999;
}
.folders .option-folder-list .button.light,
.folders .option-folder-list .button.light:hover {
	-webkit-box-shadow: none;
	-moz-box-shadow: none;
	-ms-box-shadow: none;
	-o-box-shadow: none;
	box-shadow: none;
}
.folders .option-folder-list .rename {
	background-image: url("../images/16/edit.png");
}
.folders .option-folder-list .move {
	background-image: url("../images/16/blue_arrow_up.png");
}
.folders .option-folder-list .delete {
	background-image: url("../images/16/delete.png");
}
#renameFolderForm {
	margin: 10% 0;
	height: 36px !important;
	overflow: hidden;
}
#moveFolderForm {
	margin: 10% 0;
	height: 72px !important;
	overflow: hidden;
}


/* Page Maps-local
------------------*/
.section-maps-local .options-checkbox {
	margin-top: 10px;
}
#renameFolderNewName {
	width: 50%;
}
#renameMapList {
	width: 53%;
}


/* Page upload
------------------*/
.section-maps-upload .path {
	margin-right: 5px;
}
.section-maps-upload .options-checkbox {
	margin-bottom: 30px;
}


/* Page Maps-Order
---------------------- */
.ui-sortable li {
	margin: 2px 0;
	padding: 5px;
	min-height: 17px;
	color: #666;
	font-weight: normal;
	overflow: hidden;
	cursor: pointer;
	-webkit-border-radius: 3px;
	-moz-border-radius: 3px;
	-ms-border-radius: 3px;
	-o-border-radius: 3px;
	border-radius: 3px;
}
.ui-sortable li:hover {
	background: #d9e8ff;
}
.ui-sortable li div {
	float: left;
}
.ui-sortable li .order-map-name,
.ui-sortable li .order-server-name {
	padding: 0 10px;
	width: 50%;
}
.ui-sortable li .order-server-name {
	font-weight: bold;
}
.ui-sortable li .order-server-addr-port,
.ui-sortable li .order-map-env,
.ui-sortable li .order-map-author {
	padding: 0 10px;
	width: 20%;
}
.ui-sortable li .order-map-env img,
.ui-sortable li .order-map-author img {
	margin: 0 5px -3px 0;
}
.autoSortMode.options-radio-inline li {
	width: 174px;
	color: #666;
}
.autoSortMode.options-radio-inline li .name {
	margin-top: 8px;
	width: 100px;
	font-size: .9em;
}


/* Page Maps Create MatchSettings
---------------------- */
#matchSettingName {
	width: 250px;
}
#matchSettingNameExists {
	float: right;
	margin: 4px 0;
	padding: 0 3px 0 2px;
	line-height: 16px;
	font-size: .85em;
	-webkit-border-radius: 3px;
	-moz-border-radius: 3px;
	-ms-border-radius: 3px;
	-o-border-radius: 3px;
	border-radius: 3px;
}
#matchSettingNameExists span {
	float: left;
	margin-right: 3px;
}
.section-maps-creatematchset td.key,
.section-maps-creatematchset td.value {
	width: 40%;
}
.section-maps-creatematchset .mapsSelection {
	margin: 10px 0 20px;
	height: 30px;
	overflow: hidden;
}
.section-maps-creatematchset .mapsSelection select {
	width: 200px;
}
.section-maps-creatematchset .mapsSelection input {
	float: right;
	margin-left: 10px;
}
.section-maps-creatematchset .mapsSelection input + input {
	margin: 0;
}
.section-maps-creatematchset .mapsSelected {
	padding-top: 10px;
	height: 30px;
	border-top: 1px solid #ddd;
	overflow: hidden;
}
.section-maps-creatematchset .mapsSelected p {
	float: left;
	margin: 4px 0 0;
}
.section-maps-creatematchset .mapsSelected input {
	float: right;
}
.section-maps-creatematchset #mapSelectionDialog tr {
	cursor: default;
}


/* Page plugins
--------------------*/
.section-plugins-list .content ul {
	margin: 12px 0;
	padding-left: 40px;
}
.section-plugins-list .content li {
	list-style-type: disc;
}


/* Page Guest-Ban
---------------------- */
#banlist,
#blacklist,
#guestlist,
#ignorelist,
#playlists {
	position: relative;
}
#banlist .title-detail,
#blacklist .title-detail,
#guestlist .title-detail,
#ignorelist .title-detail,
#playlists .title-detail {
	top: 4px;
	right: 0;
}
.section-guestban table {
	margin-bottom: 25px;
}
.section-guestban .addPlayer {
	margin-bottom: 25px;
	padding: 5px;
}
.section-guestban .addPlayer select,
.section-guestban .addPlayer .text {
	float: left;
	margin-right: 24px;
}
.section-guestban .addPlayer .text {
	width: 41%;
}
.section-guestban .addPlayer #addPlayerList {
	width: 44%;
}
.section-guestban .addPlayer .addPlayerTypeList {
	width: 120px;
}
.section-guestban .addPlayer .button {
	width: 90px;
	margin: 0;
}
#form-new-playlist {
	display: block;
	margin: 6px 0 8px;
}
#form-new-playlist[hidden=hidden] {
	display: none !important;
}
#form-new-playlist select {
	width: 120px;
	margin-right: 12px;
	padding: 3px 5px 2px;
	vertical-align: top;
}
#form-new-playlist .text {
	width: 202px;
	height: 17px;
	margin-right: 12px;
	vertical-align: top;
}
#form-new-playlist .button {
	width: 90px;
	font-size: .9em;
}

/* Couleurs GameMode & Jeux
----------------------------- */
.rounds {
	color: #ffcc11;
}
.timeattack {
	color: #d1321e;
}
.team {
	color: #aabb00;
}
.laps {
	color: #88aa11;
}
.stunts {
	color: #5600da;
}
.cup {
	color: #ff8c11;
}
.script,
.other {
	color: #444;
}
.maniaplanet {
	color: #2277cc;
}
.tmforever {
	color: #ad0000;
}
.team_-1,
.team_0,
.team_1 {
	display: block;
	float: left;
	margin-right: 5px;
	width: 7px;
	height: 16px;
	opacity: .8;
}
.team_-1 {
	background: #000;
}
.team_0 {
	background: #00f;
}
.team_1 {
	background: #f00;
}


/* TmNick
------------------------ */
.tmnick_global {
	font-weight: none;
	font-style: normal;
	letter-spacing: 0;
}
.tmnick_normal {
	letter-spacing: 0;
}
.tmnick_short {
	letter-spacing: -1px;
}
.tmnick_wide {
	letter-spacing: 2px;
}
.tmnick_raz {
	font-weight: none;
	font-style: normal;
	letter-spacing: 0;
}
.tmnick_italic {
	font-style: italic;
}
.tmnick_bold {
	font-weight: bold;
	letter-spacing: 1px;
}
.tmnick_upper {
	text-transform: uppercase;
}
.tmnick_shadowed {
	text-shadow: 1px 1px 1px #444;
}
.tmnick_internallink,
.tmnick_internallink:visited {
	color: inherit;
	text-decoration: none;
	border-bottom: 1px solid #000;
}
.tmnick_internallink:hover {
	color: inherit;
	text-decoration: none;
	border-bottom: 1px solid Blue;
}
.tmnick_internallink_withlogin,
.tmnick_internallink_withlogin:visited  {
	color: inherit;
	text-decoration: none;
	border-bottom: 1px solid #f0e68c;
}
.tmnick_internallink_withlogin:hover {
	color: inherit;
	text-decoration: none;
	border-bottom: 1px solid Gold;
}
.tmnick_externallink {
	line-height: 18px;
	color: inherit;
	text-decoration: none;
	border-bottom: 1px solid  #75481e;
}
.tmnick_externallink:hover {
	color: inherit;
	border-color: Orange;
}


/* ColorPicker
------------------------*/
.section-gameinfos .colorSelectorWrapper {
	float: right;
	position: relative;
}
.section-gameinfos .colorSelector {
	position: absolute;
	top: 0;
	right: 38px;
	border-width: 2px 0 2px 2px;
}
.colorSelector {
	position: relative;
	width: 20px;
	height: 20px;
	border: 2px solid #ddd;
	cursor: pointer;
}
.colorpicker {
	display: none;
	position: absolute;
	top: 22px;
	left: -2px;
	z-index: 1000;
	width: 47px;
	height: 169px;
	background: #ddd;
	overflow: hidden;
}
.colorpicker_hue {
	position: absolute;
	top: 9px;
	left: 6px;
	width: 35px;
	height: 150px;
	background: url("../images/colorpicker/slider.png") no-repeat center top;
	cursor: n-resize;
}
.colorpicker_hue > div {
	position: absolute;
	left: 0;
	margin: -4px 0 0;
	width: 35px;
	height: 9px;
	background: url("../images/colorpicker/picker.png") no-repeat;
	overflow: hidden;
}
.colorpicker_color,
.colorpicker_new_color,
.colorpicker_field,
.colorpicker_hex,
.colorpicker_submit,
.colorpicker_current_color {
	display: none;
}


/* DisplayServ
-------------------- */
#displayserv {
	width: 80%;
	margin: 20px auto 30px;
}


/* Danish
------------------------*/
html[lang="dk"] #connection-inner .connection-label {
	width: 85%;
}
html[lang="dk"] .section-servers-online-config fieldset {
	width: 575px;
}
.title-detail #detailMode {
	vertical-align: middle;
}
.title-detail .last input {
	margin-top: -3px;
}
.tmnick_shadowed {
	color: #666 !important;
}
.options-radio-inline li .name {
	width: 127px;
}
/*! jQuery UI - v1.10.3 - 2013-06-08
* http://jqueryui.com
* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%23727272&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%23727272&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%23727272&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%23727272&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%23727272&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23ccc&fcHighlight=%23444444&iconColorHighlight=%23727272&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */

/* Layout helpers
----------------------------------*/
.ui-helper-hidden {
	display: none;
}
.ui-helper-hidden-accessible {
	border: 0;
	clip: rect(0 0 0 0);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
}
.ui-helper-reset {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	line-height: 1.3;
	text-decoration: none;
	font-size: 100%;
	list-style: none;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
	content: "";
	display: table;
	border-collapse: collapse;
}
.ui-helper-clearfix:after {
	clear: both;
}
.ui-helper-clearfix {
	min-height: 0; /* support: IE7 */
}
.ui-helper-zfix {
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	position: absolute;
	opacity: 0;
	filter:Alpha(Opacity=0);
}

.ui-front {
	z-index: 100;
}


/* Interaction Cues
----------------------------------*/
.ui-state-disabled {
	cursor: default !important;
}


/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	display: block;
	text-indent: -99999px;
	overflow: hidden;
	background-repeat: no-repeat;
}


/* Misc visuals
----------------------------------*/

/* Overlays */
.ui-widget-overlay {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}
.ui-resizable {
	position: relative;
}
.ui-resizable-handle {
	position: absolute;
	font-size: 0.1px;
	display: block;
}
.ui-resizable-disabled .ui-resizable-handle,
.ui-resizable-autohide .ui-resizable-handle {
	display: none;
}
.ui-resizable-n {
	cursor: n-resize;
	height: 7px;
	width: 100%;
	top: -5px;
	left: 0;
}
.ui-resizable-s {
	cursor: s-resize;
	height: 7px;
	width: 100%;
	bottom: -5px;
	left: 0;
}
.ui-resizable-e {
	cursor: e-resize;
	width: 7px;
	right: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-w {
	cursor: w-resize;
	width: 7px;
	left: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-se {
	cursor: se-resize;
	width: 12px;
	height: 12px;
	right: 1px;
	bottom: 1px;
}
.ui-resizable-sw {
	cursor: sw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	bottom: -5px;
}
.ui-resizable-nw {
	cursor: nw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	top: -5px;
}
.ui-resizable-ne {
	cursor: ne-resize;
	width: 9px;
	height: 9px;
	right: -5px;
	top: -5px;
}
.ui-selectable-helper {
	position: absolute;
	z-index: 100;
	border: 1px dotted black;
}
.ui-accordion .ui-accordion-header {
	display: block;
	cursor: pointer;
	position: relative;
	margin-top: 2px;
	padding: .5em .5em .5em .7em;
	min-height: 0; /* support: IE7 */
}
.ui-accordion .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-noicons {
	padding-left: .7em;
}
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
	position: absolute;
	left: .5em;
	top: 50%;
	margin-top: -8px;
}
.ui-accordion .ui-accordion-content {
	padding: 1em 2.2em;
	border-top: 0;
	overflow: auto;
}
.ui-autocomplete {
	position: absolute;
	top: 0;
	left: 0;
	cursor: default;
}
.ui-button {
	display: inline-block;
	position: relative;
	padding: 0;
	line-height: normal;
	margin-right: .1em;
	cursor: pointer;
	vertical-align: middle;
	text-align: center;
	overflow: visible; /* removes extra width in IE */
}
.ui-button,
.ui-button:link,
.ui-button:visited,
.ui-button:hover,
.ui-button:active {
	text-decoration: none;
}
/* to make room for the icon, a width needs to be set here */
.ui-button-icon-only {
	width: 2.2em;
}
/* button elements seem to need a little more width */
button.ui-button-icon-only {
	width: 2.4em;
}
.ui-button-icons-only {
	width: 3.4em;
}
button.ui-button-icons-only {
	width: 3.7em;
}

/* button text element */
.ui-button .ui-button-text {
	display: block;
	line-height: normal;
}
.ui-button-text-only .ui-button-text {
	padding: .4em 1em;
}
.ui-button-icon-only .ui-button-text,
.ui-button-icons-only .ui-button-text {
	padding: .4em;
	text-indent: -9999999px;
}
.ui-button-text-icon-primary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 1em .4em 2.1em;
}
.ui-button-text-icon-secondary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 2.1em .4em 1em;
}
.ui-button-text-icons .ui-button-text {
	padding-left: 2.1em;
	padding-right: 2.1em;
}
/* no icon support for input elements, provide padding by default */
input.ui-button {
	padding: .4em 1em;
}

/* button icon element(s) */
.ui-button-icon-only .ui-icon,
.ui-button-text-icon-primary .ui-icon,
.ui-button-text-icon-secondary .ui-icon,
.ui-button-text-icons .ui-icon,
.ui-button-icons-only .ui-icon {
	position: absolute;
	top: 50%;
	margin-top: -8px;
}
.ui-button-icon-only .ui-icon {
	left: 50%;
	margin-left: -8px;
}
.ui-button-text-icon-primary .ui-button-icon-primary,
.ui-button-text-icons .ui-button-icon-primary,
.ui-button-icons-only .ui-button-icon-primary {
	left: .5em;
}
.ui-button-text-icon-secondary .ui-button-icon-secondary,
.ui-button-text-icons .ui-button-icon-secondary,
.ui-button-icons-only .ui-button-icon-secondary {
	right: .5em;
}

/* button sets */
.ui-buttonset {
	margin-right: 7px;
}
.ui-buttonset .ui-button {
	margin-left: 0;
	margin-right: -.3em;
}

/* workarounds */
/* reset extra padding in Firefox, see h5bp.com/l */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
	border: 0;
	padding: 0;
}
.ui-datepicker {
	width: 17em;
	padding: .2em .2em 0;
	display: none;
}
.ui-datepicker .ui-datepicker-header {
	position: relative;
	padding: .2em 0;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
	position: absolute;
	top: 2px;
	width: 1.8em;
	height: 1.8em;
}
.ui-datepicker .ui-datepicker-prev-hover,
.ui-datepicker .ui-datepicker-next-hover {
	top: 1px;
}
.ui-datepicker .ui-datepicker-prev {
	left: 2px;
}
.ui-datepicker .ui-datepicker-next {
	right: 2px;
}
.ui-datepicker .ui-datepicker-prev-hover {
	left: 1px;
}
.ui-datepicker .ui-datepicker-next-hover {
	right: 1px;
}
.ui-datepicker .ui-datepicker-prev span,
.ui-datepicker .ui-datepicker-next span {
	display: block;
	position: absolute;
	left: 50%;
	margin-left: -8px;
	top: 50%;
	margin-top: -8px;
}
.ui-datepicker .ui-datepicker-title {
	margin: 0 2.3em;
	line-height: 1.8em;
	text-align: center;
}
.ui-datepicker .ui-datepicker-title select {
	font-size: 1em;
	margin: 1px 0;
}
.ui-datepicker select.ui-datepicker-month-year {
	width: 100%;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
	width: 49%;
}
.ui-datepicker table {
	width: 100%;
	font-size: .9em;
	border-collapse: collapse;
	margin: 0 0 .4em;
}
.ui-datepicker th {
	padding: .7em .3em;
	text-align: center;
	font-weight: bold;
	border: 0;
}
.ui-datepicker td {
	border: 0;
	padding: 1px;
}
.ui-datepicker td span,
.ui-datepicker td a {
	display: block;
	padding: .2em;
	text-align: right;
	text-decoration: none;
}
.ui-datepicker .ui-datepicker-buttonpane {
	background-image: none;
	margin: .7em 0 0 0;
	padding: 0 .2em;
	border-left: 0;
	border-right: 0;
	border-bottom: 0;
}
.ui-datepicker .ui-datepicker-buttonpane button {
	float: right;
	margin: .5em .2em .4em;
	cursor: pointer;
	padding: .2em .6em .3em .6em;
	width: auto;
	overflow: visible;
}
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
	float: left;
}

/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi {
	width: auto;
}
.ui-datepicker-multi .ui-datepicker-group {
	float: left;
}
.ui-datepicker-multi .ui-datepicker-group table {
	width: 95%;
	margin: 0 auto .4em;
}
.ui-datepicker-multi-2 .ui-datepicker-group {
	width: 50%;
}
.ui-datepicker-multi-3 .ui-datepicker-group {
	width: 33.3%;
}
.ui-datepicker-multi-4 .ui-datepicker-group {
	width: 25%;
}
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
	border-left-width: 0;
}
.ui-datepicker-multi .ui-datepicker-buttonpane {
	clear: left;
}
.ui-datepicker-row-break {
	clear: both;
	width: 100%;
	font-size: 0;
}

/* RTL support */
.ui-datepicker-rtl {
	direction: rtl;
}
.ui-datepicker-rtl .ui-datepicker-prev {
	right: 2px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next {
	left: 2px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-prev:hover {
	right: 1px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next:hover {
	left: 1px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane {
	clear: right;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
	float: left;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
.ui-datepicker-rtl .ui-datepicker-group {
	float: right;
}
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
	border-right-width: 0;
	border-left-width: 1px;
}
.ui-dialog {
	position: absolute;
	top: 0;
	left: 0;
	padding: .2em;
	outline: 0;
}
.ui-dialog .ui-dialog-titlebar {
	padding: .4em 1em;
	position: relative;
}
.ui-dialog .ui-dialog-title {
	float: left;
	margin: .1em 0;
	white-space: nowrap;
	width: 90%;
	overflow: hidden;
	text-overflow: ellipsis;
}
.ui-dialog .ui-dialog-titlebar-close {
	position: absolute;
	right: .3em;
	top: 50%;
	width: 21px;
	margin: -10px 0 0 0;
	padding: 1px;
	height: 20px;
}
.ui-dialog .ui-dialog-content {
	position: relative;
	border: 0;
	padding: .5em 1em;
	background: none;
	overflow: auto;
}
.ui-dialog .ui-dialog-buttonpane {
	text-align: left;
	border-width: 1px 0 0 0;
	background-image: none;
	margin-top: .5em;
	padding: .3em 1em .5em .4em;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
	float: right;
}
.ui-dialog .ui-dialog-buttonpane button {
	margin: .5em .4em .5em 0;
	cursor: pointer;
}
.ui-dialog .ui-resizable-se {
	width: 12px;
	height: 12px;
	right: -5px;
	bottom: -5px;
	background-position: 16px 16px;
}
.ui-draggable .ui-dialog-titlebar {
	cursor: move;
}
.ui-menu {
	list-style: none;
	padding: 2px;
	margin: 0;
	display: block;
	outline: none;
}
.ui-menu .ui-menu {
	margin-top: -3px;
	position: absolute;
}
.ui-menu .ui-menu-item {
	margin: 0;
	padding: 0;
	width: 100%;
	/* support: IE10, see #8844 */
	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}
.ui-menu .ui-menu-divider {
	margin: 5px -2px 5px -2px;
	height: 0;
	font-size: 0;
	line-height: 0;
	border-width: 1px 0 0 0;
}
.ui-menu .ui-menu-item a {
	text-decoration: none;
	display: block;
	padding: 2px .4em;
	line-height: 1.5;
	min-height: 0; /* support: IE7 */
	font-weight: normal;
}
.ui-menu .ui-menu-item a.ui-state-focus,
.ui-menu .ui-menu-item a.ui-state-active {
	font-weight: normal;
	margin: -1px;
}

.ui-menu .ui-state-disabled {
	font-weight: normal;
	margin: .4em 0 .2em;
	line-height: 1.5;
}
.ui-menu .ui-state-disabled a {
	cursor: default;
}

/* icon support */
.ui-menu-icons {
	position: relative;
}
.ui-menu-icons .ui-menu-item a {
	position: relative;
	padding-left: 2em;
}

/* left-aligned */
.ui-menu .ui-icon {
	position: absolute;
	top: .2em;
	left: .2em;
}

/* right-aligned */
.ui-menu .ui-menu-icon {
	position: static;
	float: right;
}
.ui-progressbar {
	height: 2em;
	text-align: left;
	overflow: hidden;
}
.ui-progressbar .ui-progressbar-value {
	margin: -1px;
	height: 100%;
}
.ui-progressbar .ui-progressbar-overlay {
	background: url("../../images/jqueryui/black/animated-overlay.gif");
	height: 100%;
	filter: alpha(opacity=25);
	opacity: 0.25;
}
.ui-progressbar-indeterminate .ui-progressbar-value {
	background-image: none;
}
.ui-slider {
	position: relative;
	text-align: left;
}
.ui-slider .ui-slider-handle {
	position: absolute;
	z-index: 2;
	width: 1.2em;
	height: 1.2em;
	cursor: default;
}
.ui-slider .ui-slider-range {
	position: absolute;
	z-index: 1;
	font-size: .7em;
	display: block;
	border: 0;
	background-position: 0 0;
}

/* For IE8 - See #6727 */
.ui-slider.ui-state-disabled .ui-slider-handle,
.ui-slider.ui-state-disabled .ui-slider-range {
	filter: inherit;
}

.ui-slider-horizontal {
	height: .8em;
}
.ui-slider-horizontal .ui-slider-handle {
	top: -.3em;
	margin-left: -.6em;
}
.ui-slider-horizontal .ui-slider-range {
	top: 0;
	height: 100%;
}
.ui-slider-horizontal .ui-slider-range-min {
	left: 0;
}
.ui-slider-horizontal .ui-slider-range-max {
	right: 0;
}

.ui-slider-vertical {
	width: .8em;
	height: 100px;
}
.ui-slider-vertical .ui-slider-handle {
	left: -.3em;
	margin-left: 0;
	margin-bottom: -.6em;
}
.ui-slider-vertical .ui-slider-range {
	left: 0;
	width: 100%;
}
.ui-slider-vertical .ui-slider-range-min {
	bottom: 0;
}
.ui-slider-vertical .ui-slider-range-max {
	top: 0;
}
.ui-spinner {
	position: relative;
	display: inline-block;
	overflow: hidden;
	padding: 0;
	vertical-align: middle;
}
.ui-spinner-input {
	border: none;
	background: none;
	color: inherit;
	padding: 0;
	margin: .2em 0;
	vertical-align: middle;
	margin-left: .4em;
	margin-right: 22px;
}
.ui-spinner-button {
	width: 16px;
	height: 50%;
	font-size: .5em;
	padding: 0;
	margin: 0;
	text-align: center;
	position: absolute;
	cursor: default;
	display: block;
	overflow: hidden;
	right: 0;
}
/* more specificity required here to overide default borders */
.ui-spinner a.ui-spinner-button {
	border-top: none;
	border-bottom: none;
	border-right: none;
}
/* vertical centre icon */
.ui-spinner .ui-icon {
	position: absolute;
	margin-top: -8px;
	top: 50%;
	left: 0;
}
.ui-spinner-up {
	top: 0;
}
.ui-spinner-down {
	bottom: 0;
}

/* TR overrides */
.ui-spinner .ui-icon-triangle-1-s {
	/* need to fix icons sprite */
	background-position: -65px -16px;
}
.ui-tabs {
	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
	padding: .2em;
}
.ui-tabs .ui-tabs-nav {
	margin: 0;
	padding: .2em .2em 0;
}
.ui-tabs .ui-tabs-nav li {
	list-style: none;
	float: left;
	position: relative;
	top: 0;
	margin: 1px .2em 0 0;
	border-bottom-width: 0;
	padding: 0;
	white-space: nowrap;
}
.ui-tabs .ui-tabs-nav li a {
	float: left;
	padding: .5em 1em;
	text-decoration: none;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
	margin-bottom: -1px;
	padding-bottom: 1px;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
	cursor: text;
}
.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
	cursor: pointer;
}
.ui-tabs .ui-tabs-panel {
	display: block;
	border-width: 0;
	padding: 1em 1.4em;
	background: none;
}
.ui-tooltip {
	padding: 8px;
	position: absolute;
	z-index: 9999;
	max-width: 300px;
	-webkit-box-shadow: 0 0 5px #aaa;
	box-shadow: 0 0 5px #aaa;
}
body .ui-tooltip {
	border-width: 2px;
}

/* Component containers
----------------------------------*/
.ui-widget {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1.1em;
}
.ui-widget .ui-widget {
	font-size: 1em;
}
.ui-widget input,
.ui-widget select,
.ui-widget textarea,
.ui-widget button {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1em;
}
.ui-widget-content {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/black/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-widget-content a {
	color: #444444;
}
.ui-widget-header {
	border: 1px solid #dddddd;
	background: #dddddd url("../../images/jqueryui/black/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
	color: #444444;
	font-weight: bold;
}
.ui-widget-header a {
	color: #444444;
}

/* Interaction states
----------------------------------*/
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
	border: 1px solid #dddddd;
	background: #f6f6f6 url("../../images/jqueryui/black/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #444;
}
.ui-state-default a,
.ui-state-default a:link,
.ui-state-default a:visited {
	color: #444;
	text-decoration: none;
}
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus {
	border: 1px solid #727272;
	background: #727272 url("../../images/jqueryui/black/ui-bg_highlight-soft_25_727272_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #ffffff;
}
.ui-state-hover a,
.ui-state-hover a:hover,
.ui-state-hover a:link,
.ui-state-hover a:visited {
	color: #ffffff;
	text-decoration: none;
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/black/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #727272;
}
.ui-state-active a,
.ui-state-active a:link,
.ui-state-active a:visited {
	color: #727272;
	text-decoration: none;
}

/* Interaction Cues
----------------------------------*/
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
	border: 1px solid #ccc;
	background: #ffffff url("../../images/jqueryui/black/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-state-highlight a,
.ui-widget-content .ui-state-highlight a,
.ui-widget-header .ui-state-highlight a {
	color: #444444;
}
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-widget-header .ui-state-error {
	border: 1px solid #EA4F4F;
	background: #ffffff url("../../images/jqueryui/black/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #222222;
}
.ui-state-error a,
.ui-widget-content .ui-state-error a,
.ui-widget-header .ui-state-error a {
	color: #222222;
}
.ui-state-error-text,
.ui-widget-content .ui-state-error-text,
.ui-widget-header .ui-state-error-text {
	color: #222222;
}
.ui-priority-primary,
.ui-widget-content .ui-priority-primary,
.ui-widget-header .ui-priority-primary {
	font-weight: bold;
}
.ui-priority-secondary,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
	opacity: .7;
	filter:Alpha(Opacity=70);
	font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
	opacity: .35;
	filter:Alpha(Opacity=35);
	background-image: none;
}
.ui-state-disabled .ui-icon {
	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
}

/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	width: 16px;
	height: 16px;
}
.ui-icon,
.ui-widget-content .ui-icon {
	background-image: url("../../images/jqueryui/black/ui-icons_727272_256x240.png");
}
.ui-widget-header .ui-icon {
	background-image: url("../../images/jqueryui/black/ui-icons_727272_256x240.png");
}
.ui-state-default .ui-icon {
	background-image: url("../../images/jqueryui/black/ui-icons_666666_256x240.png");
}
.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon {
	background-image: url("../../images/jqueryui/black/ui-icons_ffffff_256x240.png");
}
.ui-state-active .ui-icon {
	background-image: url("../../images/jqueryui/black/ui-icons_454545_256x240.png");
}
.ui-state-highlight .ui-icon {
	background-image: url("../../images/jqueryui/black/ui-icons_727272_256x240.png");
}
.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon {
	background-image: url("../../images/jqueryui/black/ui-icons_EA4F4F_256x240.png");
}

/* positioning */
.ui-icon-blank { background-position: 16px 16px; }
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -97px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-on { background-position: -96px -144px; }
.ui-icon-radio-off { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }


/* Misc visuals
----------------------------------*/

/* Corner radius */
.ui-corner-all,
.ui-corner-top,
.ui-corner-left,
.ui-corner-tl {
	border-top-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-top,
.ui-corner-right,
.ui-corner-tr {
	border-top-right-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-left,
.ui-corner-bl {
	border-bottom-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-right,
.ui-corner-br {
	border-bottom-right-radius: 2px;
}

/* Overlays */
.ui-widget-overlay {
	background: #eeeeee url("../../images/jqueryui/black/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
	opacity: .8;
	filter: Alpha(Opacity=80);
}
.ui-widget-shadow {
	margin: -4px 0 0 -4px;
	padding: 4px;
	background: #aaaaaa url("../../images/jqueryui/black/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
	opacity: .6;
	filter: Alpha(Opacity=60);
	border-radius: 0px;
}
/*! jQuery UI - v1.10.3 - 2013-06-08
* http://jqueryui.com
* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%235e9cd5&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%235e9cd5&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%235e9cd5&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%235e9cd5&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%235e9cd5&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23cccccc&fcHighlight=%23444444&iconColorHighlight=%235e9cd5&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */

/* Layout helpers
----------------------------------*/
.ui-helper-hidden {
	display: none;
}
.ui-helper-hidden-accessible {
	border: 0;
	clip: rect(0 0 0 0);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
}
.ui-helper-reset {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	line-height: 1.3;
	text-decoration: none;
	font-size: 100%;
	list-style: none;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
	content: "";
	display: table;
	border-collapse: collapse;
}
.ui-helper-clearfix:after {
	clear: both;
}
.ui-helper-clearfix {
	min-height: 0; /* support: IE7 */
}
.ui-helper-zfix {
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	position: absolute;
	opacity: 0;
	filter:Alpha(Opacity=0);
}

.ui-front {
	z-index: 100;
}


/* Interaction Cues
----------------------------------*/
.ui-state-disabled {
	cursor: default !important;
}


/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	display: block;
	text-indent: -99999px;
	overflow: hidden;
	background-repeat: no-repeat;
}


/* Misc visuals
----------------------------------*/

/* Overlays */
.ui-widget-overlay {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}
.ui-resizable {
	position: relative;
}
.ui-resizable-handle {
	position: absolute;
	font-size: 0.1px;
	display: block;
}
.ui-resizable-disabled .ui-resizable-handle,
.ui-resizable-autohide .ui-resizable-handle {
	display: none;
}
.ui-resizable-n {
	cursor: n-resize;
	height: 7px;
	width: 100%;
	top: -5px;
	left: 0;
}
.ui-resizable-s {
	cursor: s-resize;
	height: 7px;
	width: 100%;
	bottom: -5px;
	left: 0;
}
.ui-resizable-e {
	cursor: e-resize;
	width: 7px;
	right: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-w {
	cursor: w-resize;
	width: 7px;
	left: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-se {
	cursor: se-resize;
	width: 12px;
	height: 12px;
	right: 1px;
	bottom: 1px;
}
.ui-resizable-sw {
	cursor: sw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	bottom: -5px;
}
.ui-resizable-nw {
	cursor: nw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	top: -5px;
}
.ui-resizable-ne {
	cursor: ne-resize;
	width: 9px;
	height: 9px;
	right: -5px;
	top: -5px;
}
.ui-selectable-helper {
	position: absolute;
	z-index: 100;
	border: 1px dotted black;
}
.ui-accordion .ui-accordion-header {
	display: block;
	cursor: pointer;
	position: relative;
	margin-top: 2px;
	padding: .5em .5em .5em .7em;
	min-height: 0; /* support: IE7 */
}
.ui-accordion .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-noicons {
	padding-left: .7em;
}
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
	position: absolute;
	left: .5em;
	top: 50%;
	margin-top: -8px;
}
.ui-accordion .ui-accordion-content {
	padding: 1em 2.2em;
	border-top: 0;
	overflow: auto;
}
.ui-autocomplete {
	position: absolute;
	top: 0;
	left: 0;
	cursor: default;
}
.ui-button {
	display: inline-block;
	position: relative;
	padding: 0;
	line-height: normal;
	margin-right: .1em;
	cursor: pointer;
	vertical-align: middle;
	text-align: center;
	overflow: visible; /* removes extra width in IE */
}
.ui-button,
.ui-button:link,
.ui-button:visited,
.ui-button:hover,
.ui-button:active {
	text-decoration: none;
}
/* to make room for the icon, a width needs to be set here */
.ui-button-icon-only {
	width: 2.2em;
}
/* button elements seem to need a little more width */
button.ui-button-icon-only {
	width: 2.4em;
}
.ui-button-icons-only {
	width: 3.4em;
}
button.ui-button-icons-only {
	width: 3.7em;
}

/* button text element */
.ui-button .ui-button-text {
	display: block;
	line-height: normal;
}
.ui-button-text-only .ui-button-text {
	padding: .4em 1em;
}
.ui-button-icon-only .ui-button-text,
.ui-button-icons-only .ui-button-text {
	padding: .4em;
	text-indent: -9999999px;
}
.ui-button-text-icon-primary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 1em .4em 2.1em;
}
.ui-button-text-icon-secondary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 2.1em .4em 1em;
}
.ui-button-text-icons .ui-button-text {
	padding-left: 2.1em;
	padding-right: 2.1em;
}
/* no icon support for input elements, provide padding by default */
input.ui-button {
	padding: .4em 1em;
}

/* button icon element(s) */
.ui-button-icon-only .ui-icon,
.ui-button-text-icon-primary .ui-icon,
.ui-button-text-icon-secondary .ui-icon,
.ui-button-text-icons .ui-icon,
.ui-button-icons-only .ui-icon {
	position: absolute;
	top: 50%;
	margin-top: -8px;
}
.ui-button-icon-only .ui-icon {
	left: 50%;
	margin-left: -8px;
}
.ui-button-text-icon-primary .ui-button-icon-primary,
.ui-button-text-icons .ui-button-icon-primary,
.ui-button-icons-only .ui-button-icon-primary {
	left: .5em;
}
.ui-button-text-icon-secondary .ui-button-icon-secondary,
.ui-button-text-icons .ui-button-icon-secondary,
.ui-button-icons-only .ui-button-icon-secondary {
	right: .5em;
}

/* button sets */
.ui-buttonset {
	margin-right: 7px;
}
.ui-buttonset .ui-button {
	margin-left: 0;
	margin-right: -.3em;
}

/* workarounds */
/* reset extra padding in Firefox, see h5bp.com/l */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
	border: 0;
	padding: 0;
}
.ui-datepicker {
	width: 17em;
	padding: .2em .2em 0;
	display: none;
}
.ui-datepicker .ui-datepicker-header {
	position: relative;
	padding: .2em 0;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
	position: absolute;
	top: 2px;
	width: 1.8em;
	height: 1.8em;
}
.ui-datepicker .ui-datepicker-prev-hover,
.ui-datepicker .ui-datepicker-next-hover {
	top: 1px;
}
.ui-datepicker .ui-datepicker-prev {
	left: 2px;
}
.ui-datepicker .ui-datepicker-next {
	right: 2px;
}
.ui-datepicker .ui-datepicker-prev-hover {
	left: 1px;
}
.ui-datepicker .ui-datepicker-next-hover {
	right: 1px;
}
.ui-datepicker .ui-datepicker-prev span,
.ui-datepicker .ui-datepicker-next span {
	display: block;
	position: absolute;
	left: 50%;
	margin-left: -8px;
	top: 50%;
	margin-top: -8px;
}
.ui-datepicker .ui-datepicker-title {
	margin: 0 2.3em;
	line-height: 1.8em;
	text-align: center;
}
.ui-datepicker .ui-datepicker-title select {
	font-size: 1em;
	margin: 1px 0;
}
.ui-datepicker select.ui-datepicker-month-year {
	width: 100%;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
	width: 49%;
}
.ui-datepicker table {
	width: 100%;
	font-size: .9em;
	border-collapse: collapse;
	margin: 0 0 .4em;
}
.ui-datepicker th {
	padding: .7em .3em;
	text-align: center;
	font-weight: bold;
	border: 0;
}
.ui-datepicker td {
	border: 0;
	padding: 1px;
}
.ui-datepicker td span,
.ui-datepicker td a {
	display: block;
	padding: .2em;
	text-align: right;
	text-decoration: none;
}
.ui-datepicker .ui-datepicker-buttonpane {
	background-image: none;
	margin: .7em 0 0 0;
	padding: 0 .2em;
	border-left: 0;
	border-right: 0;
	border-bottom: 0;
}
.ui-datepicker .ui-datepicker-buttonpane button {
	float: right;
	margin: .5em .2em .4em;
	cursor: pointer;
	padding: .2em .6em .3em .6em;
	width: auto;
	overflow: visible;
}
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
	float: left;
}

/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi {
	width: auto;
}
.ui-datepicker-multi .ui-datepicker-group {
	float: left;
}
.ui-datepicker-multi .ui-datepicker-group table {
	width: 95%;
	margin: 0 auto .4em;
}
.ui-datepicker-multi-2 .ui-datepicker-group {
	width: 50%;
}
.ui-datepicker-multi-3 .ui-datepicker-group {
	width: 33.3%;
}
.ui-datepicker-multi-4 .ui-datepicker-group {
	width: 25%;
}
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
	border-left-width: 0;
}
.ui-datepicker-multi .ui-datepicker-buttonpane {
	clear: left;
}
.ui-datepicker-row-break {
	clear: both;
	width: 100%;
	font-size: 0;
}

/* RTL support */
.ui-datepicker-rtl {
	direction: rtl;
}
.ui-datepicker-rtl .ui-datepicker-prev {
	right: 2px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next {
	left: 2px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-prev:hover {
	right: 1px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next:hover {
	left: 1px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane {
	clear: right;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
	float: left;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
.ui-datepicker-rtl .ui-datepicker-group {
	float: right;
}
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
	border-right-width: 0;
	border-left-width: 1px;
}
.ui-dialog {
	position: absolute;
	top: 0;
	left: 0;
	padding: .2em;
	outline: 0;
}
.ui-dialog .ui-dialog-titlebar {
	padding: .4em 1em;
	position: relative;
}
.ui-dialog .ui-dialog-title {
	float: left;
	margin: .1em 0;
	white-space: nowrap;
	width: 90%;
	overflow: hidden;
	text-overflow: ellipsis;
}
.ui-dialog .ui-dialog-titlebar-close {
	position: absolute;
	right: .3em;
	top: 50%;
	width: 21px;
	margin: -10px 0 0 0;
	padding: 1px;
	height: 20px;
}
.ui-dialog .ui-dialog-content {
	position: relative;
	border: 0;
	padding: .5em 1em;
	background: none;
	overflow: auto;
}
.ui-dialog .ui-dialog-buttonpane {
	text-align: left;
	border-width: 1px 0 0 0;
	background-image: none;
	margin-top: .5em;
	padding: .3em 1em .5em .4em;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
	float: right;
}
.ui-dialog .ui-dialog-buttonpane button {
	margin: .5em .4em .5em 0;
	cursor: pointer;
}
.ui-dialog .ui-resizable-se {
	width: 12px;
	height: 12px;
	right: -5px;
	bottom: -5px;
	background-position: 16px 16px;
}
.ui-draggable .ui-dialog-titlebar {
	cursor: move;
}
.ui-menu {
	list-style: none;
	padding: 2px;
	margin: 0;
	display: block;
	outline: none;
}
.ui-menu .ui-menu {
	margin-top: -3px;
	position: absolute;
}
.ui-menu .ui-menu-item {
	margin: 0;
	padding: 0;
	width: 100%;
	/* support: IE10, see #8844 */
	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}
.ui-menu .ui-menu-divider {
	margin: 5px -2px 5px -2px;
	height: 0;
	font-size: 0;
	line-height: 0;
	border-width: 1px 0 0 0;
}
.ui-menu .ui-menu-item a {
	text-decoration: none;
	display: block;
	padding: 2px .4em;
	line-height: 1.5;
	min-height: 0; /* support: IE7 */
	font-weight: normal;
}
.ui-menu .ui-menu-item a.ui-state-focus,
.ui-menu .ui-menu-item a.ui-state-active {
	font-weight: normal;
	margin: -1px;
}

.ui-menu .ui-state-disabled {
	font-weight: normal;
	margin: .4em 0 .2em;
	line-height: 1.5;
}
.ui-menu .ui-state-disabled a {
	cursor: default;
}

/* icon support */
.ui-menu-icons {
	position: relative;
}
.ui-menu-icons .ui-menu-item a {
	position: relative;
	padding-left: 2em;
}

/* left-aligned */
.ui-menu .ui-icon {
	position: absolute;
	top: .2em;
	left: .2em;
}

/* right-aligned */
.ui-menu .ui-menu-icon {
	position: static;
	float: right;
}
.ui-progressbar {
	height: 2em;
	text-align: left;
	overflow: hidden;
}
.ui-progressbar .ui-progressbar-value {
	margin: -1px;
	height: 100%;
}
.ui-progressbar .ui-progressbar-overlay {
	background: url("../../images/jqueryui/blue/animated-overlay.gif");
	height: 100%;
	filter: alpha(opacity=25);
	opacity: 0.25;
}
.ui-progressbar-indeterminate .ui-progressbar-value {
	background-image: none;
}
.ui-slider {
	position: relative;
	text-align: left;
}
.ui-slider .ui-slider-handle {
	position: absolute;
	z-index: 2;
	width: 1.2em;
	height: 1.2em;
	cursor: default;
}
.ui-slider .ui-slider-range {
	position: absolute;
	z-index: 1;
	font-size: .7em;
	display: block;
	border: 0;
	background-position: 0 0;
}

/* For IE8 - See #6727 */
.ui-slider.ui-state-disabled .ui-slider-handle,
.ui-slider.ui-state-disabled .ui-slider-range {
	filter: inherit;
}

.ui-slider-horizontal {
	height: .8em;
}
.ui-slider-horizontal .ui-slider-handle {
	top: -.3em;
	margin-left: -.6em;
}
.ui-slider-horizontal .ui-slider-range {
	top: 0;
	height: 100%;
}
.ui-slider-horizontal .ui-slider-range-min {
	left: 0;
}
.ui-slider-horizontal .ui-slider-range-max {
	right: 0;
}

.ui-slider-vertical {
	width: .8em;
	height: 100px;
}
.ui-slider-vertical .ui-slider-handle {
	left: -.3em;
	margin-left: 0;
	margin-bottom: -.6em;
}
.ui-slider-vertical .ui-slider-range {
	left: 0;
	width: 100%;
}
.ui-slider-vertical .ui-slider-range-min {
	bottom: 0;
}
.ui-slider-vertical .ui-slider-range-max {
	top: 0;
}
.ui-spinner {
	position: relative;
	display: inline-block;
	overflow: hidden;
	padding: 0;
	vertical-align: middle;
}
.ui-spinner-input {
	border: none;
	background: none;
	color: inherit;
	padding: 0;
	margin: .2em 0;
	vertical-align: middle;
	margin-left: .4em;
	margin-right: 22px;
}
.ui-spinner-button {
	width: 16px;
	height: 50%;
	font-size: .5em;
	padding: 0;
	margin: 0;
	text-align: center;
	position: absolute;
	cursor: default;
	display: block;
	overflow: hidden;
	right: 0;
}
/* more specificity required here to overide default borders */
.ui-spinner a.ui-spinner-button {
	border-top: none;
	border-bottom: none;
	border-right: none;
}
/* vertical centre icon */
.ui-spinner .ui-icon {
	position: absolute;
	margin-top: -8px;
	top: 50%;
	left: 0;
}
.ui-spinner-up {
	top: 0;
}
.ui-spinner-down {
	bottom: 0;
}

/* TR overrides */
.ui-spinner .ui-icon-triangle-1-s {
	/* need to fix icons sprite */
	background-position: -65px -16px;
}
.ui-tabs {
	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
	padding: .2em;
}
.ui-tabs .ui-tabs-nav {
	margin: 0;
	padding: .2em .2em 0;
}
.ui-tabs .ui-tabs-nav li {
	list-style: none;
	float: left;
	position: relative;
	top: 0;
	margin: 1px .2em 0 0;
	border-bottom-width: 0;
	padding: 0;
	white-space: nowrap;
}
.ui-tabs .ui-tabs-nav li a {
	float: left;
	padding: .5em 1em;
	text-decoration: none;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
	margin-bottom: -1px;
	padding-bottom: 1px;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
	cursor: text;
}
.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
	cursor: pointer;
}
.ui-tabs .ui-tabs-panel {
	display: block;
	border-width: 0;
	padding: 1em 1.4em;
	background: none;
}
.ui-tooltip {
	padding: 8px;
	position: absolute;
	z-index: 9999;
	max-width: 300px;
	-webkit-box-shadow: 0 0 5px #aaa;
	box-shadow: 0 0 5px #aaa;
}
body .ui-tooltip {
	border-width: 2px;
}

/* Component containers
----------------------------------*/
.ui-widget {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1.1em;
}
.ui-widget .ui-widget {
	font-size: 1em;
}
.ui-widget input,
.ui-widget select,
.ui-widget textarea,
.ui-widget button {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1em;
}
.ui-widget-content {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/blue/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-widget-content a {
	color: #444444;
}
.ui-widget-header {
	border: 1px solid #dddddd;
	background: #dddddd url("../../images/jqueryui/blue/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
	color: #444444;
	font-weight: bold;
}
.ui-widget-header a {
	color: #444444;
}

/* Interaction states
----------------------------------*/
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
	border: 1px solid #dddddd;
	background: #f6f6f6 url("../../images/jqueryui/blue/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #444;
}
.ui-state-default a,
.ui-state-default a:link,
.ui-state-default a:visited {
	color: #444;
	text-decoration: none;
}
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus {
	border: 1px solid #5e9cd5;
	background: #5e9cd5 url("../../images/jqueryui/blue/ui-bg_highlight-soft_25_5e9cd5_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #ffffff;
}
.ui-state-hover a,
.ui-state-hover a:hover,
.ui-state-hover a:link,
.ui-state-hover a:visited {
	color: #ffffff;
	text-decoration: none;
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/blue/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #5e9cd5;
}
.ui-state-active a,
.ui-state-active a:link,
.ui-state-active a:visited {
	color: #5e9cd5;
	text-decoration: none;
}

/* Interaction Cues
----------------------------------*/
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
	border: 1px solid #cccccc;
	background: #ffffff url("../../images/jqueryui/blue/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-state-highlight a,
.ui-widget-content .ui-state-highlight a,
.ui-widget-header .ui-state-highlight a {
	color: #444444;
}
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-widget-header .ui-state-error {
	border: 1px solid #EA4F4F;
	background: #ffffff url("../../images/jqueryui/blue/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #222222;
}
.ui-state-error a,
.ui-widget-content .ui-state-error a,
.ui-widget-header .ui-state-error a {
	color: #222222;
}
.ui-state-error-text,
.ui-widget-content .ui-state-error-text,
.ui-widget-header .ui-state-error-text {
	color: #222222;
}
.ui-priority-primary,
.ui-widget-content .ui-priority-primary,
.ui-widget-header .ui-priority-primary {
	font-weight: bold;
}
.ui-priority-secondary,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
	opacity: .7;
	filter:Alpha(Opacity=70);
	font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
	opacity: .35;
	filter:Alpha(Opacity=35);
	background-image: none;
}
.ui-state-disabled .ui-icon {
	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
}

/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	width: 16px;
	height: 16px;
}
.ui-icon,
.ui-widget-content .ui-icon {
	background-image: url("../../images/jqueryui/blue/ui-icons_5e9cd5_256x240.png");
}
.ui-widget-header .ui-icon {
	background-image: url("../../images/jqueryui/blue/ui-icons_5e9cd5_256x240.png");
}
.ui-state-default .ui-icon {
	background-image: url("../../images/jqueryui/blue/ui-icons_666666_256x240.png");
}
.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon {
	background-image: url("../../images/jqueryui/blue/ui-icons_ffffff_256x240.png");
}
.ui-state-active .ui-icon {
	background-image: url("../../images/jqueryui/blue/ui-icons_454545_256x240.png");
}
.ui-state-highlight .ui-icon {
	background-image: url("../../images/jqueryui/blue/ui-icons_5e9cd5_256x240.png");
}
.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon {
	background-image: url("../../images/jqueryui/blue/ui-icons_EA4F4F_256x240.png");
}

/* positioning */
.ui-icon-blank { background-position: 16px 16px; }
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -97px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-on { background-position: -96px -144px; }
.ui-icon-radio-off { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }


/* Misc visuals
----------------------------------*/

/* Corner radius */
.ui-corner-all,
.ui-corner-top,
.ui-corner-left,
.ui-corner-tl {
	border-top-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-top,
.ui-corner-right,
.ui-corner-tr {
	border-top-right-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-left,
.ui-corner-bl {
	border-bottom-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-right,
.ui-corner-br {
	border-bottom-right-radius: 2px;
}

/* Overlays */
.ui-widget-overlay {
	background: #eeeeee url("../../images/jqueryui/blue/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
	opacity: .8;
	filter: Alpha(Opacity=80);
}
.ui-widget-shadow {
	margin: -4px 0 0 -4px;
	padding: 4px;
	background: #aaaaaa url("../../images/jqueryui/blue/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
	opacity: .6;
	filter: Alpha(Opacity=60);
	border-radius: 0px;
}
/*! jQuery UI - v1.10.3 - 2013-06-08
* http://jqueryui.com
* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%238aca1b&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%238aca1b&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%238aca1b&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%238aca1b&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%238aca1b&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23ccc&fcHighlight=%23444444&iconColorHighlight=%238aca1b&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */

/* Layout helpers
----------------------------------*/
.ui-helper-hidden {
	display: none;
}
.ui-helper-hidden-accessible {
	border: 0;
	clip: rect(0 0 0 0);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
}
.ui-helper-reset {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	line-height: 1.3;
	text-decoration: none;
	font-size: 100%;
	list-style: none;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
	content: "";
	display: table;
	border-collapse: collapse;
}
.ui-helper-clearfix:after {
	clear: both;
}
.ui-helper-clearfix {
	min-height: 0; /* support: IE7 */
}
.ui-helper-zfix {
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	position: absolute;
	opacity: 0;
	filter:Alpha(Opacity=0);
}

.ui-front {
	z-index: 100;
}


/* Interaction Cues
----------------------------------*/
.ui-state-disabled {
	cursor: default !important;
}


/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	display: block;
	text-indent: -99999px;
	overflow: hidden;
	background-repeat: no-repeat;
}


/* Misc visuals
----------------------------------*/

/* Overlays */
.ui-widget-overlay {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}
.ui-resizable {
	position: relative;
}
.ui-resizable-handle {
	position: absolute;
	font-size: 0.1px;
	display: block;
}
.ui-resizable-disabled .ui-resizable-handle,
.ui-resizable-autohide .ui-resizable-handle {
	display: none;
}
.ui-resizable-n {
	cursor: n-resize;
	height: 7px;
	width: 100%;
	top: -5px;
	left: 0;
}
.ui-resizable-s {
	cursor: s-resize;
	height: 7px;
	width: 100%;
	bottom: -5px;
	left: 0;
}
.ui-resizable-e {
	cursor: e-resize;
	width: 7px;
	right: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-w {
	cursor: w-resize;
	width: 7px;
	left: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-se {
	cursor: se-resize;
	width: 12px;
	height: 12px;
	right: 1px;
	bottom: 1px;
}
.ui-resizable-sw {
	cursor: sw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	bottom: -5px;
}
.ui-resizable-nw {
	cursor: nw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	top: -5px;
}
.ui-resizable-ne {
	cursor: ne-resize;
	width: 9px;
	height: 9px;
	right: -5px;
	top: -5px;
}
.ui-selectable-helper {
	position: absolute;
	z-index: 100;
	border: 1px dotted black;
}
.ui-accordion .ui-accordion-header {
	display: block;
	cursor: pointer;
	position: relative;
	margin-top: 2px;
	padding: .5em .5em .5em .7em;
	min-height: 0; /* support: IE7 */
}
.ui-accordion .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-noicons {
	padding-left: .7em;
}
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
	position: absolute;
	left: .5em;
	top: 50%;
	margin-top: -8px;
}
.ui-accordion .ui-accordion-content {
	padding: 1em 2.2em;
	border-top: 0;
	overflow: auto;
}
.ui-autocomplete {
	position: absolute;
	top: 0;
	left: 0;
	cursor: default;
}
.ui-button {
	display: inline-block;
	position: relative;
	padding: 0;
	line-height: normal;
	margin-right: .1em;
	cursor: pointer;
	vertical-align: middle;
	text-align: center;
	overflow: visible; /* removes extra width in IE */
}
.ui-button,
.ui-button:link,
.ui-button:visited,
.ui-button:hover,
.ui-button:active {
	text-decoration: none;
}
/* to make room for the icon, a width needs to be set here */
.ui-button-icon-only {
	width: 2.2em;
}
/* button elements seem to need a little more width */
button.ui-button-icon-only {
	width: 2.4em;
}
.ui-button-icons-only {
	width: 3.4em;
}
button.ui-button-icons-only {
	width: 3.7em;
}

/* button text element */
.ui-button .ui-button-text {
	display: block;
	line-height: normal;
}
.ui-button-text-only .ui-button-text {
	padding: .4em 1em;
}
.ui-button-icon-only .ui-button-text,
.ui-button-icons-only .ui-button-text {
	padding: .4em;
	text-indent: -9999999px;
}
.ui-button-text-icon-primary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 1em .4em 2.1em;
}
.ui-button-text-icon-secondary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 2.1em .4em 1em;
}
.ui-button-text-icons .ui-button-text {
	padding-left: 2.1em;
	padding-right: 2.1em;
}
/* no icon support for input elements, provide padding by default */
input.ui-button {
	padding: .4em 1em;
}

/* button icon element(s) */
.ui-button-icon-only .ui-icon,
.ui-button-text-icon-primary .ui-icon,
.ui-button-text-icon-secondary .ui-icon,
.ui-button-text-icons .ui-icon,
.ui-button-icons-only .ui-icon {
	position: absolute;
	top: 50%;
	margin-top: -8px;
}
.ui-button-icon-only .ui-icon {
	left: 50%;
	margin-left: -8px;
}
.ui-button-text-icon-primary .ui-button-icon-primary,
.ui-button-text-icons .ui-button-icon-primary,
.ui-button-icons-only .ui-button-icon-primary {
	left: .5em;
}
.ui-button-text-icon-secondary .ui-button-icon-secondary,
.ui-button-text-icons .ui-button-icon-secondary,
.ui-button-icons-only .ui-button-icon-secondary {
	right: .5em;
}

/* button sets */
.ui-buttonset {
	margin-right: 7px;
}
.ui-buttonset .ui-button {
	margin-left: 0;
	margin-right: -.3em;
}

/* workarounds */
/* reset extra padding in Firefox, see h5bp.com/l */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
	border: 0;
	padding: 0;
}
.ui-datepicker {
	width: 17em;
	padding: .2em .2em 0;
	display: none;
}
.ui-datepicker .ui-datepicker-header {
	position: relative;
	padding: .2em 0;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
	position: absolute;
	top: 2px;
	width: 1.8em;
	height: 1.8em;
}
.ui-datepicker .ui-datepicker-prev-hover,
.ui-datepicker .ui-datepicker-next-hover {
	top: 1px;
}
.ui-datepicker .ui-datepicker-prev {
	left: 2px;
}
.ui-datepicker .ui-datepicker-next {
	right: 2px;
}
.ui-datepicker .ui-datepicker-prev-hover {
	left: 1px;
}
.ui-datepicker .ui-datepicker-next-hover {
	right: 1px;
}
.ui-datepicker .ui-datepicker-prev span,
.ui-datepicker .ui-datepicker-next span {
	display: block;
	position: absolute;
	left: 50%;
	margin-left: -8px;
	top: 50%;
	margin-top: -8px;
}
.ui-datepicker .ui-datepicker-title {
	margin: 0 2.3em;
	line-height: 1.8em;
	text-align: center;
}
.ui-datepicker .ui-datepicker-title select {
	font-size: 1em;
	margin: 1px 0;
}
.ui-datepicker select.ui-datepicker-month-year {
	width: 100%;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
	width: 49%;
}
.ui-datepicker table {
	width: 100%;
	font-size: .9em;
	border-collapse: collapse;
	margin: 0 0 .4em;
}
.ui-datepicker th {
	padding: .7em .3em;
	text-align: center;
	font-weight: bold;
	border: 0;
}
.ui-datepicker td {
	border: 0;
	padding: 1px;
}
.ui-datepicker td span,
.ui-datepicker td a {
	display: block;
	padding: .2em;
	text-align: right;
	text-decoration: none;
}
.ui-datepicker .ui-datepicker-buttonpane {
	background-image: none;
	margin: .7em 0 0 0;
	padding: 0 .2em;
	border-left: 0;
	border-right: 0;
	border-bottom: 0;
}
.ui-datepicker .ui-datepicker-buttonpane button {
	float: right;
	margin: .5em .2em .4em;
	cursor: pointer;
	padding: .2em .6em .3em .6em;
	width: auto;
	overflow: visible;
}
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
	float: left;
}

/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi {
	width: auto;
}
.ui-datepicker-multi .ui-datepicker-group {
	float: left;
}
.ui-datepicker-multi .ui-datepicker-group table {
	width: 95%;
	margin: 0 auto .4em;
}
.ui-datepicker-multi-2 .ui-datepicker-group {
	width: 50%;
}
.ui-datepicker-multi-3 .ui-datepicker-group {
	width: 33.3%;
}
.ui-datepicker-multi-4 .ui-datepicker-group {
	width: 25%;
}
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
	border-left-width: 0;
}
.ui-datepicker-multi .ui-datepicker-buttonpane {
	clear: left;
}
.ui-datepicker-row-break {
	clear: both;
	width: 100%;
	font-size: 0;
}

/* RTL support */
.ui-datepicker-rtl {
	direction: rtl;
}
.ui-datepicker-rtl .ui-datepicker-prev {
	right: 2px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next {
	left: 2px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-prev:hover {
	right: 1px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next:hover {
	left: 1px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane {
	clear: right;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
	float: left;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
.ui-datepicker-rtl .ui-datepicker-group {
	float: right;
}
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
	border-right-width: 0;
	border-left-width: 1px;
}
.ui-dialog {
	position: absolute;
	top: 0;
	left: 0;
	padding: .2em;
	outline: 0;
}
.ui-dialog .ui-dialog-titlebar {
	padding: .4em 1em;
	position: relative;
}
.ui-dialog .ui-dialog-title {
	float: left;
	margin: .1em 0;
	white-space: nowrap;
	width: 90%;
	overflow: hidden;
	text-overflow: ellipsis;
}
.ui-dialog .ui-dialog-titlebar-close {
	position: absolute;
	right: .3em;
	top: 50%;
	width: 21px;
	margin: -10px 0 0 0;
	padding: 1px;
	height: 20px;
}
.ui-dialog .ui-dialog-content {
	position: relative;
	border: 0;
	padding: .5em 1em;
	background: none;
	overflow: auto;
}
.ui-dialog .ui-dialog-buttonpane {
	text-align: left;
	border-width: 1px 0 0 0;
	background-image: none;
	margin-top: .5em;
	padding: .3em 1em .5em .4em;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
	float: right;
}
.ui-dialog .ui-dialog-buttonpane button {
	margin: .5em .4em .5em 0;
	cursor: pointer;
}
.ui-dialog .ui-resizable-se {
	width: 12px;
	height: 12px;
	right: -5px;
	bottom: -5px;
	background-position: 16px 16px;
}
.ui-draggable .ui-dialog-titlebar {
	cursor: move;
}
.ui-menu {
	list-style: none;
	padding: 2px;
	margin: 0;
	display: block;
	outline: none;
}
.ui-menu .ui-menu {
	margin-top: -3px;
	position: absolute;
}
.ui-menu .ui-menu-item {
	margin: 0;
	padding: 0;
	width: 100%;
	/* support: IE10, see #8844 */
	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}
.ui-menu .ui-menu-divider {
	margin: 5px -2px 5px -2px;
	height: 0;
	font-size: 0;
	line-height: 0;
	border-width: 1px 0 0 0;
}
.ui-menu .ui-menu-item a {
	text-decoration: none;
	display: block;
	padding: 2px .4em;
	line-height: 1.5;
	min-height: 0; /* support: IE7 */
	font-weight: normal;
}
.ui-menu .ui-menu-item a.ui-state-focus,
.ui-menu .ui-menu-item a.ui-state-active {
	font-weight: normal;
	margin: -1px;
}

.ui-menu .ui-state-disabled {
	font-weight: normal;
	margin: .4em 0 .2em;
	line-height: 1.5;
}
.ui-menu .ui-state-disabled a {
	cursor: default;
}

/* icon support */
.ui-menu-icons {
	position: relative;
}
.ui-menu-icons .ui-menu-item a {
	position: relative;
	padding-left: 2em;
}

/* left-aligned */
.ui-menu .ui-icon {
	position: absolute;
	top: .2em;
	left: .2em;
}

/* right-aligned */
.ui-menu .ui-menu-icon {
	position: static;
	float: right;
}
.ui-progressbar {
	height: 2em;
	text-align: left;
	overflow: hidden;
}
.ui-progressbar .ui-progressbar-value {
	margin: -1px;
	height: 100%;
}
.ui-progressbar .ui-progressbar-overlay {
	background: url("../../images/jqueryui/green/animated-overlay.gif");
	height: 100%;
	filter: alpha(opacity=25);
	opacity: 0.25;
}
.ui-progressbar-indeterminate .ui-progressbar-value {
	background-image: none;
}
.ui-slider {
	position: relative;
	text-align: left;
}
.ui-slider .ui-slider-handle {
	position: absolute;
	z-index: 2;
	width: 1.2em;
	height: 1.2em;
	cursor: default;
}
.ui-slider .ui-slider-range {
	position: absolute;
	z-index: 1;
	font-size: .7em;
	display: block;
	border: 0;
	background-position: 0 0;
}

/* For IE8 - See #6727 */
.ui-slider.ui-state-disabled .ui-slider-handle,
.ui-slider.ui-state-disabled .ui-slider-range {
	filter: inherit;
}

.ui-slider-horizontal {
	height: .8em;
}
.ui-slider-horizontal .ui-slider-handle {
	top: -.3em;
	margin-left: -.6em;
}
.ui-slider-horizontal .ui-slider-range {
	top: 0;
	height: 100%;
}
.ui-slider-horizontal .ui-slider-range-min {
	left: 0;
}
.ui-slider-horizontal .ui-slider-range-max {
	right: 0;
}

.ui-slider-vertical {
	width: .8em;
	height: 100px;
}
.ui-slider-vertical .ui-slider-handle {
	left: -.3em;
	margin-left: 0;
	margin-bottom: -.6em;
}
.ui-slider-vertical .ui-slider-range {
	left: 0;
	width: 100%;
}
.ui-slider-vertical .ui-slider-range-min {
	bottom: 0;
}
.ui-slider-vertical .ui-slider-range-max {
	top: 0;
}
.ui-spinner {
	position: relative;
	display: inline-block;
	overflow: hidden;
	padding: 0;
	vertical-align: middle;
}
.ui-spinner-input {
	border: none;
	background: none;
	color: inherit;
	padding: 0;
	margin: .2em 0;
	vertical-align: middle;
	margin-left: .4em;
	margin-right: 22px;
}
.ui-spinner-button {
	width: 16px;
	height: 50%;
	font-size: .5em;
	padding: 0;
	margin: 0;
	text-align: center;
	position: absolute;
	cursor: default;
	display: block;
	overflow: hidden;
	right: 0;
}
/* more specificity required here to overide default borders */
.ui-spinner a.ui-spinner-button {
	border-top: none;
	border-bottom: none;
	border-right: none;
}
/* vertical centre icon */
.ui-spinner .ui-icon {
	position: absolute;
	margin-top: -8px;
	top: 50%;
	left: 0;
}
.ui-spinner-up {
	top: 0;
}
.ui-spinner-down {
	bottom: 0;
}

/* TR overrides */
.ui-spinner .ui-icon-triangle-1-s {
	/* need to fix icons sprite */
	background-position: -65px -16px;
}
.ui-tabs {
	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
	padding: .2em;
}
.ui-tabs .ui-tabs-nav {
	margin: 0;
	padding: .2em .2em 0;
}
.ui-tabs .ui-tabs-nav li {
	list-style: none;
	float: left;
	position: relative;
	top: 0;
	margin: 1px .2em 0 0;
	border-bottom-width: 0;
	padding: 0;
	white-space: nowrap;
}
.ui-tabs .ui-tabs-nav li a {
	float: left;
	padding: .5em 1em;
	text-decoration: none;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
	margin-bottom: -1px;
	padding-bottom: 1px;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
	cursor: text;
}
.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
	cursor: pointer;
}
.ui-tabs .ui-tabs-panel {
	display: block;
	border-width: 0;
	padding: 1em 1.4em;
	background: none;
}
.ui-tooltip {
	padding: 8px;
	position: absolute;
	z-index: 9999;
	max-width: 300px;
	-webkit-box-shadow: 0 0 5px #aaa;
	box-shadow: 0 0 5px #aaa;
}
body .ui-tooltip {
	border-width: 2px;
}

/* Component containers
----------------------------------*/
.ui-widget {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1.1em;
}
.ui-widget .ui-widget {
	font-size: 1em;
}
.ui-widget input,
.ui-widget select,
.ui-widget textarea,
.ui-widget button {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1em;
}
.ui-widget-content {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/green/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-widget-content a {
	color: #444444;
}
.ui-widget-header {
	border: 1px solid #dddddd;
	background: #dddddd url("../../images/jqueryui/green/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
	color: #444444;
	font-weight: bold;
}
.ui-widget-header a {
	color: #444444;
}

/* Interaction states
----------------------------------*/
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
	border: 1px solid #dddddd;
	background: #f6f6f6 url("../../images/jqueryui/green/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #444;
}
.ui-state-default a,
.ui-state-default a:link,
.ui-state-default a:visited {
	color: #444;
	text-decoration: none;
}
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus {
	border: 1px solid #8aca1b;
	background: #8aca1b url("../../images/jqueryui/green/ui-bg_highlight-soft_25_8aca1b_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #ffffff;
}
.ui-state-hover a,
.ui-state-hover a:hover,
.ui-state-hover a:link,
.ui-state-hover a:visited {
	color: #ffffff;
	text-decoration: none;
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/green/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #8aca1b;
}
.ui-state-active a,
.ui-state-active a:link,
.ui-state-active a:visited {
	color: #8aca1b;
	text-decoration: none;
}

/* Interaction Cues
----------------------------------*/
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
	border: 1px solid #ccc;
	background: #ffffff url("../../images/jqueryui/green/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-state-highlight a,
.ui-widget-content .ui-state-highlight a,
.ui-widget-header .ui-state-highlight a {
	color: #444444;
}
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-widget-header .ui-state-error {
	border: 1px solid #EA4F4F;
	background: #ffffff url("../../images/jqueryui/green/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #222222;
}
.ui-state-error a,
.ui-widget-content .ui-state-error a,
.ui-widget-header .ui-state-error a {
	color: #222222;
}
.ui-state-error-text,
.ui-widget-content .ui-state-error-text,
.ui-widget-header .ui-state-error-text {
	color: #222222;
}
.ui-priority-primary,
.ui-widget-content .ui-priority-primary,
.ui-widget-header .ui-priority-primary {
	font-weight: bold;
}
.ui-priority-secondary,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
	opacity: .7;
	filter:Alpha(Opacity=70);
	font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
	opacity: .35;
	filter:Alpha(Opacity=35);
	background-image: none;
}
.ui-state-disabled .ui-icon {
	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
}

/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	width: 16px;
	height: 16px;
}
.ui-icon,
.ui-widget-content .ui-icon {
	background-image: url("../../images/jqueryui/green/ui-icons_8aca1b_256x240.png");
}
.ui-widget-header .ui-icon {
	background-image: url("../../images/jqueryui/green/ui-icons_8aca1b_256x240.png");
}
.ui-state-default .ui-icon {
	background-image: url("../../images/jqueryui/green/ui-icons_666666_256x240.png");
}
.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon {
	background-image: url("../../images/jqueryui/green/ui-icons_ffffff_256x240.png");
}
.ui-state-active .ui-icon {
	background-image: url("../../images/jqueryui/green/ui-icons_454545_256x240.png");
}
.ui-state-highlight .ui-icon {
	background-image: url("../../images/jqueryui/green/ui-icons_8aca1b_256x240.png");
}
.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon {
	background-image: url("../../images/jqueryui/green/ui-icons_EA4F4F_256x240.png");
}

/* positioning */
.ui-icon-blank { background-position: 16px 16px; }
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -97px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-on { background-position: -96px -144px; }
.ui-icon-radio-off { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }


/* Misc visuals
----------------------------------*/

/* Corner radius */
.ui-corner-all,
.ui-corner-top,
.ui-corner-left,
.ui-corner-tl {
	border-top-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-top,
.ui-corner-right,
.ui-corner-tr {
	border-top-right-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-left,
.ui-corner-bl {
	border-bottom-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-right,
.ui-corner-br {
	border-bottom-right-radius: 2px;
}

/* Overlays */
.ui-widget-overlay {
	background: #eeeeee url("../../images/jqueryui/green/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
	opacity: .8;
	filter: Alpha(Opacity=80);
}
.ui-widget-shadow {
	margin: -4px 0 0 -4px;
	padding: 4px;
	background: #aaaaaa url("../../images/jqueryui/green/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
	opacity: .6;
	filter: Alpha(Opacity=60);
	border-radius: 0px;
}
/*! jQuery UI - v1.10.3 - 2013-06-08
* http://jqueryui.com
* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%23ffa600&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%23ffa600&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%23ffa600&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%23ffa600&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%23ffa600&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23ccc&fcHighlight=%23444444&iconColorHighlight=%23ffa600&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */

/* Layout helpers
----------------------------------*/
.ui-helper-hidden {
	display: none;
}
.ui-helper-hidden-accessible {
	border: 0;
	clip: rect(0 0 0 0);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
}
.ui-helper-reset {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	line-height: 1.3;
	text-decoration: none;
	font-size: 100%;
	list-style: none;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
	content: "";
	display: table;
	border-collapse: collapse;
}
.ui-helper-clearfix:after {
	clear: both;
}
.ui-helper-clearfix {
	min-height: 0; /* support: IE7 */
}
.ui-helper-zfix {
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	position: absolute;
	opacity: 0;
	filter:Alpha(Opacity=0);
}

.ui-front {
	z-index: 100;
}


/* Interaction Cues
----------------------------------*/
.ui-state-disabled {
	cursor: default !important;
}


/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	display: block;
	text-indent: -99999px;
	overflow: hidden;
	background-repeat: no-repeat;
}


/* Misc visuals
----------------------------------*/

/* Overlays */
.ui-widget-overlay {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}
.ui-resizable {
	position: relative;
}
.ui-resizable-handle {
	position: absolute;
	font-size: 0.1px;
	display: block;
}
.ui-resizable-disabled .ui-resizable-handle,
.ui-resizable-autohide .ui-resizable-handle {
	display: none;
}
.ui-resizable-n {
	cursor: n-resize;
	height: 7px;
	width: 100%;
	top: -5px;
	left: 0;
}
.ui-resizable-s {
	cursor: s-resize;
	height: 7px;
	width: 100%;
	bottom: -5px;
	left: 0;
}
.ui-resizable-e {
	cursor: e-resize;
	width: 7px;
	right: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-w {
	cursor: w-resize;
	width: 7px;
	left: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-se {
	cursor: se-resize;
	width: 12px;
	height: 12px;
	right: 1px;
	bottom: 1px;
}
.ui-resizable-sw {
	cursor: sw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	bottom: -5px;
}
.ui-resizable-nw {
	cursor: nw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	top: -5px;
}
.ui-resizable-ne {
	cursor: ne-resize;
	width: 9px;
	height: 9px;
	right: -5px;
	top: -5px;
}
.ui-selectable-helper {
	position: absolute;
	z-index: 100;
	border: 1px dotted black;
}
.ui-accordion .ui-accordion-header {
	display: block;
	cursor: pointer;
	position: relative;
	margin-top: 2px;
	padding: .5em .5em .5em .7em;
	min-height: 0; /* support: IE7 */
}
.ui-accordion .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-noicons {
	padding-left: .7em;
}
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
	position: absolute;
	left: .5em;
	top: 50%;
	margin-top: -8px;
}
.ui-accordion .ui-accordion-content {
	padding: 1em 2.2em;
	border-top: 0;
	overflow: auto;
}
.ui-autocomplete {
	position: absolute;
	top: 0;
	left: 0;
	cursor: default;
}
.ui-button {
	display: inline-block;
	position: relative;
	padding: 0;
	line-height: normal;
	margin-right: .1em;
	cursor: pointer;
	vertical-align: middle;
	text-align: center;
	overflow: visible; /* removes extra width in IE */
}
.ui-button,
.ui-button:link,
.ui-button:visited,
.ui-button:hover,
.ui-button:active {
	text-decoration: none;
}
/* to make room for the icon, a width needs to be set here */
.ui-button-icon-only {
	width: 2.2em;
}
/* button elements seem to need a little more width */
button.ui-button-icon-only {
	width: 2.4em;
}
.ui-button-icons-only {
	width: 3.4em;
}
button.ui-button-icons-only {
	width: 3.7em;
}

/* button text element */
.ui-button .ui-button-text {
	display: block;
	line-height: normal;
}
.ui-button-text-only .ui-button-text {
	padding: .4em 1em;
}
.ui-button-icon-only .ui-button-text,
.ui-button-icons-only .ui-button-text {
	padding: .4em;
	text-indent: -9999999px;
}
.ui-button-text-icon-primary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 1em .4em 2.1em;
}
.ui-button-text-icon-secondary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 2.1em .4em 1em;
}
.ui-button-text-icons .ui-button-text {
	padding-left: 2.1em;
	padding-right: 2.1em;
}
/* no icon support for input elements, provide padding by default */
input.ui-button {
	padding: .4em 1em;
}

/* button icon element(s) */
.ui-button-icon-only .ui-icon,
.ui-button-text-icon-primary .ui-icon,
.ui-button-text-icon-secondary .ui-icon,
.ui-button-text-icons .ui-icon,
.ui-button-icons-only .ui-icon {
	position: absolute;
	top: 50%;
	margin-top: -8px;
}
.ui-button-icon-only .ui-icon {
	left: 50%;
	margin-left: -8px;
}
.ui-button-text-icon-primary .ui-button-icon-primary,
.ui-button-text-icons .ui-button-icon-primary,
.ui-button-icons-only .ui-button-icon-primary {
	left: .5em;
}
.ui-button-text-icon-secondary .ui-button-icon-secondary,
.ui-button-text-icons .ui-button-icon-secondary,
.ui-button-icons-only .ui-button-icon-secondary {
	right: .5em;
}

/* button sets */
.ui-buttonset {
	margin-right: 7px;
}
.ui-buttonset .ui-button {
	margin-left: 0;
	margin-right: -.3em;
}

/* workarounds */
/* reset extra padding in Firefox, see h5bp.com/l */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
	border: 0;
	padding: 0;
}
.ui-datepicker {
	width: 17em;
	padding: .2em .2em 0;
	display: none;
}
.ui-datepicker .ui-datepicker-header {
	position: relative;
	padding: .2em 0;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
	position: absolute;
	top: 2px;
	width: 1.8em;
	height: 1.8em;
}
.ui-datepicker .ui-datepicker-prev-hover,
.ui-datepicker .ui-datepicker-next-hover {
	top: 1px;
}
.ui-datepicker .ui-datepicker-prev {
	left: 2px;
}
.ui-datepicker .ui-datepicker-next {
	right: 2px;
}
.ui-datepicker .ui-datepicker-prev-hover {
	left: 1px;
}
.ui-datepicker .ui-datepicker-next-hover {
	right: 1px;
}
.ui-datepicker .ui-datepicker-prev span,
.ui-datepicker .ui-datepicker-next span {
	display: block;
	position: absolute;
	left: 50%;
	margin-left: -8px;
	top: 50%;
	margin-top: -8px;
}
.ui-datepicker .ui-datepicker-title {
	margin: 0 2.3em;
	line-height: 1.8em;
	text-align: center;
}
.ui-datepicker .ui-datepicker-title select {
	font-size: 1em;
	margin: 1px 0;
}
.ui-datepicker select.ui-datepicker-month-year {
	width: 100%;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
	width: 49%;
}
.ui-datepicker table {
	width: 100%;
	font-size: .9em;
	border-collapse: collapse;
	margin: 0 0 .4em;
}
.ui-datepicker th {
	padding: .7em .3em;
	text-align: center;
	font-weight: bold;
	border: 0;
}
.ui-datepicker td {
	border: 0;
	padding: 1px;
}
.ui-datepicker td span,
.ui-datepicker td a {
	display: block;
	padding: .2em;
	text-align: right;
	text-decoration: none;
}
.ui-datepicker .ui-datepicker-buttonpane {
	background-image: none;
	margin: .7em 0 0 0;
	padding: 0 .2em;
	border-left: 0;
	border-right: 0;
	border-bottom: 0;
}
.ui-datepicker .ui-datepicker-buttonpane button {
	float: right;
	margin: .5em .2em .4em;
	cursor: pointer;
	padding: .2em .6em .3em .6em;
	width: auto;
	overflow: visible;
}
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
	float: left;
}

/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi {
	width: auto;
}
.ui-datepicker-multi .ui-datepicker-group {
	float: left;
}
.ui-datepicker-multi .ui-datepicker-group table {
	width: 95%;
	margin: 0 auto .4em;
}
.ui-datepicker-multi-2 .ui-datepicker-group {
	width: 50%;
}
.ui-datepicker-multi-3 .ui-datepicker-group {
	width: 33.3%;
}
.ui-datepicker-multi-4 .ui-datepicker-group {
	width: 25%;
}
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
	border-left-width: 0;
}
.ui-datepicker-multi .ui-datepicker-buttonpane {
	clear: left;
}
.ui-datepicker-row-break {
	clear: both;
	width: 100%;
	font-size: 0;
}

/* RTL support */
.ui-datepicker-rtl {
	direction: rtl;
}
.ui-datepicker-rtl .ui-datepicker-prev {
	right: 2px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next {
	left: 2px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-prev:hover {
	right: 1px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next:hover {
	left: 1px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane {
	clear: right;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
	float: left;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
.ui-datepicker-rtl .ui-datepicker-group {
	float: right;
}
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
	border-right-width: 0;
	border-left-width: 1px;
}
.ui-dialog {
	position: absolute;
	top: 0;
	left: 0;
	padding: .2em;
	outline: 0;
}
.ui-dialog .ui-dialog-titlebar {
	padding: .4em 1em;
	position: relative;
}
.ui-dialog .ui-dialog-title {
	float: left;
	margin: .1em 0;
	white-space: nowrap;
	width: 90%;
	overflow: hidden;
	text-overflow: ellipsis;
}
.ui-dialog .ui-dialog-titlebar-close {
	position: absolute;
	right: .3em;
	top: 50%;
	width: 21px;
	margin: -10px 0 0 0;
	padding: 1px;
	height: 20px;
}
.ui-dialog .ui-dialog-content {
	position: relative;
	border: 0;
	padding: .5em 1em;
	background: none;
	overflow: auto;
}
.ui-dialog .ui-dialog-buttonpane {
	text-align: left;
	border-width: 1px 0 0 0;
	background-image: none;
	margin-top: .5em;
	padding: .3em 1em .5em .4em;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
	float: right;
}
.ui-dialog .ui-dialog-buttonpane button {
	margin: .5em .4em .5em 0;
	cursor: pointer;
}
.ui-dialog .ui-resizable-se {
	width: 12px;
	height: 12px;
	right: -5px;
	bottom: -5px;
	background-position: 16px 16px;
}
.ui-draggable .ui-dialog-titlebar {
	cursor: move;
}
.ui-menu {
	list-style: none;
	padding: 2px;
	margin: 0;
	display: block;
	outline: none;
}
.ui-menu .ui-menu {
	margin-top: -3px;
	position: absolute;
}
.ui-menu .ui-menu-item {
	margin: 0;
	padding: 0;
	width: 100%;
	/* support: IE10, see #8844 */
	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}
.ui-menu .ui-menu-divider {
	margin: 5px -2px 5px -2px;
	height: 0;
	font-size: 0;
	line-height: 0;
	border-width: 1px 0 0 0;
}
.ui-menu .ui-menu-item a {
	text-decoration: none;
	display: block;
	padding: 2px .4em;
	line-height: 1.5;
	min-height: 0; /* support: IE7 */
	font-weight: normal;
}
.ui-menu .ui-menu-item a.ui-state-focus,
.ui-menu .ui-menu-item a.ui-state-active {
	font-weight: normal;
	margin: -1px;
}

.ui-menu .ui-state-disabled {
	font-weight: normal;
	margin: .4em 0 .2em;
	line-height: 1.5;
}
.ui-menu .ui-state-disabled a {
	cursor: default;
}

/* icon support */
.ui-menu-icons {
	position: relative;
}
.ui-menu-icons .ui-menu-item a {
	position: relative;
	padding-left: 2em;
}

/* left-aligned */
.ui-menu .ui-icon {
	position: absolute;
	top: .2em;
	left: .2em;
}

/* right-aligned */
.ui-menu .ui-menu-icon {
	position: static;
	float: right;
}
.ui-progressbar {
	height: 2em;
	text-align: left;
	overflow: hidden;
}
.ui-progressbar .ui-progressbar-value {
	margin: -1px;
	height: 100%;
}
.ui-progressbar .ui-progressbar-overlay {
	background: url("../../images/jqueryui/orange/animated-overlay.gif");
	height: 100%;
	filter: alpha(opacity=25);
	opacity: 0.25;
}
.ui-progressbar-indeterminate .ui-progressbar-value {
	background-image: none;
}
.ui-slider {
	position: relative;
	text-align: left;
}
.ui-slider .ui-slider-handle {
	position: absolute;
	z-index: 2;
	width: 1.2em;
	height: 1.2em;
	cursor: default;
}
.ui-slider .ui-slider-range {
	position: absolute;
	z-index: 1;
	font-size: .7em;
	display: block;
	border: 0;
	background-position: 0 0;
}

/* For IE8 - See #6727 */
.ui-slider.ui-state-disabled .ui-slider-handle,
.ui-slider.ui-state-disabled .ui-slider-range {
	filter: inherit;
}

.ui-slider-horizontal {
	height: .8em;
}
.ui-slider-horizontal .ui-slider-handle {
	top: -.3em;
	margin-left: -.6em;
}
.ui-slider-horizontal .ui-slider-range {
	top: 0;
	height: 100%;
}
.ui-slider-horizontal .ui-slider-range-min {
	left: 0;
}
.ui-slider-horizontal .ui-slider-range-max {
	right: 0;
}

.ui-slider-vertical {
	width: .8em;
	height: 100px;
}
.ui-slider-vertical .ui-slider-handle {
	left: -.3em;
	margin-left: 0;
	margin-bottom: -.6em;
}
.ui-slider-vertical .ui-slider-range {
	left: 0;
	width: 100%;
}
.ui-slider-vertical .ui-slider-range-min {
	bottom: 0;
}
.ui-slider-vertical .ui-slider-range-max {
	top: 0;
}
.ui-spinner {
	position: relative;
	display: inline-block;
	overflow: hidden;
	padding: 0;
	vertical-align: middle;
}
.ui-spinner-input {
	border: none;
	background: none;
	color: inherit;
	padding: 0;
	margin: .2em 0;
	vertical-align: middle;
	margin-left: .4em;
	margin-right: 22px;
}
.ui-spinner-button {
	width: 16px;
	height: 50%;
	font-size: .5em;
	padding: 0;
	margin: 0;
	text-align: center;
	position: absolute;
	cursor: default;
	display: block;
	overflow: hidden;
	right: 0;
}
/* more specificity required here to overide default borders */
.ui-spinner a.ui-spinner-button {
	border-top: none;
	border-bottom: none;
	border-right: none;
}
/* vertical centre icon */
.ui-spinner .ui-icon {
	position: absolute;
	margin-top: -8px;
	top: 50%;
	left: 0;
}
.ui-spinner-up {
	top: 0;
}
.ui-spinner-down {
	bottom: 0;
}

/* TR overrides */
.ui-spinner .ui-icon-triangle-1-s {
	/* need to fix icons sprite */
	background-position: -65px -16px;
}
.ui-tabs {
	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
	padding: .2em;
}
.ui-tabs .ui-tabs-nav {
	margin: 0;
	padding: .2em .2em 0;
}
.ui-tabs .ui-tabs-nav li {
	list-style: none;
	float: left;
	position: relative;
	top: 0;
	margin: 1px .2em 0 0;
	border-bottom-width: 0;
	padding: 0;
	white-space: nowrap;
}
.ui-tabs .ui-tabs-nav li a {
	float: left;
	padding: .5em 1em;
	text-decoration: none;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
	margin-bottom: -1px;
	padding-bottom: 1px;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
	cursor: text;
}
.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
	cursor: pointer;
}
.ui-tabs .ui-tabs-panel {
	display: block;
	border-width: 0;
	padding: 1em 1.4em;
	background: none;
}
.ui-tooltip {
	padding: 8px;
	position: absolute;
	z-index: 9999;
	max-width: 300px;
	-webkit-box-shadow: 0 0 5px #aaa;
	box-shadow: 0 0 5px #aaa;
}
body .ui-tooltip {
	border-width: 2px;
}

/* Component containers
----------------------------------*/
.ui-widget {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1.1em;
}
.ui-widget .ui-widget {
	font-size: 1em;
}
.ui-widget input,
.ui-widget select,
.ui-widget textarea,
.ui-widget button {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1em;
}
.ui-widget-content {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/orange/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-widget-content a {
	color: #444444;
}
.ui-widget-header {
	border: 1px solid #dddddd;
	background: #dddddd url("../../images/jqueryui/orange/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
	color: #444444;
	font-weight: bold;
}
.ui-widget-header a {
	color: #444444;
}

/* Interaction states
----------------------------------*/
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
	border: 1px solid #dddddd;
	background: #f6f6f6 url("../../images/jqueryui/orange/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #444;
}
.ui-state-default a,
.ui-state-default a:link,
.ui-state-default a:visited {
	color: #444;
	text-decoration: none;
}
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus {
	border: 1px solid #ffa600;
	background: #ffa600 url("../../images/jqueryui/orange/ui-bg_highlight-soft_25_ffa600_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #ffffff;
}
.ui-state-hover a,
.ui-state-hover a:hover,
.ui-state-hover a:link,
.ui-state-hover a:visited {
	color: #ffffff;
	text-decoration: none;
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/orange/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #ffa600;
}
.ui-state-active a,
.ui-state-active a:link,
.ui-state-active a:visited {
	color: #ffa600;
	text-decoration: none;
}

/* Interaction Cues
----------------------------------*/
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
	border: 1px solid #ccc;
	background: #ffffff url("../../images/jqueryui/orange/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-state-highlight a,
.ui-widget-content .ui-state-highlight a,
.ui-widget-header .ui-state-highlight a {
	color: #444444;
}
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-widget-header .ui-state-error {
	border: 1px solid #EA4F4F;
	background: #ffffff url("../../images/jqueryui/orange/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #222222;
}
.ui-state-error a,
.ui-widget-content .ui-state-error a,
.ui-widget-header .ui-state-error a {
	color: #222222;
}
.ui-state-error-text,
.ui-widget-content .ui-state-error-text,
.ui-widget-header .ui-state-error-text {
	color: #222222;
}
.ui-priority-primary,
.ui-widget-content .ui-priority-primary,
.ui-widget-header .ui-priority-primary {
	font-weight: bold;
}
.ui-priority-secondary,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
	opacity: .7;
	filter:Alpha(Opacity=70);
	font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
	opacity: .35;
	filter:Alpha(Opacity=35);
	background-image: none;
}
.ui-state-disabled .ui-icon {
	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
}

/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	width: 16px;
	height: 16px;
}
.ui-icon,
.ui-widget-content .ui-icon {
	background-image: url("../../images/jqueryui/orange/ui-icons_ffa600_256x240.png");
}
.ui-widget-header .ui-icon {
	background-image: url("../../images/jqueryui/orange/ui-icons_ffa600_256x240.png");
}
.ui-state-default .ui-icon {
	background-image: url("../../images/jqueryui/orange/ui-icons_666666_256x240.png");
}
.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon {
	background-image: url("../../images/jqueryui/orange/ui-icons_ffffff_256x240.png");
}
.ui-state-active .ui-icon {
	background-image: url("../../images/jqueryui/orange/ui-icons_454545_256x240.png");
}
.ui-state-highlight .ui-icon {
	background-image: url("../../images/jqueryui/orange/ui-icons_ffa600_256x240.png");
}
.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon {
	background-image: url("../../images/jqueryui/orange/ui-icons_EA4F4F_256x240.png");
}

/* positioning */
.ui-icon-blank { background-position: 16px 16px; }
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -97px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-on { background-position: -96px -144px; }
.ui-icon-radio-off { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }


/* Misc visuals
----------------------------------*/

/* Corner radius */
.ui-corner-all,
.ui-corner-top,
.ui-corner-left,
.ui-corner-tl {
	border-top-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-top,
.ui-corner-right,
.ui-corner-tr {
	border-top-right-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-left,
.ui-corner-bl {
	border-bottom-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-right,
.ui-corner-br {
	border-bottom-right-radius: 2px;
}

/* Overlays */
.ui-widget-overlay {
	background: #eeeeee url("../../images/jqueryui/orange/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
	opacity: .8;
	filter: Alpha(Opacity=80);
}
.ui-widget-shadow {
	margin: -4px 0 0 -4px;
	padding: 4px;
	background: #aaaaaa url("../../images/jqueryui/orange/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
	opacity: .6;
	filter: Alpha(Opacity=60);
	border-radius: 0px;
}
/*! jQuery UI - v1.10.3 - 2013-06-08
* http://jqueryui.com
* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%23b15cd5&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%23b15cd5&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%23b15cd5&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%23b15cd5&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%23b15cd5&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23ccc&fcHighlight=%23444444&iconColorHighlight=%23b15cd5&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */

/* Layout helpers
----------------------------------*/
.ui-helper-hidden {
	display: none;
}
.ui-helper-hidden-accessible {
	border: 0;
	clip: rect(0 0 0 0);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
}
.ui-helper-reset {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	line-height: 1.3;
	text-decoration: none;
	font-size: 100%;
	list-style: none;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
	content: "";
	display: table;
	border-collapse: collapse;
}
.ui-helper-clearfix:after {
	clear: both;
}
.ui-helper-clearfix {
	min-height: 0; /* support: IE7 */
}
.ui-helper-zfix {
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	position: absolute;
	opacity: 0;
	filter:Alpha(Opacity=0);
}

.ui-front {
	z-index: 100;
}


/* Interaction Cues
----------------------------------*/
.ui-state-disabled {
	cursor: default !important;
}


/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	display: block;
	text-indent: -99999px;
	overflow: hidden;
	background-repeat: no-repeat;
}


/* Misc visuals
----------------------------------*/

/* Overlays */
.ui-widget-overlay {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}
.ui-resizable {
	position: relative;
}
.ui-resizable-handle {
	position: absolute;
	font-size: 0.1px;
	display: block;
}
.ui-resizable-disabled .ui-resizable-handle,
.ui-resizable-autohide .ui-resizable-handle {
	display: none;
}
.ui-resizable-n {
	cursor: n-resize;
	height: 7px;
	width: 100%;
	top: -5px;
	left: 0;
}
.ui-resizable-s {
	cursor: s-resize;
	height: 7px;
	width: 100%;
	bottom: -5px;
	left: 0;
}
.ui-resizable-e {
	cursor: e-resize;
	width: 7px;
	right: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-w {
	cursor: w-resize;
	width: 7px;
	left: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-se {
	cursor: se-resize;
	width: 12px;
	height: 12px;
	right: 1px;
	bottom: 1px;
}
.ui-resizable-sw {
	cursor: sw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	bottom: -5px;
}
.ui-resizable-nw {
	cursor: nw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	top: -5px;
}
.ui-resizable-ne {
	cursor: ne-resize;
	width: 9px;
	height: 9px;
	right: -5px;
	top: -5px;
}
.ui-selectable-helper {
	position: absolute;
	z-index: 100;
	border: 1px dotted black;
}
.ui-accordion .ui-accordion-header {
	display: block;
	cursor: pointer;
	position: relative;
	margin-top: 2px;
	padding: .5em .5em .5em .7em;
	min-height: 0; /* support: IE7 */
}
.ui-accordion .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-noicons {
	padding-left: .7em;
}
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
	position: absolute;
	left: .5em;
	top: 50%;
	margin-top: -8px;
}
.ui-accordion .ui-accordion-content {
	padding: 1em 2.2em;
	border-top: 0;
	overflow: auto;
}
.ui-autocomplete {
	position: absolute;
	top: 0;
	left: 0;
	cursor: default;
}
.ui-button {
	display: inline-block;
	position: relative;
	padding: 0;
	line-height: normal;
	margin-right: .1em;
	cursor: pointer;
	vertical-align: middle;
	text-align: center;
	overflow: visible; /* removes extra width in IE */
}
.ui-button,
.ui-button:link,
.ui-button:visited,
.ui-button:hover,
.ui-button:active {
	text-decoration: none;
}
/* to make room for the icon, a width needs to be set here */
.ui-button-icon-only {
	width: 2.2em;
}
/* button elements seem to need a little more width */
button.ui-button-icon-only {
	width: 2.4em;
}
.ui-button-icons-only {
	width: 3.4em;
}
button.ui-button-icons-only {
	width: 3.7em;
}

/* button text element */
.ui-button .ui-button-text {
	display: block;
	line-height: normal;
}
.ui-button-text-only .ui-button-text {
	padding: .4em 1em;
}
.ui-button-icon-only .ui-button-text,
.ui-button-icons-only .ui-button-text {
	padding: .4em;
	text-indent: -9999999px;
}
.ui-button-text-icon-primary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 1em .4em 2.1em;
}
.ui-button-text-icon-secondary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 2.1em .4em 1em;
}
.ui-button-text-icons .ui-button-text {
	padding-left: 2.1em;
	padding-right: 2.1em;
}
/* no icon support for input elements, provide padding by default */
input.ui-button {
	padding: .4em 1em;
}

/* button icon element(s) */
.ui-button-icon-only .ui-icon,
.ui-button-text-icon-primary .ui-icon,
.ui-button-text-icon-secondary .ui-icon,
.ui-button-text-icons .ui-icon,
.ui-button-icons-only .ui-icon {
	position: absolute;
	top: 50%;
	margin-top: -8px;
}
.ui-button-icon-only .ui-icon {
	left: 50%;
	margin-left: -8px;
}
.ui-button-text-icon-primary .ui-button-icon-primary,
.ui-button-text-icons .ui-button-icon-primary,
.ui-button-icons-only .ui-button-icon-primary {
	left: .5em;
}
.ui-button-text-icon-secondary .ui-button-icon-secondary,
.ui-button-text-icons .ui-button-icon-secondary,
.ui-button-icons-only .ui-button-icon-secondary {
	right: .5em;
}

/* button sets */
.ui-buttonset {
	margin-right: 7px;
}
.ui-buttonset .ui-button {
	margin-left: 0;
	margin-right: -.3em;
}

/* workarounds */
/* reset extra padding in Firefox, see h5bp.com/l */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
	border: 0;
	padding: 0;
}
.ui-datepicker {
	width: 17em;
	padding: .2em .2em 0;
	display: none;
}
.ui-datepicker .ui-datepicker-header {
	position: relative;
	padding: .2em 0;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
	position: absolute;
	top: 2px;
	width: 1.8em;
	height: 1.8em;
}
.ui-datepicker .ui-datepicker-prev-hover,
.ui-datepicker .ui-datepicker-next-hover {
	top: 1px;
}
.ui-datepicker .ui-datepicker-prev {
	left: 2px;
}
.ui-datepicker .ui-datepicker-next {
	right: 2px;
}
.ui-datepicker .ui-datepicker-prev-hover {
	left: 1px;
}
.ui-datepicker .ui-datepicker-next-hover {
	right: 1px;
}
.ui-datepicker .ui-datepicker-prev span,
.ui-datepicker .ui-datepicker-next span {
	display: block;
	position: absolute;
	left: 50%;
	margin-left: -8px;
	top: 50%;
	margin-top: -8px;
}
.ui-datepicker .ui-datepicker-title {
	margin: 0 2.3em;
	line-height: 1.8em;
	text-align: center;
}
.ui-datepicker .ui-datepicker-title select {
	font-size: 1em;
	margin: 1px 0;
}
.ui-datepicker select.ui-datepicker-month-year {
	width: 100%;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
	width: 49%;
}
.ui-datepicker table {
	width: 100%;
	font-size: .9em;
	border-collapse: collapse;
	margin: 0 0 .4em;
}
.ui-datepicker th {
	padding: .7em .3em;
	text-align: center;
	font-weight: bold;
	border: 0;
}
.ui-datepicker td {
	border: 0;
	padding: 1px;
}
.ui-datepicker td span,
.ui-datepicker td a {
	display: block;
	padding: .2em;
	text-align: right;
	text-decoration: none;
}
.ui-datepicker .ui-datepicker-buttonpane {
	background-image: none;
	margin: .7em 0 0 0;
	padding: 0 .2em;
	border-left: 0;
	border-right: 0;
	border-bottom: 0;
}
.ui-datepicker .ui-datepicker-buttonpane button {
	float: right;
	margin: .5em .2em .4em;
	cursor: pointer;
	padding: .2em .6em .3em .6em;
	width: auto;
	overflow: visible;
}
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
	float: left;
}

/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi {
	width: auto;
}
.ui-datepicker-multi .ui-datepicker-group {
	float: left;
}
.ui-datepicker-multi .ui-datepicker-group table {
	width: 95%;
	margin: 0 auto .4em;
}
.ui-datepicker-multi-2 .ui-datepicker-group {
	width: 50%;
}
.ui-datepicker-multi-3 .ui-datepicker-group {
	width: 33.3%;
}
.ui-datepicker-multi-4 .ui-datepicker-group {
	width: 25%;
}
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
	border-left-width: 0;
}
.ui-datepicker-multi .ui-datepicker-buttonpane {
	clear: left;
}
.ui-datepicker-row-break {
	clear: both;
	width: 100%;
	font-size: 0;
}

/* RTL support */
.ui-datepicker-rtl {
	direction: rtl;
}
.ui-datepicker-rtl .ui-datepicker-prev {
	right: 2px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next {
	left: 2px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-prev:hover {
	right: 1px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next:hover {
	left: 1px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane {
	clear: right;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
	float: left;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
.ui-datepicker-rtl .ui-datepicker-group {
	float: right;
}
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
	border-right-width: 0;
	border-left-width: 1px;
}
.ui-dialog {
	position: absolute;
	top: 0;
	left: 0;
	padding: .2em;
	outline: 0;
}
.ui-dialog .ui-dialog-titlebar {
	padding: .4em 1em;
	position: relative;
}
.ui-dialog .ui-dialog-title {
	float: left;
	margin: .1em 0;
	white-space: nowrap;
	width: 90%;
	overflow: hidden;
	text-overflow: ellipsis;
}
.ui-dialog .ui-dialog-titlebar-close {
	position: absolute;
	right: .3em;
	top: 50%;
	width: 21px;
	margin: -10px 0 0 0;
	padding: 1px;
	height: 20px;
}
.ui-dialog .ui-dialog-content {
	position: relative;
	border: 0;
	padding: .5em 1em;
	background: none;
	overflow: auto;
}
.ui-dialog .ui-dialog-buttonpane {
	text-align: left;
	border-width: 1px 0 0 0;
	background-image: none;
	margin-top: .5em;
	padding: .3em 1em .5em .4em;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
	float: right;
}
.ui-dialog .ui-dialog-buttonpane button {
	margin: .5em .4em .5em 0;
	cursor: pointer;
}
.ui-dialog .ui-resizable-se {
	width: 12px;
	height: 12px;
	right: -5px;
	bottom: -5px;
	background-position: 16px 16px;
}
.ui-draggable .ui-dialog-titlebar {
	cursor: move;
}
.ui-menu {
	list-style: none;
	padding: 2px;
	margin: 0;
	display: block;
	outline: none;
}
.ui-menu .ui-menu {
	margin-top: -3px;
	position: absolute;
}
.ui-menu .ui-menu-item {
	margin: 0;
	padding: 0;
	width: 100%;
	/* support: IE10, see #8844 */
	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}
.ui-menu .ui-menu-divider {
	margin: 5px -2px 5px -2px;
	height: 0;
	font-size: 0;
	line-height: 0;
	border-width: 1px 0 0 0;
}
.ui-menu .ui-menu-item a {
	text-decoration: none;
	display: block;
	padding: 2px .4em;
	line-height: 1.5;
	min-height: 0; /* support: IE7 */
	font-weight: normal;
}
.ui-menu .ui-menu-item a.ui-state-focus,
.ui-menu .ui-menu-item a.ui-state-active {
	font-weight: normal;
	margin: -1px;
}

.ui-menu .ui-state-disabled {
	font-weight: normal;
	margin: .4em 0 .2em;
	line-height: 1.5;
}
.ui-menu .ui-state-disabled a {
	cursor: default;
}

/* icon support */
.ui-menu-icons {
	position: relative;
}
.ui-menu-icons .ui-menu-item a {
	position: relative;
	padding-left: 2em;
}

/* left-aligned */
.ui-menu .ui-icon {
	position: absolute;
	top: .2em;
	left: .2em;
}

/* right-aligned */
.ui-menu .ui-menu-icon {
	position: static;
	float: right;
}
.ui-progressbar {
	height: 2em;
	text-align: left;
	overflow: hidden;
}
.ui-progressbar .ui-progressbar-value {
	margin: -1px;
	height: 100%;
}
.ui-progressbar .ui-progressbar-overlay {
	background: url("../../images/jqueryui/purple/animated-overlay.gif");
	height: 100%;
	filter: alpha(opacity=25);
	opacity: 0.25;
}
.ui-progressbar-indeterminate .ui-progressbar-value {
	background-image: none;
}
.ui-slider {
	position: relative;
	text-align: left;
}
.ui-slider .ui-slider-handle {
	position: absolute;
	z-index: 2;
	width: 1.2em;
	height: 1.2em;
	cursor: default;
}
.ui-slider .ui-slider-range {
	position: absolute;
	z-index: 1;
	font-size: .7em;
	display: block;
	border: 0;
	background-position: 0 0;
}

/* For IE8 - See #6727 */
.ui-slider.ui-state-disabled .ui-slider-handle,
.ui-slider.ui-state-disabled .ui-slider-range {
	filter: inherit;
}

.ui-slider-horizontal {
	height: .8em;
}
.ui-slider-horizontal .ui-slider-handle {
	top: -.3em;
	margin-left: -.6em;
}
.ui-slider-horizontal .ui-slider-range {
	top: 0;
	height: 100%;
}
.ui-slider-horizontal .ui-slider-range-min {
	left: 0;
}
.ui-slider-horizontal .ui-slider-range-max {
	right: 0;
}

.ui-slider-vertical {
	width: .8em;
	height: 100px;
}
.ui-slider-vertical .ui-slider-handle {
	left: -.3em;
	margin-left: 0;
	margin-bottom: -.6em;
}
.ui-slider-vertical .ui-slider-range {
	left: 0;
	width: 100%;
}
.ui-slider-vertical .ui-slider-range-min {
	bottom: 0;
}
.ui-slider-vertical .ui-slider-range-max {
	top: 0;
}
.ui-spinner {
	position: relative;
	display: inline-block;
	overflow: hidden;
	padding: 0;
	vertical-align: middle;
}
.ui-spinner-input {
	border: none;
	background: none;
	color: inherit;
	padding: 0;
	margin: .2em 0;
	vertical-align: middle;
	margin-left: .4em;
	margin-right: 22px;
}
.ui-spinner-button {
	width: 16px;
	height: 50%;
	font-size: .5em;
	padding: 0;
	margin: 0;
	text-align: center;
	position: absolute;
	cursor: default;
	display: block;
	overflow: hidden;
	right: 0;
}
/* more specificity required here to overide default borders */
.ui-spinner a.ui-spinner-button {
	border-top: none;
	border-bottom: none;
	border-right: none;
}
/* vertical centre icon */
.ui-spinner .ui-icon {
	position: absolute;
	margin-top: -8px;
	top: 50%;
	left: 0;
}
.ui-spinner-up {
	top: 0;
}
.ui-spinner-down {
	bottom: 0;
}

/* TR overrides */
.ui-spinner .ui-icon-triangle-1-s {
	/* need to fix icons sprite */
	background-position: -65px -16px;
}
.ui-tabs {
	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
	padding: .2em;
}
.ui-tabs .ui-tabs-nav {
	margin: 0;
	padding: .2em .2em 0;
}
.ui-tabs .ui-tabs-nav li {
	list-style: none;
	float: left;
	position: relative;
	top: 0;
	margin: 1px .2em 0 0;
	border-bottom-width: 0;
	padding: 0;
	white-space: nowrap;
}
.ui-tabs .ui-tabs-nav li a {
	float: left;
	padding: .5em 1em;
	text-decoration: none;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
	margin-bottom: -1px;
	padding-bottom: 1px;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
	cursor: text;
}
.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
	cursor: pointer;
}
.ui-tabs .ui-tabs-panel {
	display: block;
	border-width: 0;
	padding: 1em 1.4em;
	background: none;
}
.ui-tooltip {
	padding: 8px;
	position: absolute;
	z-index: 9999;
	max-width: 300px;
	-webkit-box-shadow: 0 0 5px #aaa;
	box-shadow: 0 0 5px #aaa;
}
body .ui-tooltip {
	border-width: 2px;
}

/* Component containers
----------------------------------*/
.ui-widget {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1.1em;
}
.ui-widget .ui-widget {
	font-size: 1em;
}
.ui-widget input,
.ui-widget select,
.ui-widget textarea,
.ui-widget button {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1em;
}
.ui-widget-content {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/purple/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-widget-content a {
	color: #444444;
}
.ui-widget-header {
	border: 1px solid #dddddd;
	background: #dddddd url("../../images/jqueryui/purple/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
	color: #444444;
	font-weight: bold;
}
.ui-widget-header a {
	color: #444444;
}

/* Interaction states
----------------------------------*/
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
	border: 1px solid #dddddd;
	background: #f6f6f6 url("../../images/jqueryui/purple/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #444;
}
.ui-state-default a,
.ui-state-default a:link,
.ui-state-default a:visited {
	color: #444;
	text-decoration: none;
}
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus {
	border: 1px solid #b15cd5;
	background: #b15cd5 url("../../images/jqueryui/purple/ui-bg_highlight-soft_25_b15cd5_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #ffffff;
}
.ui-state-hover a,
.ui-state-hover a:hover,
.ui-state-hover a:link,
.ui-state-hover a:visited {
	color: #ffffff;
	text-decoration: none;
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/purple/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #b15cd5;
}
.ui-state-active a,
.ui-state-active a:link,
.ui-state-active a:visited {
	color: #b15cd5;
	text-decoration: none;
}

/* Interaction Cues
----------------------------------*/
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
	border: 1px solid #ccc;
	background: #ffffff url("../../images/jqueryui/purple/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-state-highlight a,
.ui-widget-content .ui-state-highlight a,
.ui-widget-header .ui-state-highlight a {
	color: #444444;
}
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-widget-header .ui-state-error {
	border: 1px solid #EA4F4F;
	background: #ffffff url("../../images/jqueryui/purple/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #222222;
}
.ui-state-error a,
.ui-widget-content .ui-state-error a,
.ui-widget-header .ui-state-error a {
	color: #222222;
}
.ui-state-error-text,
.ui-widget-content .ui-state-error-text,
.ui-widget-header .ui-state-error-text {
	color: #222222;
}
.ui-priority-primary,
.ui-widget-content .ui-priority-primary,
.ui-widget-header .ui-priority-primary {
	font-weight: bold;
}
.ui-priority-secondary,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
	opacity: .7;
	filter:Alpha(Opacity=70);
	font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
	opacity: .35;
	filter:Alpha(Opacity=35);
	background-image: none;
}
.ui-state-disabled .ui-icon {
	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
}

/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	width: 16px;
	height: 16px;
}
.ui-icon,
.ui-widget-content .ui-icon {
	background-image: url("../../images/jqueryui/purple/ui-icons_b15cd5_256x240.png");
}
.ui-widget-header .ui-icon {
	background-image: url("../../images/jqueryui/purple/ui-icons_b15cd5_256x240.png");
}
.ui-state-default .ui-icon {
	background-image: url("../../images/jqueryui/purple/ui-icons_666666_256x240.png");
}
.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon {
	background-image: url("../../images/jqueryui/purple/ui-icons_ffffff_256x240.png");
}
.ui-state-active .ui-icon {
	background-image: url("../../images/jqueryui/purple/ui-icons_454545_256x240.png");
}
.ui-state-highlight .ui-icon {
	background-image: url("../../images/jqueryui/purple/ui-icons_b15cd5_256x240.png");
}
.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon {
	background-image: url("../../images/jqueryui/purple/ui-icons_EA4F4F_256x240.png");
}

/* positioning */
.ui-icon-blank { background-position: 16px 16px; }
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -97px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-on { background-position: -96px -144px; }
.ui-icon-radio-off { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }


/* Misc visuals
----------------------------------*/

/* Corner radius */
.ui-corner-all,
.ui-corner-top,
.ui-corner-left,
.ui-corner-tl {
	border-top-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-top,
.ui-corner-right,
.ui-corner-tr {
	border-top-right-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-left,
.ui-corner-bl {
	border-bottom-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-right,
.ui-corner-br {
	border-bottom-right-radius: 2px;
}

/* Overlays */
.ui-widget-overlay {
	background: #eeeeee url("../../images/jqueryui/purple/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
	opacity: .8;
	filter: Alpha(Opacity=80);
}
.ui-widget-shadow {
	margin: -4px 0 0 -4px;
	padding: 4px;
	background: #aaaaaa url("../../images/jqueryui/purple/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
	opacity: .6;
	filter: Alpha(Opacity=60);
	border-radius: 0px;
}
/*! jQuery UI - v1.10.3 - 2013-06-08
* http://jqueryui.com
* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=%23dddddd&bgTextureHeader=highlight_soft&bgImgOpacityHeader=50&borderColorHeader=%23dddddd&fcHeader=%23444444&iconColorHeader=%23EA4F4F&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23dddddd&fcContent=%23444444&iconColorContent=%23EA4F4F&bgColorDefault=%23f6f6f6&bgTextureDefault=highlight_soft&bgImgOpacityDefault=100&borderColorDefault=%23dddddd&fcDefault=%23444&iconColorDefault=%23666666&bgColorHover=%23EA4F4F&bgTextureHover=highlight_soft&bgImgOpacityHover=25&borderColorHover=%23EA4F4F&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23dddddd&fcActive=%23EA4F4F&iconColorActive=%23454545&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23cccccc&fcHighlight=%23444444&iconColorHighlight=%23EA4F4F&bgColorError=%23ffffff&bgTextureError=flat&bgImgOpacityError=55&borderColorError=%23EA4F4F&fcError=%23222222&iconColorError=%23EA4F4F&bgColorOverlay=%23eeeeee&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0px
* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */

/* Layout helpers
----------------------------------*/
.ui-helper-hidden {
	display: none;
}
.ui-helper-hidden-accessible {
	border: 0;
	clip: rect(0 0 0 0);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
}
.ui-helper-reset {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	line-height: 1.3;
	text-decoration: none;
	font-size: 100%;
	list-style: none;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
	content: "";
	display: table;
	border-collapse: collapse;
}
.ui-helper-clearfix:after {
	clear: both;
}
.ui-helper-clearfix {
	min-height: 0; /* support: IE7 */
}
.ui-helper-zfix {
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	position: absolute;
	opacity: 0;
	filter:Alpha(Opacity=0);
}

.ui-front {
	z-index: 100;
}


/* Interaction Cues
----------------------------------*/
.ui-state-disabled {
	cursor: default !important;
}


/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	display: block;
	text-indent: -99999px;
	overflow: hidden;
	background-repeat: no-repeat;
}


/* Misc visuals
----------------------------------*/

/* Overlays */
.ui-widget-overlay {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}
.ui-resizable {
	position: relative;
}
.ui-resizable-handle {
	position: absolute;
	font-size: 0.1px;
	display: block;
}
.ui-resizable-disabled .ui-resizable-handle,
.ui-resizable-autohide .ui-resizable-handle {
	display: none;
}
.ui-resizable-n {
	cursor: n-resize;
	height: 7px;
	width: 100%;
	top: -5px;
	left: 0;
}
.ui-resizable-s {
	cursor: s-resize;
	height: 7px;
	width: 100%;
	bottom: -5px;
	left: 0;
}
.ui-resizable-e {
	cursor: e-resize;
	width: 7px;
	right: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-w {
	cursor: w-resize;
	width: 7px;
	left: -5px;
	top: 0;
	height: 100%;
}
.ui-resizable-se {
	cursor: se-resize;
	width: 12px;
	height: 12px;
	right: 1px;
	bottom: 1px;
}
.ui-resizable-sw {
	cursor: sw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	bottom: -5px;
}
.ui-resizable-nw {
	cursor: nw-resize;
	width: 9px;
	height: 9px;
	left: -5px;
	top: -5px;
}
.ui-resizable-ne {
	cursor: ne-resize;
	width: 9px;
	height: 9px;
	right: -5px;
	top: -5px;
}
.ui-selectable-helper {
	position: absolute;
	z-index: 100;
	border: 1px dotted black;
}
.ui-accordion .ui-accordion-header {
	display: block;
	cursor: pointer;
	position: relative;
	margin-top: 2px;
	padding: .5em .5em .5em .7em;
	min-height: 0; /* support: IE7 */
}
.ui-accordion .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-noicons {
	padding-left: .7em;
}
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
	padding-left: 2.2em;
}
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
	position: absolute;
	left: .5em;
	top: 50%;
	margin-top: -8px;
}
.ui-accordion .ui-accordion-content {
	padding: 1em 2.2em;
	border-top: 0;
	overflow: auto;
}
.ui-autocomplete {
	position: absolute;
	top: 0;
	left: 0;
	cursor: default;
}
.ui-button {
	display: inline-block;
	position: relative;
	padding: 0;
	line-height: normal;
	margin-right: .1em;
	cursor: pointer;
	vertical-align: middle;
	text-align: center;
	overflow: visible; /* removes extra width in IE */
}
.ui-button,
.ui-button:link,
.ui-button:visited,
.ui-button:hover,
.ui-button:active {
	text-decoration: none;
}
/* to make room for the icon, a width needs to be set here */
.ui-button-icon-only {
	width: 2.2em;
}
/* button elements seem to need a little more width */
button.ui-button-icon-only {
	width: 2.4em;
}
.ui-button-icons-only {
	width: 3.4em;
}
button.ui-button-icons-only {
	width: 3.7em;
}

/* button text element */
.ui-button .ui-button-text {
	display: block;
	line-height: normal;
}
.ui-button-text-only .ui-button-text {
	padding: .4em 1em;
}
.ui-button-icon-only .ui-button-text,
.ui-button-icons-only .ui-button-text {
	padding: .4em;
	text-indent: -9999999px;
}
.ui-button-text-icon-primary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 1em .4em 2.1em;
}
.ui-button-text-icon-secondary .ui-button-text,
.ui-button-text-icons .ui-button-text {
	padding: .4em 2.1em .4em 1em;
}
.ui-button-text-icons .ui-button-text {
	padding-left: 2.1em;
	padding-right: 2.1em;
}
/* no icon support for input elements, provide padding by default */
input.ui-button {
	padding: .4em 1em;
}

/* button icon element(s) */
.ui-button-icon-only .ui-icon,
.ui-button-text-icon-primary .ui-icon,
.ui-button-text-icon-secondary .ui-icon,
.ui-button-text-icons .ui-icon,
.ui-button-icons-only .ui-icon {
	position: absolute;
	top: 50%;
	margin-top: -8px;
}
.ui-button-icon-only .ui-icon {
	left: 50%;
	margin-left: -8px;
}
.ui-button-text-icon-primary .ui-button-icon-primary,
.ui-button-text-icons .ui-button-icon-primary,
.ui-button-icons-only .ui-button-icon-primary {
	left: .5em;
}
.ui-button-text-icon-secondary .ui-button-icon-secondary,
.ui-button-text-icons .ui-button-icon-secondary,
.ui-button-icons-only .ui-button-icon-secondary {
	right: .5em;
}

/* button sets */
.ui-buttonset {
	margin-right: 7px;
}
.ui-buttonset .ui-button {
	margin-left: 0;
	margin-right: -.3em;
}

/* workarounds */
/* reset extra padding in Firefox, see h5bp.com/l */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
	border: 0;
	padding: 0;
}
.ui-datepicker {
	width: 17em;
	padding: .2em .2em 0;
	display: none;
}
.ui-datepicker .ui-datepicker-header {
	position: relative;
	padding: .2em 0;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
	position: absolute;
	top: 2px;
	width: 1.8em;
	height: 1.8em;
}
.ui-datepicker .ui-datepicker-prev-hover,
.ui-datepicker .ui-datepicker-next-hover {
	top: 1px;
}
.ui-datepicker .ui-datepicker-prev {
	left: 2px;
}
.ui-datepicker .ui-datepicker-next {
	right: 2px;
}
.ui-datepicker .ui-datepicker-prev-hover {
	left: 1px;
}
.ui-datepicker .ui-datepicker-next-hover {
	right: 1px;
}
.ui-datepicker .ui-datepicker-prev span,
.ui-datepicker .ui-datepicker-next span {
	display: block;
	position: absolute;
	left: 50%;
	margin-left: -8px;
	top: 50%;
	margin-top: -8px;
}
.ui-datepicker .ui-datepicker-title {
	margin: 0 2.3em;
	line-height: 1.8em;
	text-align: center;
}
.ui-datepicker .ui-datepicker-title select {
	font-size: 1em;
	margin: 1px 0;
}
.ui-datepicker select.ui-datepicker-month-year {
	width: 100%;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
	width: 49%;
}
.ui-datepicker table {
	width: 100%;
	font-size: .9em;
	border-collapse: collapse;
	margin: 0 0 .4em;
}
.ui-datepicker th {
	padding: .7em .3em;
	text-align: center;
	font-weight: bold;
	border: 0;
}
.ui-datepicker td {
	border: 0;
	padding: 1px;
}
.ui-datepicker td span,
.ui-datepicker td a {
	display: block;
	padding: .2em;
	text-align: right;
	text-decoration: none;
}
.ui-datepicker .ui-datepicker-buttonpane {
	background-image: none;
	margin: .7em 0 0 0;
	padding: 0 .2em;
	border-left: 0;
	border-right: 0;
	border-bottom: 0;
}
.ui-datepicker .ui-datepicker-buttonpane button {
	float: right;
	margin: .5em .2em .4em;
	cursor: pointer;
	padding: .2em .6em .3em .6em;
	width: auto;
	overflow: visible;
}
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
	float: left;
}

/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi {
	width: auto;
}
.ui-datepicker-multi .ui-datepicker-group {
	float: left;
}
.ui-datepicker-multi .ui-datepicker-group table {
	width: 95%;
	margin: 0 auto .4em;
}
.ui-datepicker-multi-2 .ui-datepicker-group {
	width: 50%;
}
.ui-datepicker-multi-3 .ui-datepicker-group {
	width: 33.3%;
}
.ui-datepicker-multi-4 .ui-datepicker-group {
	width: 25%;
}
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
	border-left-width: 0;
}
.ui-datepicker-multi .ui-datepicker-buttonpane {
	clear: left;
}
.ui-datepicker-row-break {
	clear: both;
	width: 100%;
	font-size: 0;
}

/* RTL support */
.ui-datepicker-rtl {
	direction: rtl;
}
.ui-datepicker-rtl .ui-datepicker-prev {
	right: 2px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next {
	left: 2px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-prev:hover {
	right: 1px;
	left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next:hover {
	left: 1px;
	right: auto;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane {
	clear: right;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
	float: left;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
.ui-datepicker-rtl .ui-datepicker-group {
	float: right;
}
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
	border-right-width: 0;
	border-left-width: 1px;
}
.ui-dialog {
	position: absolute;
	top: 0;
	left: 0;
	padding: .2em;
	outline: 0;
}
.ui-dialog .ui-dialog-titlebar {
	padding: .4em 1em;
	position: relative;
}
.ui-dialog .ui-dialog-title {
	float: left;
	margin: .1em 0;
	white-space: nowrap;
	width: 90%;
	overflow: hidden;
	text-overflow: ellipsis;
}
.ui-dialog .ui-dialog-titlebar-close {
	position: absolute;
	right: .3em;
	top: 50%;
	width: 21px;
	margin: -10px 0 0 0;
	padding: 1px;
	height: 20px;
}
.ui-dialog .ui-dialog-content {
	position: relative;
	border: 0;
	padding: .5em 1em;
	background: none;
	overflow: auto;
}
.ui-dialog .ui-dialog-buttonpane {
	text-align: left;
	border-width: 1px 0 0 0;
	background-image: none;
	margin-top: .5em;
	padding: .3em 1em .5em .4em;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
	float: right;
}
.ui-dialog .ui-dialog-buttonpane button {
	margin: .5em .4em .5em 0;
	cursor: pointer;
}
.ui-dialog .ui-resizable-se {
	width: 12px;
	height: 12px;
	right: -5px;
	bottom: -5px;
	background-position: 16px 16px;
}
.ui-draggable .ui-dialog-titlebar {
	cursor: move;
}
.ui-menu {
	list-style: none;
	padding: 2px;
	margin: 0;
	display: block;
	outline: none;
}
.ui-menu .ui-menu {
	margin-top: -3px;
	position: absolute;
}
.ui-menu .ui-menu-item {
	margin: 0;
	padding: 0;
	width: 100%;
	/* support: IE10, see #8844 */
	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}
.ui-menu .ui-menu-divider {
	margin: 5px -2px 5px -2px;
	height: 0;
	font-size: 0;
	line-height: 0;
	border-width: 1px 0 0 0;
}
.ui-menu .ui-menu-item a {
	text-decoration: none;
	display: block;
	padding: 2px .4em;
	line-height: 1.5;
	min-height: 0; /* support: IE7 */
	font-weight: normal;
}
.ui-menu .ui-menu-item a.ui-state-focus,
.ui-menu .ui-menu-item a.ui-state-active {
	font-weight: normal;
	margin: -1px;
}

.ui-menu .ui-state-disabled {
	font-weight: normal;
	margin: .4em 0 .2em;
	line-height: 1.5;
}
.ui-menu .ui-state-disabled a {
	cursor: default;
}

/* icon support */
.ui-menu-icons {
	position: relative;
}
.ui-menu-icons .ui-menu-item a {
	position: relative;
	padding-left: 2em;
}

/* left-aligned */
.ui-menu .ui-icon {
	position: absolute;
	top: .2em;
	left: .2em;
}

/* right-aligned */
.ui-menu .ui-menu-icon {
	position: static;
	float: right;
}
.ui-progressbar {
	height: 2em;
	text-align: left;
	overflow: hidden;
}
.ui-progressbar .ui-progressbar-value {
	margin: -1px;
	height: 100%;
}
.ui-progressbar .ui-progressbar-overlay {
	background: url("../../images/jqueryui/red/animated-overlay.gif");
	height: 100%;
	filter: alpha(opacity=25);
	opacity: 0.25;
}
.ui-progressbar-indeterminate .ui-progressbar-value {
	background-image: none;
}
.ui-slider {
	position: relative;
	text-align: left;
}
.ui-slider .ui-slider-handle {
	position: absolute;
	z-index: 2;
	width: 1.2em;
	height: 1.2em;
	cursor: default;
}
.ui-slider .ui-slider-range {
	position: absolute;
	z-index: 1;
	font-size: .7em;
	display: block;
	border: 0;
	background-position: 0 0;
}

/* For IE8 - See #6727 */
.ui-slider.ui-state-disabled .ui-slider-handle,
.ui-slider.ui-state-disabled .ui-slider-range {
	filter: inherit;
}

.ui-slider-horizontal {
	height: .8em;
}
.ui-slider-horizontal .ui-slider-handle {
	top: -.3em;
	margin-left: -.6em;
}
.ui-slider-horizontal .ui-slider-range {
	top: 0;
	height: 100%;
}
.ui-slider-horizontal .ui-slider-range-min {
	left: 0;
}
.ui-slider-horizontal .ui-slider-range-max {
	right: 0;
}

.ui-slider-vertical {
	width: .8em;
	height: 100px;
}
.ui-slider-vertical .ui-slider-handle {
	left: -.3em;
	margin-left: 0;
	margin-bottom: -.6em;
}
.ui-slider-vertical .ui-slider-range {
	left: 0;
	width: 100%;
}
.ui-slider-vertical .ui-slider-range-min {
	bottom: 0;
}
.ui-slider-vertical .ui-slider-range-max {
	top: 0;
}
.ui-spinner {
	position: relative;
	display: inline-block;
	overflow: hidden;
	padding: 0;
	vertical-align: middle;
}
.ui-spinner-input {
	border: none;
	background: none;
	color: inherit;
	padding: 0;
	margin: .2em 0;
	vertical-align: middle;
	margin-left: .4em;
	margin-right: 22px;
}
.ui-spinner-button {
	width: 16px;
	height: 50%;
	font-size: .5em;
	padding: 0;
	margin: 0;
	text-align: center;
	position: absolute;
	cursor: default;
	display: block;
	overflow: hidden;
	right: 0;
}
/* more specificity required here to overide default borders */
.ui-spinner a.ui-spinner-button {
	border-top: none;
	border-bottom: none;
	border-right: none;
}
/* vertical centre icon */
.ui-spinner .ui-icon {
	position: absolute;
	margin-top: -8px;
	top: 50%;
	left: 0;
}
.ui-spinner-up {
	top: 0;
}
.ui-spinner-down {
	bottom: 0;
}

/* TR overrides */
.ui-spinner .ui-icon-triangle-1-s {
	/* need to fix icons sprite */
	background-position: -65px -16px;
}
.ui-tabs {
	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
	padding: .2em;
}
.ui-tabs .ui-tabs-nav {
	margin: 0;
	padding: .2em .2em 0;
}
.ui-tabs .ui-tabs-nav li {
	list-style: none;
	float: left;
	position: relative;
	top: 0;
	margin: 1px .2em 0 0;
	border-bottom-width: 0;
	padding: 0;
	white-space: nowrap;
}
.ui-tabs .ui-tabs-nav li a {
	float: left;
	padding: .5em 1em;
	text-decoration: none;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
	margin-bottom: -1px;
	padding-bottom: 1px;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
	cursor: text;
}
.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
	cursor: pointer;
}
.ui-tabs .ui-tabs-panel {
	display: block;
	border-width: 0;
	padding: 1em 1.4em;
	background: none;
}
.ui-tooltip {
	padding: 8px;
	position: absolute;
	z-index: 9999;
	max-width: 300px;
	-webkit-box-shadow: 0 0 5px #aaa;
	box-shadow: 0 0 5px #aaa;
}
body .ui-tooltip {
	border-width: 2px;
}

/* Component containers
----------------------------------*/
.ui-widget {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1.1em;
}
.ui-widget .ui-widget {
	font-size: 1em;
}
.ui-widget input,
.ui-widget select,
.ui-widget textarea,
.ui-widget button {
	font-family: Helvetica,Arial,sans-serif;
	font-size: 1em;
}
.ui-widget-content {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/red/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-widget-content a {
	color: #444444;
}
.ui-widget-header {
	border: 1px solid #dddddd;
	background: #dddddd url("../../images/jqueryui/red/ui-bg_highlight-soft_50_dddddd_1x100.png") 50% 50% repeat-x;
	color: #444444;
	font-weight: bold;
}
.ui-widget-header a {
	color: #444444;
}

/* Interaction states
----------------------------------*/
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
	border: 1px solid #dddddd;
	background: #f6f6f6 url("../../images/jqueryui/red/ui-bg_highlight-soft_100_f6f6f6_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #444;
}
.ui-state-default a,
.ui-state-default a:link,
.ui-state-default a:visited {
	color: #444;
	text-decoration: none;
}
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus {
	border: 1px solid #EA4F4F;
	background: #EA4F4F url("../../images/jqueryui/red/ui-bg_highlight-soft_25_EA4F4F_1x100.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #ffffff;
}
.ui-state-hover a,
.ui-state-hover a:hover,
.ui-state-hover a:link,
.ui-state-hover a:visited {
	color: #ffffff;
	text-decoration: none;
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active {
	border: 1px solid #dddddd;
	background: #ffffff url("../../images/jqueryui/red/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
	font-weight: bold;
	color: #EA4F4F;
}
.ui-state-active a,
.ui-state-active a:link,
.ui-state-active a:visited {
	color: #EA4F4F;
	text-decoration: none;
}

/* Interaction Cues
----------------------------------*/
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
	border: 1px solid #cccccc;
	background: #ffffff url("../../images/jqueryui/red/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #444444;
}
.ui-state-highlight a,
.ui-widget-content .ui-state-highlight a,
.ui-widget-header .ui-state-highlight a {
	color: #444444;
}
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-widget-header .ui-state-error {
	border: 1px solid #EA4F4F;
	background: #ffffff url("../../images/jqueryui/red/ui-bg_flat_55_ffffff_40x100.png") 50% 50% repeat-x;
	color: #222222;
}
.ui-state-error a,
.ui-widget-content .ui-state-error a,
.ui-widget-header .ui-state-error a {
	color: #222222;
}
.ui-state-error-text,
.ui-widget-content .ui-state-error-text,
.ui-widget-header .ui-state-error-text {
	color: #222222;
}
.ui-priority-primary,
.ui-widget-content .ui-priority-primary,
.ui-widget-header .ui-priority-primary {
	font-weight: bold;
}
.ui-priority-secondary,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
	opacity: .7;
	filter:Alpha(Opacity=70);
	font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
	opacity: .35;
	filter:Alpha(Opacity=35);
	background-image: none;
}
.ui-state-disabled .ui-icon {
	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
}

/* Icons
----------------------------------*/

/* states and images */
.ui-icon {
	width: 16px;
	height: 16px;
}
.ui-icon,
.ui-widget-content .ui-icon {
	background-image: url("../../images/jqueryui/red/ui-icons_EA4F4F_256x240.png");
}
.ui-widget-header .ui-icon {
	background-image: url("../../images/jqueryui/red/ui-icons_EA4F4F_256x240.png");
}
.ui-state-default .ui-icon {
	background-image: url("../../images/jqueryui/red/ui-icons_666666_256x240.png");
}
.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon {
	background-image: url("../../images/jqueryui/red/ui-icons_ffffff_256x240.png");
}
.ui-state-active .ui-icon {
	background-image: url("../../images/jqueryui/red/ui-icons_454545_256x240.png");
}
.ui-state-highlight .ui-icon {
	background-image: url("../../images/jqueryui/red/ui-icons_EA4F4F_256x240.png");
}
.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon {
	background-image: url("../../images/jqueryui/red/ui-icons_EA4F4F_256x240.png");
}

/* positioning */
.ui-icon-blank { background-position: 16px 16px; }
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -97px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-on { background-position: -96px -144px; }
.ui-icon-radio-off { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }


/* Misc visuals
----------------------------------*/

/* Corner radius */
.ui-corner-all,
.ui-corner-top,
.ui-corner-left,
.ui-corner-tl {
	border-top-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-top,
.ui-corner-right,
.ui-corner-tr {
	border-top-right-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-left,
.ui-corner-bl {
	border-bottom-left-radius: 2px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-right,
.ui-corner-br {
	border-bottom-right-radius: 2px;
}

/* Overlays */
.ui-widget-overlay {
	background: #eeeeee url("../../images/jqueryui/red/ui-bg_flat_0_eeeeee_40x100.png") 50% 50% repeat-x;
	opacity: .8;
	filter: Alpha(Opacity=80);
}
.ui-widget-shadow {
	margin: -4px 0 0 -4px;
	padding: 4px;
	background: #aaaaaa url("../../images/jqueryui/red/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
	opacity: .6;
	filter: Alpha(Opacity=60);
	border-radius: 0px;
}
#page-inner {
	position: relative;
	padding-bottom: 170px;
	overflow: hidden;
}
#header-inner,
#nav-inner,
#connection-inner,
#content-inner,
#footer-inner {
	width: 99%;
}
footer,
#theme,
#lang,
#newfolder,
.menu-principal ul li.accesslink,
.section-chat #chatColor,
.section-chat #chatDestination,
.section-chat #chatSend,
.options-radio-inline li .icon,
.connection-label label {
	display: none;
}
#content {
	margin-top: 50px;
}
#as_server,
#as_password,
#as_adminlevel {
	clear: both;
	float: left;
	margin: 5px 0;
	padding: 5px 10px;
	width: 100%;
}
#as_password {
	width: 97.5%;
}
#connection-inner,
.menu-principal {
	height: 100%;
}
#connection-inner .connection-label,
#connection-inner .connection-login {
	width: 99%;
}
#as_login {
	width: 100%;
}

.speed-admin {
	position: absolute;
	left: 0;
	top: 84px;
	width: 60%;
}
.speed-admin ul {
	width: 100%;
	height: 27px;
	background: #555;
}
.speed-admin ul li {
	display: block;
	float: left;
}
.speed-admin ul li + li {
	margin-left: 2px;
}
.speed-admin ul li a {
	padding: 5px 22px 0;
	background-position: 20px 5px;
}
.speed-admin ul li a:hover,
.speed-admin ul li a.locked {
	background-position: 20px 5px;
}
.speed-admin ul li + li a {
	margin: 0;
}
.switch-server {
	top: 84px;
	right: 0;
	width: 40%;
}
.switch-server #switchServerList {
	padding: 7px 10px 8px;
	width: 100%;
	border: 0;
	-webkit-border-radius: 0 0 5px 5px;
	-moz-border-radius: 0 0 5px 5px;
	-ms-border-radius: 0 0 5px 5px;
	-o-border-radius: 0 0 5px 5px;
	border-radius: 0 0 5px 5px;
}

.horizontal-nav {
	position: absolute;
	bottom: 0;
	padding-bottom: 5px;
	width: 100%;
}
.menu-principal {
	height: 140px;
	border-width: 1px;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-ms-border-radius: 5px;
	-o-border-radius: 5px;
	border-radius: 5px;
}
.menu-principal ul {
	width: 102%;
}
.menu-principal .menu-right {
	clear: both;
	float: left;
	padding-left: 5px;
}
.menu-principal ul li {
	margin-bottom: 4px;
	width: 48.5%;
}
.menu-principal ul li.accessgeneral {
	width: 99%;
}
.menu-principal .menu-right li {
	width: 32%;
}
.menu-principal ul li a {
	height: 25px;
	line-height: 25px;
	font-size: 1.05em;
	-webkit-border-radius: 0;
	-moz-border-radius: 0;
	-ms-border-radius: 0;
	-o-border-radius: 0;
	border-radius: 0;
}
.section-index .cadre.left,
.section-guestban .cadre.left,
.hasMenu.hasFolders .cadre.left.menu {
	margin-bottom: 10px;
	width: 97.5%;
}
.section-index .cadre.right,
.section-guestban .cadre.right {
	clear: both;
	float: left;
	margin: -10px 0 0;
	padding-top: 20px;
	padding-left: 10px;
	width: 97.5%;
}
.section-index .title-detail,
.section-guestban .title-detail {
	top: 24px;
}
#playerlist {
	min-height: 150px;
}
.section-chat #chatNickname {
	width: 18%;
}
.section-chat #chatSend {
	width: 20%;
}
.section-chat #chatMessage {
	margin: 0;
	width: 68%;
}

.hasMenu .cadre.right,
.hasMenu.hasFolders .cadre.right {
	width: 71%;
}
.cadre.left.menu {
	margin-bottom: 0;
}
.cadre.middle.folders {
	clear: left;
	width: 15.5%;
}
.options-radio-inline li {
	width: 22%;
}
.options-radio-inline li .name {
	width: 100%;
}
.section-maps-order .options-radio-inline li {
	width: 14%;
}
.section-maps-order .save {
	margin-top: 10px;
}
.path {
	width: 200px;
}
<?php	// Includes	session_start();	$configPath = '../../'.$_SESSION['adminserv']['path'].'config/';	require_once $configPath.'adminserv.cfg.php';	require_once $configPath.'extension.cfg.php';		// Thème	$themeColor = (isset($_GET['th'])) ? addslashes($_GET['th']) : AdminServConfig::DEFAULT_THEME;?><?php if($themeColor != null): ?>	<?php		$color1 = ExtensionConfig::$THEMES[$themeColor][0];		$color2 = ExtensionConfig::$THEMES[$themeColor][1];				// CSS		header('Content-type: text/css');	?>/* Color */#title .title-color,h2,h3 {	color: <?php echo $color1; ?>;}/* Background color */#header-color-line,h1,.menu .vertical-nav ul li a.active,.menu .vertical-nav ul li a:hover,.qq-upload-button-hover,.qq-upload-drop-area-active,.qq-progress-bar {	background-color: <?php echo $color1; ?>;}tbody tr.selected,.options-radio-inline li:hover,.options-radio-inline li.selected,.ui-sortable li:hover {	background-color: <?php echo $color2; ?>;}/* Others */.button.light,.button.dark {	-webkit-box-shadow: 0 4px 0 <?php echo $color1; ?>;	-moz-box-shadow: 0 4px 0 <?php echo $color1; ?>;	-ms-box-shadow: 0 4px 0 <?php echo $color1; ?>;	-o-box-shadow: 0 4px 0 <?php echo $color1; ?>;	box-shadow: 0 4px 0 <?php echo $color1; ?>;}fieldset legend {	-webkit-box-shadow: 0 3px <?php echo $color1; ?>;	-moz-box-shadow: 0 3px <?php echo $color1; ?>;	-ms-box-shadow: 0 3px <?php echo $color1; ?>;	-o-box-shadow: 0 3px <?php echo $color1; ?>;	box-shadow: 0 3px <?php echo $color1; ?>;}.menu .vertical-nav ul li a {	border-bottom-color: <?php echo $color2; ?>;}.options-checkbox {	border-left-color: <?php echo $color1; ?>;}.folders .option-folder-list .arrow-down {	border-color: <?php echo $color1; ?> transparent transparent;}.folders .option-folder-list .arrow-up {	border-color: transparent transparent <?php echo $color1; ?>;}.content p a {	border-color: <?php echo $color1; ?>;}<?php endif; ?>
$(document).ready(function(){
	
	/**
	* Global
	*/
	$('#theme, #lang').hover(function(){
		$(this).css('height', $(this).find('ul').height()+'px');
	}, function(){
		$(this).css('height', $(this).find('ul li:first-child').height()+'px');
	});
	$('#footer-inner a').click(function(event){
		event.preventDefault();
		window.open( $(this).attr('href') );
	});
	
	
	/**
	* Config
	*/
	if( $('body').hasClass('config') ){
		/**
		* Serveurs
		*/
		if( $('body').hasClass('section-config-servers') ){
			// Clic sur les lignes
			$('#serverList').on('click', 'tr', function(){
				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
					// Si la ligne est déjà sélectionnée, on l'enlève
					if( $(this).hasClass('selected') ){
						$('#serverList tr').removeClass('selected');
						$(this).find('td.checkbox input').prop('checked', false);
					}
					// Sinon, on l'ajoute
					else{
						$('#serverList tr').removeClass('selected');
						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
					}
				}
				
				// Mise à jour du nb de lignes sélectionnées
				$('.cadre').updateNbSelectedLines();
			});
			// Supprimer un serveur
			$('#deleteserver').click(function(){
				if( !confirm( $(this).data('confirm-text') ) ){
					return false;
				}
			});
		}
		else if( $('body').hasClass('section-config-addserver') ){
			$('#addServerAdmLvlSA, #addServerAdmLvlADM, #addServerAdmLvlUSR').blur(function(){
				if( $(this).val() == '' ){
					$(this).val('all');
				}
			});
		}
		else if( $('body').hasClass('section-config-serversorder') ){
			// Tri manuel
			$('#sortableServersList').sortable({
				placeholder: 'ui-state-highlight',
				revert: true,
				zIndex: 9999
			}).disableSelection();
			$('#reset').click(function(){
				location.href = $('.section-config-serversorder .cadre form').attr('action');
			});
			$('#save').click(function(){
				var listStr = '';
				var list = $('#sortableServersList li .order-server-name');
				if( list.length > 0 ){
					$.each(list, function(i, n){
						listStr += n.textContent+',';
					});
					$('#list').val(listStr.substring(0, listStr.length-1));
				}
			});
		}
		else if( $('body').hasClass('section-config-adminlevel') ){
			// Clic sur les lignes
			$('#levelList').on('click', 'tr', function(){
				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
					// Si la ligne est déjà sélectionnée, on l'enlève
					if( $(this).hasClass('selected') ){
						$('#levelList tr').removeClass('selected');
						$(this).find('td.checkbox input').prop('checked', false);
					}
					// Sinon, on l'ajoute
					else{
						$('#levelList tr').removeClass('selected');
						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
					}
				}
				
				// Mise à jour du nb de lignes sélectionnées
				$('.cadre').updateNbSelectedLines();
			});
			// Supprimer un niveau admin
			$('#deletelevel').click(function(){
				if( !confirm( $(this).data('confirm-text') ) ){
					return false;
				}
			});
		}
		else if( $('body').hasClass('section-config-addlevel') ){
			// Access
			$('#defaultAccess, #selectedAccess').sortable({
				connectWith: '.adminlevelAccessList',
				revert: true
			}).disableSelection();
			// Permission
			$('#defaultPermission, #selectedPermission').sortable({
				connectWith: '.adminlevelPermissionList',
				revert: true
			}).disableSelection();
			
			// Submit
			$('#savelevel').click(function(){
				var lists = {
					access: {
						list: '#selectedAccess li',
						target: '#selectedAccessSortList'
					},
					permission: {
						list: '#selectedPermission li',
						target: '#selectedPermissionSortList'
					}
				};
				$.each(lists, function(i, n){
					var out = '';
					var selector = $(n.list);
					if(selector.length > 0){
						selector.each(function(){
							out += $(this).text()+',';
						});
						$(n.target).val(out.substring(0, out.length-1));
					}
				});
			});
		}
		else if( $('body').hasClass('section-config-levelsorder') ){
			// Tri manuel
			$('#sortableLevelsList').sortable({
				placeholder: 'ui-state-highlight',
				revert: true,
				zIndex: 9999
			}).disableSelection();
			$('#reset').click(function(){
				location.href = $('.section-config-levelsorder .cadre form').attr('action');
			});
			$('#save').click(function(){
				var listStr = '';
				var list = $('#sortableLevelsList li .order-server-name');
				if( list.length > 0 ){
					$.each(list, function(i, n){
						listStr += n.textContent+',';
					});
					$('#list').val(listStr.substring(0, listStr.length-1));
				}
			});
		}
	}
	/**
	* Front
	*/
	else if( $('body').hasClass('front') ){
		// Adminlevel
		getServerAdminLevel();
		$('#as_server').change(function(){
			getServerAdminLevel();
			if( $('#error').css('display') == 'block' ){
				$('#error').attr('hidden', true).fadeOut('fast');
			}
		});
		$('#as_adminlevel').click(function(){
			if( $(this).html() == '' ){
				getServerAdminLevel();
			}
		});
		
		// Connexion
		$(document).keypress(function(event){
			if(event.keyCode == 13){
				$('#connection form').submit();
			}
		});
	}
	/**
	* Not front
	*/
	else{
		/**
		* Nouveau dossier
		*/
		$('#newfolder').click(function(event){
			event.preventDefault();
			if( $('#form-new-folder').prop('hidden') ){
				slideDownNewFolderForm();
			}
			else{
				slideUpNewFolderForm();
			}
		});
		$('#newFolderName').keypress(function(event){
			if(event.keyCode == 13){
				if( $(this).val() != '' ){
					$('#createFolderForm').submit();
				}
				else{
					slideUpNewFolderForm();
				}
			}
		});
		$('#newFolderValid').click(function(){
			if( $('#newFolderName').val() != '' ){
				return true;
			}
			else{
				slideUpNewFolderForm();
				return false;
			}
		});
		
		
		/**
		* Option du dossier
		*/
		$('.path').scrollLeft(1000);
		$('.folders .option-folder-list h3').click(function(){
			var selector = $(this).parent().find('ul');
			if( selector.attr('hidden') ){
				selector.slideDown('fast').removeAttr('hidden');
				$(this).find('span').removeClass('arrow-down').addClass('arrow-up');
			}
			else{
				selector.slideUp('fast').attr('hidden', true);
				$(this).find('span').removeClass('arrow-up').addClass('arrow-down');
			}
		});
		$('#renameFolder').click(function(event){
			event.preventDefault();
			$('#optionFolderHiddenFieldAction').val('rename');
			getRenameFolderForm();
		});
		$('#moveFolder').click(function(event){
			event.preventDefault();
			$('#optionFolderHiddenFieldAction').val('move');
			getMoveFolderForm();
		});
		$('#deleteFolder').click(function(event){
			event.preventDefault();
			if( confirm( $(this).data('confirm-text') ) ){
				$('#optionFolderHiddenFieldAction').val('delete');
				$('#optionFolderForm').submit();
			}
		});
		
		
		/**
		* SpeedAdmin
		*/
		$('.speed-admin a').click(function(event){
			event.preventDefault();
			if( !$(this).hasClass('locked') ){
				$(this).addClass('locked');
				speedAdmin( $(this).text() );
			}
		});
		
		
		/**
		* SwitchServer
		*/
		$('#switchServerList').change(function(){
			var page = getUrlParams('p');
			var option = $(this).find('option:selected').val();
			if(page){
				location.href = '?p='+page+'&switch='+option;
			}
			else{
				location.href = '?switch='+option;
			}
		});
		
		
		/**
		* Scroll doux
		*/
		$('a[href^="#"]').click(function(event){
			event.preventDefault();
			var target = $(this).attr('href');
			$('html, body').animate({  
				scrollTop: $(target).offset().top - 100
			}, 'slow');
		});
		
		
		/**
		* Général
		*/
		if( $('body').hasClass('section-index') ){
			// Infos serveur
			setInterval(function(){
				getCurrentServerInfo(getMode(), getCurrentSort() );
			}, 10000);
			
			// Checkbox
			$('#checkAll').click(function(){
				$('#playerlist').checkAll( $(this).attr('checked') );
				
				// Mise à jour du nb de lignes sélectionnées
				$('.cadre.right').updateNbSelectedLines();
			});
			
			// Clic sur les lignes
			$('#playerlist').on('click', 'tr', function(){
				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
					// Si la ligne est déjà sélectionnée, on l'enlève
					if( $(this).hasClass('selected') ){
						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
					}
					// Sinon, on l'ajoute
					else{
						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
					}
					
					// Mise à jour du nb de lignes sélectionnées
					$('.cadre.right').updateNbSelectedLines();
					$('.cadre.right').updateCheckAll( $('#checkAll') );
				}
			});
			
			// Mode détail
			$('#detailMode').click(function(event){
				event.preventDefault();
				$('#playerlist').setDetailMode();
			});
			
			// Tris
			$('#playerlist table th a').click(function(event){
				event.preventDefault();
				$('#playerlist').addClass('loading');
				getCurrentServerInfo(getMode(), $(this).attr('href').split('=')[1]);
			});
		}
		/**
		* Server Options
		*/
		else if( $('body').hasClass('section-srvopts') ){
			// ServerName
			$('#ServerName').keyup(function(event){
				var key = event.keyCode;
				if(key != 13 && key != 37 && key != 39){
					$('#serverNameHtml').getColorHtml( $(this).val() );
				}
			});
			$('#ServerName').blur(function(){
				$('#serverNameHtml').getColorHtml( $(this).val() );
			});
			
			// ServerComment
			$('#ServerComment').keyup(function(event){
				var key = event.keyCode;
				if(key != 37 && key != 39){
					$('#serverCommentHtml').getColorHtml('$i'+ $(this).val() );
				}
			});
			
			// VoteRato
			$('#callVoteRatioDisabled').change(function(){
				if( $(this).val() == '0' ){
					$(this).hide();
					$('#CallVoteRatio')
						.fadeIn('fast').removeAttr('hidden')
						.parent('td').find('.returnDefaultValue').fadeIn('fast').removeAttr('hidden');
					if( $('#CallVoteRatio').val() == -1 ){
						$('#CallVoteRatio').val('0.5');
					}
				}
			});
			// Désactiver le ratio vote
			$('#resetCallVoteRatio').click(function(event){
				event.preventDefault();
				$(this).fadeOut().attr('hidden', true);
				$('#CallVoteRatio').val('-1').hide().attr('hidden', true);
				$('#callVoteRatioDisabled').fadeIn('fast').removeAttr('hidden').find('option').removeAttr('selected');
				$('#callVoteRatioDisabled option:first').select();
			});
			
			// ClientInputsMaxLatency
			$('#ClientInputsMaxLatency').change(function(){
				if( $(this).val() == 'more' ){
					$(this).hide();
					$('#ClientInputsMaxLatencyValue').fadeIn('fast').removeAttr('hidden').parent('td').find('.returnDefaultValue').fadeIn('fast').removeAttr('hidden');
				}
			});
			// Revenir à la valeur par défaut
			$('#resetClientInputsMaxLarency').click(function(event){
				event.preventDefault();
				$(this).fadeOut().attr('hidden', true);
				$('#ClientInputsMaxLatencyValue').hide().attr('hidden', true).val('');
				$('#ClientInputsMaxLatency').fadeIn('fast').removeAttr('hidden').find('option').removeAttr('selected');
				$('#ClientInputsMaxLatency option:first').select();
			});
			
			
			// Gestion des options serveur
			$('.srvopts_importexport input[name="srvoptsImportExport"]').click(function(){
				var type = $(this).val();
				
				if(type == 'Import'){
					$('#srvoptsExportName').fadeOut().attr('hidden', true);
				}
				else{
					$('#srvoptsImportName').fadeOut().attr('hidden', true);
				}
				
				$('#srvopts'+type+'Name').fadeIn('fast').removeAttr('hidden');
			});
		}
		/**
		* Game Infos
		*/
		else if( $('body').hasClass('section-gameinfos') || $('body').hasClass('section-maps-creatematchset') ){
			// GameMode
			getCurrentGameModeConfig();
			$('#NextGameMode').change(function(){
				getCurrentGameModeConfig();
			});
			
			// FinishTimeout
			$('#NextFinishTimeout').change(function(){
				if( $(this).val() == 'more' ){
					$(this).hide();
					$('#NextFinishTimeoutValue').fadeIn('fast').removeAttr('hidden').val('15').parent('td').parent('tr').find('.returnDefaultValue').fadeIn('fast').parent('td').removeAttr('hidden');
				}
			});
			
			// ForceShowAllOpponents
			$('#NextForceShowAllOpponents').change(function(){
				if( $(this).val() == 'more' ){
					$(this).hide();
					$('#NextForceShowAllOpponentsValue').fadeIn('fast').removeAttr('hidden').val('2').parent('td').parent('tr').find('.returnDefaultValue').fadeIn('fast').parent('td').removeAttr('hidden');
				}
			});
			
			// Revenir à la valeur par défaut
			$('.returnDefaultValue').click(function(event){
				event.preventDefault();
				$(this).fadeOut().attr('hidden', true);
				$(this).parent('td').parent('tr').find('td.next input').hide().attr('hidden', true).val('');
				$(this).parent('td').parent('tr').find('td.next select').fadeIn('fast').find('option').removeAttr('selected').find('option:first').select().removeAttr('hidden');
			});
			
			// Infos équipes
			$('#colorPickerTeam1').css('backgroundColor', $('#teamInfo1ColorHex').val());
			$('#colorPickerTeam1').ColorPicker({
				color: $('#teamInfo1ColorHex').val(),
				onShow: function (colpkr) {
					$(colpkr).slideDown('fast');
					return false;
				},
				onHide: function (colpkr) {
					$(colpkr).slideUp('fast');
					return false;
				},
				onChange: function (hsb, hex, rgb) {
					$('#colorPickerTeam1').css('backgroundColor', '#'+hex);
					$('#teamInfo1ColorHex').val('#'+hex);
					var val = $('#colorPickerTeam1 .colorpicker_hue div').css('top');
					$('#teamInfo1Color').val(round(1 - val.substring(0, val.length-2)/150, 3));
				}
			});
			$('#colorPickerTeam2').css('backgroundColor', $('#teamInfo2ColorHex').val());
			$('#colorPickerTeam2').ColorPicker({
				color: $('#teamInfo2ColorHex').val(),
				onShow: function (colpkr) {
					$(colpkr).slideDown('fast');
					return false;
				},
				onHide: function (colpkr) {
					$(colpkr).slideUp('fast');
					return false;
				},
				onChange: function (hsb, hex, rgb) {
					$('#colorPickerTeam2').css('backgroundColor', '#'+hex);
					$('#teamInfo2ColorHex').val('#'+hex);
					var val = $('#colorPickerTeam2 .colorpicker_hue div').css('top');
					$('#teamInfo2Color').val(round(1 - val.substring(0, val.length-2)/150, 3));
				}
			});
			
			// Script settings
			$('#getScriptSettings').click(function(event){
				event.preventDefault();
				getScriptSettings();
			});
			
			// Affichage sec -> min
			$('#NextTimeAttackLimit, #NextLapsTimeLimit, #hotSeatTimeLimit').click(function(){
				$(this).parent('td').parent('tr').find('td.preview').html('['+secToMin( $(this).val() )+' min]');
			});
			$('#NextTimeAttackLimit, #NextLapsTimeLimit, #hotSeatTimeLimit').change(function(){
				$(this).parent('td').parent('tr').find('td.preview').html('['+secToMin( $(this).val() )+' min]');
			});
			$('#NextTimeAttackLimit, #NextLapsTimeLimit, #hotSeatTimeLimit').keyup(function(){
				$(this).parent('td').parent('tr').find('td.preview').html('['+secToMin( $(this).val() )+' min]');
			});
			$('#NextTimeAttackLimit, #NextLapsTimeLimit, #hotSeatTimeLimit').blur(function(){
				$(this).parent('td').parent('tr').find('td.preview').html('');
			});
			
			
			/**
			* Create MatchSettings
			*/
			if( $('body').hasClass('section-maps-creatematchset') ){
				// Nom du matchSetting
				$('#matchSettingName').keyup(function(event){
					var key = event.keyCode;
					if(key != 13 && key != 37 && key != 39){
						matchset_getFileExists( $(this).val() );
					}
				});
				
				// Importer tout le dossier
				$('#mapImport').click(function(){
					$('.creatematchset .maps').addClass('loading');
					matchset_mapImport();
				});
				
				// Faire une sélection
				$('#mapImportSelection').click(function(){
					$('.creatematchset .maps').addClass('loading');
					matchset_mapImportSelection();
				});
				
				// Checkbox
				$('#checkAllMapImport').click(function(){
					var dialog = $('#mapImportSelectionDialog');
					dialog.checkAll( $(this).attr('checked') );
					if( dialog.find('tr.current').hasClass('selected') ){
						dialog.find('tr.current').removeClass('selected');
					}
				});
				
				// Clic sur les lignes
				$('#mapImportSelectionDialog').on('click', 'tr', function(){
					// Si la ligne est déjà sélectionnée, on l'enlève
					if( $(this).hasClass('selected') ){
						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
					}
					// Sinon, on l'ajoute
					else{
						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
					}
					// Mise à jour du CheckAll
					$('#mapImportSelectionDialog').updateCheckAll( $('#checkAllMapImport') );
				});
				
				// Voir la sélection du matchsettings
				$('#mapSelection').click(function(){
					$('.creatematchset .maps').addClass('loading');
					matchset_mapSelection();
				});
				
				// Enlever une map de la sélection
				$('#mapSelectionDialog').on('click', 'tr a', function(event){
					event.preventDefault();
					matchset_mapSelection( parseInt($(this).parent('td').parent('tr')[0].sectionRowIndex) );
				});
				
				// Nom du MatchSettings
				$('#matchSettingName').click(function(){
					$(this).select();
				});
				$('#matchSettingName').blur(function(){
					if( $(this).val() == '' ){
						$(this).val('match_settings');
					}
				});
				
				// Submit
				$('#savematchsetting').click(function(){
					if( $('#nbMapSelected').text() == '0' ){
						scrollTop();
						error( $(this).data('nomap'), true);
						return false;
					}
					else{
						return true;
					}
				});
			}
		}
		/**
		* Chat
		*/
		else if( $('body').hasClass('section-chat') ){
			var hideServerLines = 0;
			
			// Clique sur "Masquer les lignes du serveur"
			$('.title-detail a').click(function(event){
				event.preventDefault();
				// Valeur
				hideServerLines = $(this).data('val');
				if(hideServerLines == 0){
					hideServerLines = 1;
				}
				else{
					hideServerLines = 0;
				}
				getChatServerLines(hideServerLines);
				$(this).data('val', hideServerLines);
				
				// Texte
				var text = $(this).text();
				$(this).text( $(this).data('txt') ).data('txt', text);
			});
			
			// Affichage toutes les 3s
			setInterval(function(){
				getChatServerLines(hideServerLines);
			}, 3000);
			
			// Ajout d'un message
			$('#chatNickname, #chatMessage').click(function(){
				var text = $(this).val();
				var defaultText = $(this).data('default-value');
				
				if(text == defaultText){
					$(this).val('');
				}
			});
			$('#chatNickname, #chatMessage').blur(function(){
				var text = $(this).val();
				var defaultText = $(this).data('default-value');
				
				if(text == ''){
					$(this).val(defaultText);
				}
			});
			$('#chatSend').click(function(){
				var msg = $('#chatMessage').val();
				if( msg != $('#chatMessage').data('default-value') && msg != '' ){
					addChatServerLine();
				}
			});
			$('#chatMessage').keypress(function(event){
				var msg = $(this).val();
				if( msg != $(this).data('default-value') && msg != '' ){
					if( event.keyCode == 13 ){
						addChatServerLine();
					}
				}
			});
		}
		/**
		* Maps-list
		*/
		else if( $('body').hasClass('section-maps-list') ){
			var mapList = $('#maplist');
			// Mise à jour de la liste
			setInterval(function(){
				getMapList(getMode());
			}, 10000);
			
			// Checkbox
			$('#checkAll').click(function(){
				mapList.checkAll( $(this).prop('checked') );
				if( mapList.find('tr.current').hasClass('selected') ){
					mapList.find('tr.current').removeClass('selected');
				}
				
				// Mise à jour du nb de lignes sélectionnées
				$('.maps .list').updateNbSelectedLines();
			});
			
			// Clic sur les lignes
			mapList.on('click', 'tr', function(){
				if( !$(this).hasClass('current') && !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
					// Si la ligne est déjà sélectionnée, on l'enlève
					if( $(this).hasClass('selected') ){
						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
					}
					// Sinon, on l'ajoute
					else{
						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
					}
					
					// Mise à jour du nb de lignes sélectionnées
					$('.maps .list').updateNbSelectedLines();
					$('.maps .list').updateCheckAll( $('#checkAll') );
				}
			});
			
			// Mode détail
			$('#detailMode').click(function(event){
				event.preventDefault();
				mapList.setDetailMode();
			});
		}
		/**
		* Maps-upload
		*/
		else if( $('body').hasClass('section-maps-upload') ){
			//Upload
			var uploader = initializeUploader();
			
			// Mode de transfert
			$('.transferMode li').click(function(){
				$('.transferMode li').removeClass('selected');
				$('.options-checkbox li')
					.removeClass('disabled')
					.find('input').prop('disabled', false);
				$('#GotoListMaps').prop('checked', true);
				
				$(this)
					.addClass('selected')
					.find('input').prop('checked', true);
				
				if( $(this).find('input').val() == 'local' ){
					$('#SaveCurrentMatchSettings')
						.prop('disabled', true)
						.parent().addClass('disabled');
					$('#GotoListMaps').prop('checked', false);
				}
				uploader.setParams( getUploaderUserParams() );
			});
			
			// Options
			$('.options-checkbox input, .options-checkbox label').click(function(){
				uploader.setParams( getUploaderUserParams() );
			});
		}
		/**
		* Maps-local
		*/
		else if( $('body').hasClass('section-maps-local') ){
			// Checkbox
			$('#checkAll').click(function(){
				$('#maplist').checkAll( $(this).prop('checked') );
				
				// Mise à jour du nb de lignes sélectionnées
				$('.maps .local').updateNbSelectedLines();
			});
			
			// Clic sur les lignes
			$('#maplist').on('click', 'tr', function(){
				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
					// Si la ligne est déjà sélectionnée, on l'enlève
					if( $(this).hasClass('selected') ){
						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
					}
					// Sinon, on l'ajoute
					else{
						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
					}
					
					// Mise à jour du nb de lignes sélectionnées
					$('.maps .local').updateNbSelectedLines();
					$('.maps .local').updateCheckAll( $('#checkAll') );
					
					// Vérifie s'il reste des formulaires ouvert et les ferme quand il y 0 lignes sélectionnées
					if( $('#maplist tr.selected').length == 0 ){
						if( $('.selected-files-label').hasClass('optHover') ){
							slideUpRenameForm();
							slideUpMoveForm();
						}
					}
				}
			});
			
			// Renommer
			$('#renameMap').click(function(){
				if( !$('#maplist tr.selected').hasClass('onserver') ){
					if( $(this).hasClass('active') ){
						slideUpRenameForm();
					}
					else{
						if( $('#moveMap').hasClass('active') ){
							slideUpMoveForm();
						}
						slideDownRenameForm();
					}
				}
				else{
					var mapTextError = $('.local .options').data('mapisused').split(',');
					var mapName = $('#maplist tr.selected td span').html();
					error(mapTextError[0]+' '+mapName+' '+mapTextError[1]);
					scrollTop();
				}
			});
			$('#form-rename-map').on('click', '#renameMapCancel', function(){
				slideUpRenameForm();
			});
			
			// Déplacer
			$('#moveMap').click(function(){
				if( !$('#maplist tr.selected').hasClass('onserver') ){
					if( $(this).hasClass('active') ){
						slideUpMoveForm();
					}
					else{
						if( $('#renameMap').hasClass('active') ){
							slideUpRenameForm();
						}
						slideDownMoveForm();
					}
				}
				else{
					var mapTextError = $('.local .options').data('mapisused').split(',');
					var mapName = $('#maplist tr.selected td span').html();
					error(mapTextError[0]+' '+mapName+' '+mapTextError[1]);
					scrollTop();
				}
			});
			$('#form-move-map').on('click', '#moveMapCancel', function(){
				slideUpMoveForm();
			});
			
			// Supprimer
			$('#deleteMap').click(function(){
				if( !$('#maplist tr.selected').hasClass('onserver') ){
					return confirm( $(this).data('confirm') );
				}
				else{
					var mapTextError = $('.local .options').data('mapisused').split(',');
					var mapName = $('#maplist tr.selected td span').html();
					error(mapTextError[0]+' '+mapName+' '+mapTextError[1]);
					scrollTop();
					return false;
				}
			});
		}
		/**
		* Maps-matchset
		*/
		else if( $('body').hasClass('section-maps-matchset') ){
			// Checkbox
			$('input#checkAll').click(function(){
				$('#matchsetlist').checkAll( $(this).prop('checked') );
				
				// Mise à jour du nb de lignes sélectionnées
				$('.maps .matchset').updateNbSelectedLines();
			});
			
			// Clic sur les lignes
			$('#matchsetlist').on('click', 'tr', function(){
				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
					// Si la ligne est déjà sélectionnée, on l'enlève
					if( $(this).hasClass('selected') ){
						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
					}
					// Sinon, on l'ajoute
					else{
						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
					}
					
					// Mise à jour du nb de lignes sélectionnées
					$('.maps .matchset').updateNbSelectedLines();
					$('.maps .matchset').updateCheckAll( $('input#checkAll') );
					
					// Édition si une seule ligne sélectionné
					if( $('.selected-files-count').text().replace('(', '').replace(')', '') > 1 ){
						$('#editMatchset').attr('hidden', true);
					}
					else{
						if( $('#editMatchset').attr('hidden') ){
							$('#editMatchset').removeAttr('hidden');
						}
					}
				}
			});
		}
		/**
		* Maps-order
		*/
		else if( $('body').hasClass('section-maps-order') ){
			// Tri automatique
			$('.autoSortMode li').click(function(){
				$('#sortableMapList').addClass('loading');
				$(this).children('input').prop('checked', true);
				$('.autoSortMode li').removeClass('selected').find('span.ui-icon').removeClass('active');
				$(this).addClass('ui-state-default selected').find('.icon .ui-icon-arrowthick-1-n').addClass('active');
				
				// Tri
				setMapsOrderSort($(this).children('input').val(), 'asc');
			});
			$('.autoSortMode li span.ui-icon').click(function(){
				$('#sortableMapList').addClass('loading');
				$('.autoSortMode li').removeClass('selected').find('span.ui-icon').removeClass('active');
				$(this).parents('li').addClass('selected').children('input').prop('checked', true);
				$(this).addClass('active');
				
				if( $(this).hasClass('ui-icon-arrowthick-1-n') ){
					var order = 'asc';
				}
				else{
					var order = 'desc';
				}
				
				// Tri
				setMapsOrderSort($(this).parent('.icon').parent('li').children('input').val(), order);
				
				return false;
			});
			
			// Tri manuel
			$('#sortableMapList').sortable({
				placeholder: 'ui-state-highlight',
				revert: true,
				zIndex: 9999
			});
			$('#reset').click(function(){
				location.href = $('.section-maps-order .cadre.order form').attr('action');
			});
			$('#save').click(function(){
				var listStr = '';
				var list = $('#sortableMapList li .order-map-name');
				if( list.length > 0 ){
					$.each(list, function(i, n){
						listStr += n.title+',';
					});
					$('#list').val(listStr.substring(0, listStr.length-1));
				}
			});
		}
		/**
		* Guest-Ban
		*/
		else if( $('body').hasClass('section-guestban') ){
			// CleanList
			$('a.cleanList').click(function(){
				var out = false;
				var lines = $(this).parents('.title-detail').parent('div').find('tbody tr:not(.no-line)');
				
				if(lines.length > 1){
					out = true;
				}
				else{
					error( $('a.cleanList').data('empty'), true);
				}
				
				return out;
			});
			
			// Checkbox
			$('#checkAllBanlist').click(function(){
				$('#banlist').checkAll( $(this).prop('checked') );
				$('.cadre.left').updateNbSelectedLines();
			});
			$('#checkAllBlacklist').click(function(){
				$('#blacklist').checkAll( $(this).prop('checked') );
				$('.cadre.left').updateNbSelectedLines();
			});
			$('#checkAllGuestlist').click(function(){
				$('#guestlist').checkAll( $(this).prop('checked') );
				$('.cadre.left').updateNbSelectedLines();
			});
			$('#checkAllIgnorelist').click(function(){
				$('#ignorelist').checkAll( $(this).prop('checked') );
				$('.cadre.left').updateNbSelectedLines();
			});
			$('#playlists #checkAllPlaylists').click(function(){
				$('#playlists').checkAll( $(this).prop('checked') );
				$('#playlists').updateNbSelectedLines();
			});
			
			// Clic sur les lignes
			$('#banlist, #blacklist, #guestlist, #ignorelist').on('click', 'tr', function(){
				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
					// Si la ligne est déjà sélectionnée, on l'enlève
					if( $(this).hasClass('selected') ){
						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
					}
					// Sinon, on l'ajoute
					else{
						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
					}
					
					// Mise à jour du nb de lignes sélectionnées
					$('.cadre.left').updateNbSelectedLines();
					$('.cadre.left').updateCheckAll( $(this).parent('tbody').parent('table').parent('div').find('input[type=checkbox]') );
				}
			});
			$('#playlists').on('click', 'tr', function(){
				if( !$(this).hasClass('no-line') && !$(this).hasClass('table-separation') ){
					// Si la ligne est déjà sélectionnée, on l'enlève
					if( $(this).hasClass('selected') ){
						$(this).removeClass('selected').find('td.checkbox input').prop('checked', false);
					}
					// Sinon, on l'ajoute
					else{
						$(this).addClass('selected').find('td.checkbox input').prop('checked', true);
					}
					
					// Mise à jour du nb de lignes sélectionnées
					$('#playlists').updateNbSelectedLines();
					$('#playlists').updateCheckAll( $('#playlists #checkAllPlaylists') );
				}
			});
			
			// Ajouter
			$('#addPlayerList').change(function(){
				if( $(this).val() == 'more' ){
					$(this).hide().attr('hidden', true);
					$('#addPlayerLogin').fadeIn('fast').removeAttr('hidden');
				}
			});
			$('#addPlayerLogin').click(function(){
				if( $(this).val() == $(this).data('default-value') ){
					$(this).val('');
				}
			});
			$('#addPlayerLogin').blur(function(){
				if( $(this).val() == '' ){
					$(this).val( $(this).data('default-value') );
				}
			});
			
			// Créer une playlist
			$('#clickNewPlaylist').click(function(event){
				event.preventDefault();
				var selector = $('#form-new-playlist');
				if( selector.attr('hidden') ){
					selector.animate({
						height: '25px',
						marginTop: '6px',
						marginBottom: '6px'
					}, 'fast').removeAttr('hidden');
					$(this).text( $(this).data('cancel') );
				}
				else{
					selector.animate({
						height: '0',
						marginTop: '0',
						marginBottom: '0'
					}, 'fast', function(){
						$(this).attr('hidden', true);
						$('#clickNewPlaylist').text( $('#clickNewPlaylist').data('newplaylist') );
					});
				}
			});
			$('#createPlaylistName').click(function(){
				if( $(this).val() == $(this).data('playlistname') ){
					$(this).val('');
				}
			});
			$('#createPlaylistName').blur(function(){
				var val = $(this).val();
				if( val == '' ){
					$(this).val( $(this).data('playlistname') );
				}
				else{
					var extTXT = val.indexOf('.playlist.txt');
					if(extTXT === -1){
						$(this).val(val+'.playlist.txt');
					}
				}
			});
		}
	}
});
/**
* Fonctions générales
*/
function getResourcesPath(){
	return $.trim( $('#path_resources').text() );
}
function getPath(){
	return $.trim( $('.path').text() );
}
function getMode(){
	return $.trim( $('#detailMode').data('statusmode') );
}
function getCurrentSort(){
	return $('#currentSort').val();
}
function setCurrentSort(sort){
	return $('#currentSort').val(sort);
}
function scrollTop(){
	$('html, body').animate({  
		scrollTop: 0
	}, 'slow');
}
function scrollBottom(){
	$('html, body').animate({  
		scrollTop: $(document).height() - $(window).height()
	}, 'slow');
}
function getUrlParams(key){
	var params = window.location.search.substring(1);
	if(!key){
		return params;
	}
	else{
		var index = params.indexOf(key);
		if(index !== -1){
			return params.substring(index).split('&')[0].substring(2);
		}
	}
}


/**
* Affiche la valeur seconde -> minute
*
* @param int sec -> La valeur en seconde
*/
function secToMin(sec){
	if(sec == '' || sec == undefined || isNaN(sec) ){
		sec = 0;
	}
	return round( (parseInt(sec) / 60), 1);
}


/**
* Math.round avec précision
*
* @param int value     -> Valeur à arrondir
* @param int precision -> Nombre de caractère après la virgule
*/
function round(value, precision){
	power = Math.pow(10, precision);
	return (Math.ceil(value * power)) / power;
}


/**
* Affichage du texte d'erreur
*/
function error(text, hide){
	var selector = $('#error');
	selector.fadeIn('fast').html(text);
	if( selector.attr('hidden') ){
		selector.removeAttr('hidden');
	}
	
	if(hide){
		setTimeout(function(){
			selector.attr('hidden', true).fadeOut('fast');
		}, 4000);
	}
}


/**
* Affichage du texte d'erreur
*/
function info(text, hide){
	var selector = $('#info');
	selector.fadeIn('fast').html(text);
	if( selector.attr('hidden') ){
		selector.removeAttr('hidden');
	}
	
	if(hide){
		setTimeout(function(){
			selector.attr('hidden', true).fadeOut('fast');
		}, 4000);
	}
}


/**
* Administration rapide (restart, next, endround)
*
* @param string cmd -> Le nom de la méthode à utiliser
*/
function speedAdmin(cmd){
	$.post(getResourcesPath()+'ajax/speed_admin.php', {cmd: cmd}, function(response){
		if(response != 'true'){
			error('Error: '+response);
		}
		setTimeout(function(){
			var sort = getCurrentSort();
			if( $('body').hasClass('section-index') ){
				getCurrentServerInfo('', sort);
			}
			else if( $('body').hasClass('section-maps-list') ){
				getMapList('', sort);
			}
			$('.speed-admin a.locked').removeClass('locked');
		}, 2000);
	});
}


/**
* Récupère la liste des niveaux admin suivant le serveur sélectionné
*/
function getServerAdminLevel(){
	var serverName = $('#as_server').val();
	var adminLevelList = '';
	
	$.getJSON(getResourcesPath()+'ajax/get_server_adminlevel.php', {srv: serverName}, function(response){
		if(response.levels != null){
			$.each(response.levels, function(i, n){
				if(response.last != null && response.last == n){ var selected = ' selected="selected"'; }
				else{ var selected = ''; }
				adminLevelList += '<option value="'+n+'"'+selected+'>'+n+'</option>';
			});
			
			$('#as_adminlevel').html(adminLevelList);
		}
		else{
			$('#as_adminlevel').empty();
			error( $('#as_adminlevel').data('error') );
		}
	});
}


/**
* Récupère les informations du serveur actuel (map, serveur, stats, joueurs)
*/
function getCurrentServerInfo(mode, sort){
	var path_ressources = getResourcesPath();
	if(!mode){
		mode = getMode();
	}
	if(sort){
		setCurrentSort(sort);
	}
	var isTeamGameMode = $('#isTeamGameMode').val();
	
	$.getJSON(getResourcesPath()+'ajax/get_current_serverinfo.php', {mode: mode, sort: sort}, function(data){
		if(data != null){
			// Map
			if(data.map != null){
				$('#map_name').html(data.map.name);
				$('#map_author').html(data.map.author);
				$('#map_enviro').html(data.map.enviro+'<img src="'+path_ressources+'images/env/'+data.map.enviro.toLowerCase()+'.png" alt="" />');
				$('#map_uid').html(data.map.uid);
				if(data.srv.gameModeScriptName){
					var gameModeName = data.srv.gameModeScriptName+' <span class="scriptName">('+data.srv.gameModeName+')</span>';
				}else{
					var gameModeName = data.srv.gameModeName;
				}
				$('#map_gamemode').html(gameModeName).attr('class', '').addClass('value '+data.srv.gameModeName.toLowerCase() );
				if(data.map.thumb){
					$('#map_thumbnail').html('<img src="data:image/jpeg;base64,'+data.map.thumb+'" alt="'+$('#map_thumbnail').data('text-thumbnail')+'" />');
				}
				if(data.map.scores){
					$('#ScoreTeamBlue').val(data.map.scores.blue);
					$('#ScoreTeamRed').val(data.map.scores.red);
				}
			}
			
			// Server
			if(data.srv != null){
				$('#server_name').html(data.srv.name);
				$('#server_status').html(data.srv.status);
			}
			
			// Stats
			if(data.net != null){
				$('#network_uptime').html(data.net.uptime);
				$('#network_nbrconnection').html(data.net.nbrconnection);
				$('#network_meanconnectiontime').html(data.net.meanconnectiontime);
				$('#network_meannbrplayer').html(data.net.meannbrplayer);
				$('#network_recvnetrate').html(data.net.recvnetrate);
				$('#network_sendnetrate').html(data.net.sendnetrate);
				$('#network_totalreceivingsize').html(data.net.totalreceivingsize);
				$('#network_totalsendingsize').html(data.net.totalsendingsize);
			}
			
			// Players
			if(data.ply != null && !$('#playerlist').isChecked() ){
				var out = '';
				
				// Création du tableau
				out += '<tr class="table-separation"><td colspan="'; if(isTeamGameMode){ out += '6'; }else{ out += '5'; } out += '"></td></tr>';
				if( typeof(data.ply) == 'object' ){
					$.each(data.ply, function(i, player){
						out += '<tr class="'; if(i%2){ out += 'even'; }else{ out += 'odd'; } out += '">';
							if(isTeamGameMode && mode == 'detail'){
								out += '<td class="detailModeTd imgleft"><span class="team_'+player.TeamId+'" title="'+player.TeamName+'">&nbsp;</span>'+player.TeamName+'</td>';
							}
							out += '<td class="imgleft"><img src="'+path_ressources+'images/16/solo.png" alt="" />'+player.NickName+'</td>';
							if( !isTeamGameMode && mode == "detail" ){
								out += '<td class="imgleft"><img src="'+path_ressources+'images/16/leagueladder.png" alt="" />'+player.LadderRanking+'</td>';
							}
							out += '<td>'+player.Login+'</td>'
							+'<td>'+player.PlayerStatus+'</td>'
							+'<td class="checkbox"><input type="checkbox" name="player[]" value="'+player.Login+'" /></td>'
						+'</tr>';
					});
					
					if( $('#checkAll').attr('disabled') ){
						$('#checkAll').prop('disabled', false);
					}
				}
				else{
					if( !$('#checkAll').attr('disabled') ){
						$('#checkAll').prop('disabled', true);
					}
					out += '<tr class="no-line"><td class="center" colspan="'; if(isTeamGameMode){ out += '6'; }else{ out += '5'; } out += '">'+data.ply+'</td></tr>';
				}
				
				// HTML
				$('#playerlist table tbody').html(out);
				$('.cadre.right .options .nb-line').html(data.nbp);
				if( $('#playerlist').hasClass('loading') ){
					$('#playerlist').removeClass('loading');
				}
			}
		}
	});
}


/**
* Transforme une chaine de caractère de couleur en HTML
*
* @param string str
*/
(function($){
	$.fn.getColorHtml = function(str){
		var selector = $(this);
		
		$.getJSON(getResourcesPath()+'ajax/get_colorstr.php', {t: str}, function(data){
			if(data != null){
				selector.html(data.str);
			}
		});
	};
})(jQuery);


/**
* Récupère la configuration du gameMode sélectionné
*/
function getCurrentGameModeConfig(){
	var gameMode = $('#NextGameMode option:selected').text();
	var selector = $('#gameMode-'+gameMode.toLowerCase() );
	
	// Fermeture de tous les modes par défaut
	if( $('body').hasClass('section-maps-creatematchset') ){
		var section = '.section-maps-creatematchset';
	}else{
		var section = '.section-gameinfos';
	}
	$.each( $(section+' .content.gameinfos fieldset'), function(i, n){
		if( !$(this).hasClass('gameinfos_general') && !$(this).hasClass('gameinfos_teaminfos') ){
			if( $(this).attr('hidden') ){
				$(this).hide();
			}
			else{
				$(this).hide();
				$(this).attr('hidden', true);
			}
		}
	});
	
	// Affichage du mode de jeu sélectionné
	if( selector.attr('hidden') ){
		selector.slideDown('fast').removeAttr('hidden');
	}
}


/**
* Récupère les paramètres du script courant
*/
function getScriptSettings(){
	$.post(getResourcesPath()+'ajax/script_settings.php', {method: 'get'}, function(data){
		if(data != null){
			// Script info
			$('#dialogScriptInfoName').html(data.Name+' ('+data.Version+')');
			$('#dialogScriptInfoCompatibleMapTypes').html(data.CompatibleMapTypes);
			if(data.Description != ''){
				$('.dialogScriptInfoDesc').attr('hidden', false);
				$('#dialogScriptInfoDesc').html(data.Description);
			}
			
			// Paramètres
			paramsList = '';
			if( typeof(data.ParamDescs) == 'object' ){
				$.each(data.ParamDescs, function(i, param){
					var paramValueField = '';
					if(param.Type == 'boolean'){
						var isChecked = '';
						if(param.Default == 'True'){
							isChecked = ' checked="checked"';
						}
						paramValueField = '<input class="text" data-type="'+param.Type+'" type="checkbox" name="'+param.Name+'" id="'+param.Name+'" value="'+param.Default+'"'+isChecked+' />';
					}
					else{
						paramValueField = '<input class="text" data-type="'+param.Type+'" type="text" name="'+param.Name+'" id="'+param.Name+'" value="'+param.Default+'" />';
					}
					
					paramsList += '<tr>'
						+ '<td class="first">'+param.Name+'</td>'
						+ '<td class="middle">'+paramValueField+'</td>'
						+ '<td class="last">'+param.Desc+'</td>'
					+ '</tr>';
				});
				
				$('#dialogScriptSettings table tbody').html(paramsList);
			}
			
			// Dialog
			$('#getScriptSettingsDialog').dialog({
				title: $('#getScriptSettingsDialog').data('title'),
				modal: true,
				minWidth: 800,
				minHeight: 400,
				buttons: [
					{
						text: $('#getScriptSettingsDialog').data('cancel'),
						click: function(){
							$(this).dialog('close');
						}
					},
					{
						text: $('#getScriptSettingsDialog').data('save'),
						click: function(){
							setScriptSettings();
						}
					}
				]
			});
		}
	}, 'json');
}


/**
* Enregistre les paramètres du script courant
*/
function setScriptSettings(){
	var params = [];
	
	$('#dialogScriptSettings table tbody tr').each(function(){
		var key = $(this).find('.first').text();
		var type = $(this).find('.middle input').data('type');
		
		if(type == 'boolean'){
			if( $(this).find('.middle input').attr('checked') == 'checked' ){
				var val = 1;
			}
			else{
				var val = 0;
			}
		}
		else{
			var val = $(this).find('.middle input').val();
		}
		
		params.push({
			name: key,
			value: val,
			type: type,
		});
	});
	
	$.post(getResourcesPath()+'ajax/script_settings.php', {method: 'set', params: params}, function(response){
		if(response != 'true'){
			error(response);
			scrollTop();
		}
		else{
			$('#getScriptSettingsDialog').dialog('close');
			info($('#getScriptSettings').data('infotext'), true);
		}
	});
}


/**
* Récupère les lignes du chat du serveur
*
* @param bool hideServerLines -> Afficher ou non les lignes provenant d'un gestionnaire de serveur
* @return string html
*/
function getChatServerLines(hideServerLines){
	$.getJSON(getResourcesPath()+'ajax/get_chatserverlines.php', {s: hideServerLines}, function(data){
		$('#chat').html(data);
	});
}


/**
* Ajoute une ligne (pseudo + message) dans le chat du serveur
*/
function addChatServerLine(){
	var nickname = $('#chatNickname').val();
	if( nickname == $('#chatNickname').data('default-value') ){
		nickname = '';
	}
	var color = $('#chatColor').val();
	var message = $('#chatMessage').val();
	var destination = $('#chatDestination').val();
	var hideServerLines = $('#checkServerLines').data('val');
	
	$.post(getResourcesPath()+'ajax/add_chatserverline.php', {nic: nickname, clr: color, msg: message, dst: destination}, function(response){
		if(response != null){
			getChatServerLines(hideServerLines);
			$('#chatMessage').val('');
		}
	});
}


/**
* Initialisation de l'uploader Ajax
*/
function initializeUploader(){
	var formSelector = $('#formUpload');
	var statusFiles = [];
	var uploader = new qq.FileUploader({
		element: formSelector[0],
		action: getResourcesPath()+'ajax/upload.php',
		maxConnections: 2,
		params: getUploaderUserParams(),
		template:
		'<div class="qq-uploader">'
			+ '<div class="qq-upload-drop-area"><span>'+ formSelector.data('dropfiles') +'</span></div>'
			+ '<div class="qq-upload-button">'+ formSelector.data('uploadfile') +'</div>'
			+ '<ul class="qq-upload-list"></ul>'
		+ '</div>',
		fileTemplate:
		'<li>'
			+ '<span class="qq-upload-file"></span>'
			+ '<span class="qq-upload-spinner"><span class="qq-progress-bar"></span></span>'
			+ '<span class="qq-upload-size"></span>'
			+ '<a class="qq-upload-cancel" href="./">'+ formSelector.data('cancel') +'</a>'
			+ '<span class="qq-upload-failed-text">'+ formSelector.data('failed') +'</span>'
		+ '</li>',
		onProgress: function(id, fileName, loaded, total){
			window.onbeforeunload = function(){
				return formSelector.data('uploadnotfinished');
			}
			$.each( $('.qq-upload-list li'), function(key, value){
				var uploadSizeSelector = $(this).find('.qq-upload-size');
				var text = uploadSizeSelector.text();
				var newtext = text.replace(/from/gi, formSelector.data('from') );
				newtext = newtext.replace(/kb/gi, formSelector.data('kb') );
				newtext = newtext.replace(/mb/gi, formSelector.data('mb') );
				var lastpos = text.indexOf('%');
				var pourcent = text.substring(0, lastpos);
				
				uploadSizeSelector.text(newtext);
				$(this).find('.qq-progress-bar').css('width', pourcent+'px');
			});
		},
		onComplete: function(id, fileName, responseJSON){
			window.onbeforeunload = function(){}
			
			if(uploader._options.params.gtlm){
				if(responseJSON.success){
					var status = true;
				}
				else{
					var status = false;
				}
				statusFiles.push(status);
				
				if(uploader.getInProgress() == 0){
					var allowRedirect = true;
					for(var i = 0; i < statusFiles.length; i++){
						if(statusFiles[i] === false){
							allowRedirect = false;
							break;
						}
					}
					
					if(allowRedirect){
						location.href = '?p='+formSelector.data('mapspagename');
					}
				}
			}
		},
		onCancel: function(id, fileName){
			window.onbeforeunload = function(){}
		},
		messages: {
			typeError: formSelector.data('type-error'),
			sizeError: formSelector.data('size-error'),
			minSizeError: formSelector.data('minsize-error'),
			emptyError: formSelector.data('empty-error'),
			onLeave: formSelector.data('onleave')
		},
		showMessage: function(message){
			error(message);
		}
	});
	
	return uploader;
}


/**
* Récupère les paramètres utilisateur de l'uploader
*/
function getUploaderUserParams(){
	return {
		path: getPath(),
		type: $('.transferMode li.selected input').val(),
		mset: ( $('#SaveCurrentMatchSettings').attr('checked') ) ? true : false,
		gtlm: ( $('#GotoListMaps').attr('checked') ) ? true : false
	};
}


/**
* Récupère la liste des maps du serveur
*/
function getMapList(mode, sort){
	var path_ressources = getResourcesPath();
	if(!mode){
		mode = getMode();
	}
	if(sort){
		setCurrentSort(sort);
	}
	
	$.getJSON(getResourcesPath()+'ajax/get_maplist.php', {mode: mode, sort: sort}, function(data){
		if(data != null){
			if(data.lst != null && !$('#maplist').isChecked() ){
				var out = '';
				
				// Création du tableau
				out += '<tr class="table-separation"><td colspan="6"></td></tr>';
				if( typeof(data.lst) == 'object' ){
					$.each(data.lst, function(i, map){
						out += '<tr'; if(data.cid == i){ out += ' id="currentMap"'; } out += ' class="'; if(i%2){ out += 'even'; }else{ out += 'odd'; } if(data.cid == i){ out += ' current'; } out += '">'
							+'<td class="imgleft"><img src="'+path_ressources+'images/16/map.png" alt="" />'
								+'<span title="'+map.FileName+'">'+map.Name+'</span>'
								if(mode == 'detail'){
									out += '<span class="detailModeTd">'+map.UId+'</span>';
								}
							out += '</td>'
							+'<td class="imgcenter"><img src="'+path_ressources+'images/env/'+map.Environment.toLowerCase()+'.png" alt="" />'+map.Environment+'</td>'
							+'<td>'+map.Author+'</td>';
							if(mode == 'detail'){
								out += '<td>'+map.GoldTime+'</td>'
								+'<td>'+map.CopperPrice+'</td>';
							}
							out += '<td class="checkbox">'; if(data.cid != i){ out += '<input type="checkbox" name="map[]" value="'+map.FileName+'" />'; } out += '</td>'
						+'</tr>';
					});
					
					if( $('#checkAll').attr('disabled') ){
						$('#checkAll').prop('disabled', false);
					}
				}
				else{
					if( !$('#checkAll').attr('disabled') ){
						$('#checkAll').prop('disabled', true);
					}
					out += '<tr class="no-line"><td class="center" colspan="6">'+data.lst+'</td></tr>';
				}
				
				// HTML
				$('#maplist table tbody').html(out);
				$('.cadre.right .options .nb-line').html(data.nbm.count+' '+data.nbm.title);
				if( $('#maplist').hasClass('loading') ){
					$('#maplist').removeClass('loading');
				}
			}
		}
	});
}


/**
* Récupère la liste des fichiers map pour les renommer
*/
(function($){
	$.fn.getMapRenameList = function(){
		var out = '';
		var formSelector = $('#form-rename-map');
		var list = $(this);
		if( list.length > 0 ){
			out += '<ul>';
			list.each(function(){
				var mapName = $(this).val().replace(getUrlParams('d'), '');
				if(mapName.length > 36){
					var title = ' title="'+mapName+'"';
				}else{
					var title = '';
				}
				out += '<li>'
					+ '<span class="rename-map-name"'+title+'>'+mapName+'</span>'
					+ '<span class="rename-map-arrow">&nbsp;</span>'
					+ '<input class="text width3" type="text" id="renameMapList" name="renameMapList[]" value="'+mapName+'" />'
				+ '</li>';
			});
			out += '</ul>';
		}
		
		// HTML
		out += '<div class="form-input-submit">'
			+ '<input class="button dark" type="button" id="renameMapCancel" name="renameMapCancel" value="'+formSelector.data('cancel')+'" />'+"\n"
			+ '<input class="button dark" type="submit" id="renameMapValid" name="renameAutoValid" value="'+formSelector.data('autorename')+'" />'
			+ '<input class="button dark" type="submit" id="renameMapValid" name="renameMapValid" value="'+formSelector.data('rename')+'" />'
		+ '</div>';
		formSelector.html(out);
	};
})(jQuery);


/**
* Récupère l'arboréscence des dossiers pour déplacer
*/
function getMoveFolderList(nbFiles){
	$.getJSON(getResourcesPath()+'ajax/get_directory_list.php', function(data){
		if(data != null){
			var out = '';
			var formSelector = $('#form-move-map');
			if( nbFiles > 1 ){
				var nbName = nbFiles + ' maps';
			}else{
				var nbName = '1 map';
			}
			out += '<label for="moveDirectoryList">'+formSelector.data('move')+' '+nbName+' '+formSelector.data('inthefolder')+'</label>'
			+ '<select name="moveDirectoryList" id="moveDirectoryList">'
				+ '<option value=".">'+formSelector.data('root')+'</option>';
				$.each(data, function(i, n){
					out += '<option value="'+n.path+'">'+n.level+n.name+'</option>';
				});
			out += '</select>'
			+ '<div class="form-input-submit">'
				+ '<input class="button dark" type="button" id="moveMapCancel" name="moveMapCancel" value="'+formSelector.data('cancel')+'" />'+"\n"
				+ '<input class="button dark" type="submit" id="moveMapValid" name="moveMapValid" value="'+formSelector.data('move')+'" />'
			+ '</div>';
			
			// HTML
			formSelector.html(out);
		}
	});
}

/**
* Fonctions d'affichage des formulaires
*/
function slideDownRenameForm(){
	$('#form-rename-map').slideDown('fast');
	$('#renameMap').addClass('active');
	$('.options').addClass('form').find('.selected-files-label').addClass('optHover');
	$('#maplist table tbody tr.selected td.checkbox input').getMapRenameList();
}
function slideUpRenameForm(){
	$('#form-rename-map').slideUp('fast');
	$('#renameMap').removeClass('active');
	$('.options').removeClass('form').find('.selected-files-label').removeClass('optHover');
}
function slideDownMoveForm(){
	$('#form-move-map').slideDown('fast');
	$('#moveMap').addClass('active');
	$('.options').addClass('form').find('.selected-files-label').addClass('optHover');
	if( $('#form-move-map').text() == '' ){
		getMoveFolderList( $('#maplist table tbody tr.selected td.checkbox input').length );
	}
}
function slideUpMoveForm(){
	$('#form-move-map').slideUp('fast');
	$('#moveMap').removeClass('active');
	$('.options').removeClass('form').find('.selected-files-label').removeClass('optHover');
}
function slideDownNewFolderForm(){
	$('#form-new-folder').animate({
		height: '25px',
		marginTop: '6px',
		marginBottom: '6px'
	}, 'fast').removeAttr('hidden');
	$('#newfolder').text( $('#newfolder').data('cancel') );
	$('#newFolderName').select();
}
function slideUpNewFolderForm(){
	$('#form-new-folder').animate({
		height: '0',
		marginTop: '0',
		marginBottom: '0'
	}, 'fast', function(){
		$('#form-new-folder').attr('hidden', true);
		$('#newfolder').text( $('#newfolder').data('new') );
	});
}


/**
* Fait un tri sur la liste des maps pour la page "maps-order"
*/
function setMapsOrderSort(sort, order){
	var resourcesPath = getResourcesPath();
	var list = $('#jsonlist').val();
	
	$.post(getResourcesPath()+'ajax/mapsorder_sort.php', {srt: sort, ord: order, lst: list}, function(data){
		if(data != null){
			var out = '';
			if( typeof(data.lst) == 'object' ){
				$.each(data.lst, function(id, map){
					out += '<li class="ui-state-default">'
						+ '<div class="ui-icon ui-icon-arrowthick-2-n-s"></div>'
						+ '<div class="order-map-name" title="'+map.FileName+'">'+map.Name+'</div>'
						+ '<div class="order-map-env"><img src="'+resourcesPath+'images/env/'+map.Environment.toLowerCase()+'.png" alt="" />'+map.Environment+'</div>'
						+ '<div class="order-map-author"><img src="'+resourcesPath+'images/16/mapauthor.png" alt="" />'+map.Author+'</div>'
					+ '</li>';
				});
			}
			
			// HTML
			$('#sortableMapList').html(out);
			if( $('#sortableMapList').hasClass('loading') ){
				$('#sortableMapList').removeClass('loading');
			}
		}
	}, 'json');
}


/**
* Met en place l'affichage en mode détail
*/
(function($){
	$.fn.setDetailMode = function(){
		var sort = getCurrentSort();
		var type = $(this).attr('id');
		
		if( $('#detailMode').text() == $('#detailMode').data('textdetail') ){
			if(type == 'maplist'){
				getMapList('detail', sort);
			}
			else if(type == 'playerlist'){
				getCurrentServerInfo('detail', sort);
			}
			$('#detailMode').text( $('#detailMode').data('textsimple') ).data('statusmode', 'detail');
			$(this).addClass('loading').find('table th.detailModeTh').attr('hidden', false);
		}
		else{
			if(type == 'maplist'){
				getMapList('simple', sort);
			}
			else if(type == 'playerlist'){
				getCurrentServerInfo('simple', sort);
			}
			$('#detailMode').text( $('#detailMode').data('textdetail') ).data('statusmode', 'simple');
			$(this).addClass('loading').find('table th.detailModeTh').attr('hidden', true);
		}
	};
})(jQuery);


/**
* Coche toutes les checkbox d'un selecteur
*
* @param bool isChecked -> Si la checkbox "checkAll" est cochée
*/
(function($){
	$.fn.checkAll = function(isChecked){
		var lineSelector = $(this).find('tbody tr[class!="table-separation"]');
		var checkboxSelector = $(this).find('tbody td.checkbox input[type="checkbox"]');
		if(isChecked){
			checkboxSelector.prop('checked', true);
			lineSelector.addClass('selected');
		}
		else{
			checkboxSelector.prop('checked', false);
			lineSelector.removeClass('selected');
		}
	};
})(jQuery);

/**
* Met à jour la checkbox "checkAll" si toutes les lignes sont cochées ou non
*
* @param string checkAllSelector -> Selecteur de l'input "checkAll"
*/
(function($){
	$.fn.updateCheckAll = function(checkAllSelector){
		var nbSelected = $(this).find('tbody tr.selected').length;
		var nbAll = $(this).find('tbody tr[class!="table-separation"]').length;
		if( $('body').hasClass('section-maps-list') ){
			nbAll--;
		}
		
		if(nbSelected == nbAll){
			checkAllSelector.prop('checked', true);
		}
		else if(nbSelected == 0){
			if( checkAllSelector.prop('checked') ){
				checkAllSelector.prop('checked', false);
			}
		}
	};
})(jQuery);


/**
* Met à jour le nombre de fichiers sélectionnés
*/
(function($){
	$.fn.updateNbSelectedLines = function(){
		var nb = $(this).find('tbody tr.selected').length;
		
		if(nb > 0){
			$(this).find('.selected-files-label').removeClass('locked');
		}
		else{
			$(this).find('.selected-files-label').addClass('locked');
		}
		$(this).find('.selected-files-count').text('('+nb+')');
	};
})(jQuery);


/**
* Détermine si il y a au moins une ligne sélectionnée
*/
(function($){
	$.fn.isChecked = function(){
		var nb = $(this).find('tbody tr.selected').length;
		
		if(nb > 0){
			return true;
		}
		else{
			return false;
		}
	};
})(jQuery);



/**
* MATCHSETTINGS
*/

/**
* Vérifie si le nom du MatchSettings n'existe pas déjà
*
* @param string filename -> Le nom du fichier
*/
function matchset_getFileExists(filename){
	$.getJSON(getResourcesPath()+'ajax/get_matchset_fileexists.php', {path: getPath(), name: filename}, function(response){
		if(response){
			$('#matchSettingNameExists').attr('hidden', false).hide().fadeIn('fast');
		}
		else{
			$('#matchSettingNameExists').attr('hidden', true).fadeOut('fast');
		}
	});
}

/**
* Récupère la liste des maps en local pour la création d'un matchSettings
*/
function matchset_mapImport(){
	var path = $('#mapsDirectoryList').val();
	var directory = getUrlParams('d');
	
	$.getJSON(getResourcesPath()+'ajax/get_matchset_mapimport.php', {path: path, d: directory}, function(data){
		if(data != null){
			matchset_setNbMapSelection(data.nbm.count);
			$('.creatematchset .maps').removeClass('loading');
		}
	});
}
function matchset_mapImportSelection(){
	var path = $('#mapsDirectoryList').val();
	var directory = getUrlParams('d');
	var resourcesPath = getResourcesPath();
	
	$.getJSON(resourcesPath+'ajax/get_matchset_mapimport.php', {path: path, d: directory, op: 'getSelection'}, function(data){
		if(data != null){
			var out = '';
			
			// Création du tableau
			out += '<tr class="table-separation"><td colspan="4"></td></tr>';
			if( typeof(data.lst) == 'object' ){
				$.each(data.lst, function(i, map){
					out += '<tr class="'; if(i%2){ out += 'even'; }else{ out += 'odd'; } out += '">'
						+'<td class="imgleft"><img src="'+resourcesPath+'images/16/map.png" alt="" />'
							+'<span title="'+map.FileName+'">'+map.Name+'</span>'
						out += '</td>'
						+'<td class="imgcenter"><img src="'+resourcesPath+'images/env/'+map.Environment.toLowerCase()+'.png" alt="" />'+map.Environment+'</td>';
						if(map.Type){
							out += '<td><span title="'+map.Type.FullName+'">'+map.Type.Name+'</span></td>';
						}
						else{
							out += '<td>-</td>';
						}
						out += '<td>'+map.Author+'</td>';
						out += '<td class="checkbox"><input type="checkbox" name="map[]" value="'+map.FileName+'" /></td>'
					+'</tr>';
				});
				
				if( $('#checkAllMapImport').attr('disabled') ){
					$('#checkAllMapImport').prop('disabled', false);
				}
			}
			else{
				if( !$('#checkAllMapImport').attr('disabled') ){
					$('#checkAllMapImport').prop('disabled', true);
				}
				out += '<tr class="no-line"><td class="center" colspan="4">'+data.lst+'</td></tr>';
			}
			
			// HTML
			$('#mapImportSelectionDialog').removeAttr('hidden').find('table tbody').html(out);
			$('.creatematchset .maps').removeClass('loading');
			$('#mapImportSelectionDialog').dialog({
				title: $('#mapImportSelectionDialog').data('title'),
				modal: true,
				minWidth: 800,
				minHeight: 400,
				buttons: [{
					text: $('#mapImportSelectionDialog').data('select'),
					click: function(){
						var listSelection = $('#mapImportSelectionDialog tbody tr.selected');
						var listSelectionId = [];
						if( listSelection.length > 0 ){
							$.each(listSelection, function(i, n){
								if( n.className.indexOf('selected') !== -1 ){
									listSelectionId.push( parseInt(n.sectionRowIndex - 1) );
								}
							});
						}
						$.getJSON(resourcesPath+'ajax/get_matchset_mapimport.php', {path: path, op: 'setSelection', select: listSelectionId}, function(data){
							if(data != null){
								matchset_setNbMapSelection(data.nbm.count);
								$('#mapImportSelectionDialog').dialog('close');
							}
						});
					}
				}]
			});
		}
	});
}


/**
* Met à jour le nombre de maps sélectionnées
*
* @param int nb
*/
function matchset_setNbMapSelection(nb){
	$('#nbMapSelected').text(nb);
}
/**
* Récupère et affiche la sélection du MatchSettings
*/
function matchset_mapSelection(removeId){
	var path_ressources = getResourcesPath();
	if(removeId){
		var params = {remove: parseInt(removeId - 1)};
	}else{
		var params = '';
	}
	$.getJSON(getResourcesPath()+'ajax/get_matchset_mapselection.php', params, function(data){
		if(data != null){
			var out = '';
			
			// Création du tableau
			out += '<tr class="table-separation"><td colspan="4"></td></tr>';
			if( typeof(data.lst) == 'object' ){
				$.each(data.lst, function(i, map){
					out += '<tr class="'; if(i%2){ out += 'even'; }else{ out += 'odd'; } out += '">'
						+ '<td class="imgleft"><img src="'+path_ressources+'images/16/map.png" alt="" />'
							+ '<span title="'+map.FileName+'">'+map.Name+'</span>'
						+ '</td>'
						+ '<td class="imgcenter"><img src="'+path_ressources+'images/env/'+map.Environment.toLowerCase()+'.png" alt="" />'+map.Environment+'</td>';
						if(map.Type){
							out += '<td><span title="'+map.Type.FullName+'">'+map.Type.Name+'</span></td>';
						}
						else{
							out += '<td>-</td>';
						}
						out += '<td>'+map.Author+'</td>'
						+ '<td class="checkbox imgcenter"><a href="." title="'+$("#mapSelectionDialog").data("remove")+'"><img src="'+path_ressources+'images/16/delete.png" alt="" /></a></td>'
					+ '</tr>';
				});
			}
			else{
				out += '<tr class="no-line"><td class="center" colspan="4">'+data.lst+'</td></tr>';
			}
			
			// HTML
			matchset_setNbMapSelection(data.nbm.count);
			$('#mapSelectionDialog').removeAttr('hidden').find('table tbody').html(out);
			$('.creatematchset .maps').removeClass('loading');
			$('#mapSelectionDialog').dialog({
				title: $('#mapSelectionDialog').data('title'),
				modal: true,
				minWidth: 800,
				minHeight: 400,
				buttons: [{
					text: $('#mapSelectionDialog').data('close'),
					click: function(){
						$(this).dialog('close');
					}
				}]
			});
		}
	});
}


/* Folders */
function getRenameFolderForm(){
	$('#renameFolderForm').removeAttr('hidden');
	$('#renameFolderForm').dialog({
		title: $('#renameFolderForm').data('title'),
		modal: true,
		resizable: false,
		minWidth: 406,
		buttons: [
			{
				text: $('#renameFolderForm').data('cancel'),
				click: function(){
					$(this).dialog('close');
				}
			},
			{
				text: $('#renameFolderForm').data('rename'),
				click: function(){
					$('#optionFolderHiddenFieldValue').val( $('#renameFolderNewName').val() );
					$('#optionFolderForm').submit();
				}
			},
			
		]
	});
}
function getMoveFolderForm(){
	$('#moveFolderForm').removeAttr('hidden');
	$.getJSON(getResourcesPath()+'ajax/get_directory_list.php', function(data){
		if(data != null){
			var out = '';
			var formSelector = $('#moveFolderForm');
			out += '<label for="moveFormDirectoryList">'+formSelector.data('movethefolder')+'</label>'
			+ '<select name="moveFormDirectoryList" id="moveFormDirectoryList">'
				+ '<option value=".">'+formSelector.data('root')+'</option>';
				$.each(data, function(i, n){
					out += '<option value="'+n.path+'">'+n.level+n.name+'</option>';
				});
			out += '</select>';
			
			// HTML
			formSelector.html(out);
		}
	});
	$('#moveFolderForm').dialog({
		title: $('#moveFolderForm').data('title'),
		modal: true,
		resizable: false,
		minWidth: 406,
		buttons: [
			{
				text: $('#moveFolderForm').data('cancel'),
				click: function(){
					$(this).dialog('close');
				}
			},
			{
				text: $('#moveFolderForm').data('move'),
				click: function(){
					$('#optionFolderHiddenFieldValue').val( $('#moveFormDirectoryList').val() );
					$('#optionFolderForm').submit();
				}
			},
			
		]
	});
}
/**
 *
 * Color picker
 * Author: Stefan Petre www.eyecon.ro
 *
 * Dual licensed under the MIT and GPL licenses
 *
 */
(function(a){var b=function(){var b={},c,d=65,e,f='<div class="colorpicker"><div class="colorpicker_color"><div><div></div></div></div><div class="colorpicker_hue"><div></div></div><div class="colorpicker_new_color"></div><div class="colorpicker_current_color"></div><div class="colorpicker_hex"><input type="text" maxlength="6" size="6" /></div><div class="colorpicker_rgb_r colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_rgb_g colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_rgb_b colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_h colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_s colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_b colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_submit"></div></div>',g={eventName:"click",onShow:function(){},onBeforeShow:function(){},onHide:function(){},onChange:function(){},onSubmit:function(){},color:"ff0000",livePreview:true,flat:false},h=function(b,c){var d=P(b);a(c).data("colorpicker").fields.eq(1).val(d.r).end().eq(2).val(d.g).end().eq(3).val(d.b).end()},i=function(b,c){a(c).data("colorpicker").fields.eq(4).val(b.h).end().eq(5).val(b.s).end().eq(6).val(b.b).end()},j=function(b,c){a(c).data("colorpicker").fields.eq(0).val(R(b)).end()},k=function(b,c){a(c).data("colorpicker").selector.css("backgroundColor","#"+R({h:b.h,s:100,b:100}));a(c).data("colorpicker").selectorIndic.css({left:parseInt(150*b.s/100,10),top:parseInt(150*(100-b.b)/100,10)})},l=function(b,c){a(c).data("colorpicker").hue.css("top",parseInt(150-150*b.h/360,10))},m=function(b,c){a(c).data("colorpicker").currentColor.css("backgroundColor","#"+R(b))},n=function(b,c){a(c).data("colorpicker").newColor.css("backgroundColor","#"+R(b))},o=function(b){var c=b.charCode||b.keyCode||-1;if(c>d&&c<=90||c==32){return false}var e=a(this).parent().parent();if(e.data("colorpicker").livePreview===true){p.apply(this)}},p=function(b){var c=a(this).parent().parent(),d;if(this.parentNode.className.indexOf("_hex")>0){c.data("colorpicker").color=d=N(L(this.value))}else if(this.parentNode.className.indexOf("_hsb")>0){c.data("colorpicker").color=d=J({h:parseInt(c.data("colorpicker").fields.eq(4).val(),10),s:parseInt(c.data("colorpicker").fields.eq(5).val(),10),b:parseInt(c.data("colorpicker").fields.eq(6).val(),10)})}else{c.data("colorpicker").color=d=O(K({r:parseInt(c.data("colorpicker").fields.eq(1).val(),10),g:parseInt(c.data("colorpicker").fields.eq(2).val(),10),b:parseInt(c.data("colorpicker").fields.eq(3).val(),10)}))}if(b){h(d,c.get(0));j(d,c.get(0));i(d,c.get(0))}k(d,c.get(0));l(d,c.get(0));n(d,c.get(0));c.data("colorpicker").onChange.apply(c,[d,R(d),P(d)])},q=function(b){var c=a(this).parent().parent();c.data("colorpicker").fields.parent().removeClass("colorpicker_focus")},r=function(){d=this.parentNode.className.indexOf("_hex")>0?70:65;a(this).parent().parent().data("colorpicker").fields.parent().removeClass("colorpicker_focus");a(this).parent().addClass("colorpicker_focus")},s=function(b){var c=a(this).parent().find("input").focus();var d={el:a(this).parent().addClass("colorpicker_slider"),max:this.parentNode.className.indexOf("_hsb_h")>0?360:this.parentNode.className.indexOf("_hsb")>0?100:255,y:b.pageY,field:c,val:parseInt(c.val(),10),preview:a(this).parent().parent().data("colorpicker").livePreview};a(document).bind("mouseup",d,u);a(document).bind("mousemove",d,t)},t=function(a){a.data.field.val(Math.max(0,Math.min(a.data.max,parseInt(a.data.val+a.pageY-a.data.y,10))));if(a.data.preview){p.apply(a.data.field.get(0),[true])}return false},u=function(b){p.apply(b.data.field.get(0),[true]);b.data.el.removeClass("colorpicker_slider").find("input").focus();a(document).unbind("mouseup",u);a(document).unbind("mousemove",t);return false},v=function(b){b.preventDefault();var c={cal:a(this).parent(),y:a(this).offset().top};c.preview=c.cal.data("colorpicker").livePreview;a(document).bind("mouseup touchend",c,x);a(document).bind("mousemove touchmove",c,w)},w=function(a){var b=a;if(typeof event!=="undefined"&&event.touches){b=event.touches[0]}p.apply(a.data.cal.data("colorpicker").fields.eq(4).val(parseInt(360*(150-Math.max(0,Math.min(150,b.pageY-a.data.y)))/150,10)).get(0),[a.data.preview]);return false},x=function(b){h(b.data.cal.data("colorpicker").color,b.data.cal.get(0));j(b.data.cal.data("colorpicker").color,b.data.cal.get(0));a(document).unbind("mouseup touchend",x);a(document).unbind("mousemove touchmove",w);return false},y=function(b){b.preventDefault();var c={cal:a(this).parent(),pos:a(this).offset()};c.preview=c.cal.data("colorpicker").livePreview;a(document).bind("mouseup touchend",c,A);a(document).bind("mousemove touchmove",c,z)},z=function(a){var b=a;if(typeof event!=="undefined"&&event.touches){b=event.touches[0]}p.apply(a.data.cal.data("colorpicker").fields.eq(6).val(parseInt(100*(150-Math.max(0,Math.min(150,b.pageY-a.data.pos.top)))/150,10)).end().eq(5).val(parseInt(100*Math.max(0,Math.min(150,b.pageX-a.data.pos.left))/150,10)).get(0),[a.data.preview]);return false},A=function(b){h(b.data.cal.data("colorpicker").color,b.data.cal.get(0));j(b.data.cal.data("colorpicker").color,b.data.cal.get(0));a(document).unbind("mouseup touchend",A);a(document).unbind("mousemove touchmove",z);return false},B=function(b){a(this).addClass("colorpicker_focus")},C=function(b){a(this).removeClass("colorpicker_focus")},D=function(b){var c=a(this).parent();var d=c.data("colorpicker").color;c.data("colorpicker").origColor=d;m(d,c.get(0));c.data("colorpicker").onSubmit(d,R(d),P(d),c.data("colorpicker").el)},E=function(b){var c=a("body"),d=c.data("colorpickerId"),e=a(this).data("colorpickerId");if(d&&d===e){a(document).trigger("mousedown");c.data("colorpickerId",null)}else{F.call(this,b);c.data("colorpickerId",e)}},F=function(b){var c=a("#"+a(this).data("colorpickerId"));c.data("colorpicker").onBeforeShow.apply(this,[c.get(0)]);var d=a(this).offset();var e=I();var f=d.top+this.offsetHeight;var g=d.left;if(f+176>e.t+e.h){f-=this.offsetHeight+176}if(g+356>e.l+e.w){g=Math.max(0,g-356)}if(c.data("colorpicker").onShow.apply(this,[c.get(0)])!=false){c.show()}a(document).bind("mousedown",{cal:c},G);return false},G=function(b){if(!H(b.data.cal.get(0),b.target,b.data.cal.get(0))){if(b.data.cal.data("colorpicker").onHide.apply(this,[b.data.cal.get(0)])!=false){b.data.cal.hide()}a(document).unbind("mousedown",G)}},H=function(a,b,c){if(a==b){return true}if(a.contains){return a.contains(b)}if(a.compareDocumentPosition){return!!(a.compareDocumentPosition(b)&16)}var d=b.parentNode;while(d&&d!=c){if(d==a)return true;d=d.parentNode}return false},I=function(){var a=document.compatMode=="CSS1Compat";return{l:window.pageXOffset||(a?document.documentElement.scrollLeft:document.body.scrollLeft),t:window.pageYOffset||(a?document.documentElement.scrollTop:document.body.scrollTop),w:window.innerWidth||(a?document.documentElement.clientWidth:document.body.clientWidth),h:window.innerHeight||(a?document.documentElement.clientHeight:document.body.clientHeight)}},J=function(a){return{h:Math.round(Math.min(360,Math.max(0,a.h))),s:Math.round(Math.min(100,Math.max(0,a.s))),b:Math.round(Math.min(100,Math.max(0,a.b)))}},K=function(a){return{r:Math.min(255,Math.max(0,a.r)),g:Math.min(255,Math.max(0,a.g)),b:Math.min(255,Math.max(0,a.b))}},L=function(a){var b=6-a.length;if(b>0){var c=[];for(var d=0;d<b;d++){c.push("0")}c.push(a);a=c.join("")}return a},M=function(a){var a=parseInt(a.indexOf("#")>-1?a.substring(1):a,16);return{r:a>>16,g:(a&65280)>>8,b:a&255}},N=function(a){return O(M(a))},O=function(a){var b={h:0,s:0,b:0};var c=Math.min(a.r,a.g,a.b);var d=Math.max(a.r,a.g,a.b);var e=d-c;b.b=d;if(d!=0){}b.s=d!=0?255*e/d:0;if(b.s!=0){if(a.r==d){b.h=(a.g-a.b)/e}else if(a.g==d){b.h=2+(a.b-a.r)/e}else{b.h=4+(a.r-a.g)/e}}else{b.h=-1}b.h*=60;if(b.h<0){b.h+=360}b.s*=100/255;b.b*=100/255;b.h=Math.round(b.h);b.s=Math.round(b.s);b.b=Math.round(b.b);return b},P=function(a){var b={};var c=Math.round(a.h);var d=Math.round(a.s*255/100);var e=Math.round(a.b*255/100);if(d==0){b.r=b.g=b.b=e}else{var f=e;var g=(255-d)*e/255;var h=(f-g)*(c%60)/60;if(c==360)c=0;if(c<60){b.r=f;b.b=g;b.g=g+h}else if(c<120){b.g=f;b.b=g;b.r=f-h}else if(c<180){b.g=f;b.r=g;b.b=g+h}else if(c<240){b.b=f;b.r=g;b.g=f-h}else if(c<300){b.b=f;b.g=g;b.r=g+h}else if(c<360){b.r=f;b.g=g;b.b=f-h}else{b.r=0;b.g=0;b.b=0}}return{r:Math.round(b.r),g:Math.round(b.g),b:Math.round(b.b)}},Q=function(b){var c=[b.r.toString(16),b.g.toString(16),b.b.toString(16)];a.each(c,function(a,b){if(b.length==1){c[a]="0"+b}});return c.join("")},R=function(a){return Q(P(a))},S=function(){var b=a(this).parent();var c=b.data("colorpicker").origColor;b.data("colorpicker").color=c;h(c,b.get(0));j(c,b.get(0));i(c,b.get(0));k(c,b.get(0));l(c,b.get(0));n(c,b.get(0))};return{init:function(b){b=a.extend({},g,b||{});if(typeof b.color=="string"){b.color=N(b.color)}else if(b.color.r!=undefined&&b.color.g!=undefined&&b.color.b!=undefined){b.color=O(b.color)}else if(b.color.h!=undefined&&b.color.s!=undefined&&b.color.b!=undefined){b.color=J(b.color)}else{return this}return this.each(function(){if(!a(this).data("colorpickerId")){var c=a.extend({},b);c.origColor=b.color;var d="collorpicker_"+parseInt(Math.random()*1e3);a(this).data("colorpickerId",d);var e=a(f).attr("id",d);if(c.flat){e.appendTo(this).show()}else{e.appendTo(this)}c.fields=e.find("input").bind("keyup",o).bind("change",p).bind("blur",q).bind("focus",r);e.find("span").bind("mousedown touchstart",s).end().find(">div.colorpicker_current_color").bind("click",S);c.selector=e.find("div.colorpicker_color").bind("touchstart mousedown",y);c.selectorIndic=c.selector.find("div div");c.el=this;c.hue=e.find("div.colorpicker_hue div");e.find("div.colorpicker_hue").bind("mousedown touchstart",v);c.newColor=e.find("div.colorpicker_new_color");c.currentColor=e.find("div.colorpicker_current_color");e.data("colorpicker",c);e.find("div.colorpicker_submit").bind("mouseenter touchstart",B).bind("mouseleave touchend",C).bind("click",D);h(c.color,e.get(0));i(c.color,e.get(0));j(c.color,e.get(0));l(c.color,e.get(0));k(c.color,e.get(0));m(c.color,e.get(0));n(c.color,e.get(0));if(c.flat){e.css({position:"relative",display:"block"})}else{a(this).bind(c.eventName,E)}}})},showPicker:function(){return this.each(function(){if(a(this).data("colorpickerId")){F.apply(this)}})},hidePicker:function(){return this.each(function(){if(a(this).data("colorpickerId")){a("#"+a(this).data("colorpickerId")).hide()}})},setColor:function(b){if(typeof b=="string"){b=N(b)}else if(b.r!=undefined&&b.g!=undefined&&b.b!=undefined){b=O(b)}else if(b.h!=undefined&&b.s!=undefined&&b.b!=undefined){b=J(b)}else{return this}return this.each(function(){if(a(this).data("colorpickerId")){var c=a("#"+a(this).data("colorpickerId"));c.data("colorpicker").color=b;c.data("colorpicker").origColor=b;h(b,c.get(0));i(b,c.get(0));j(b,c.get(0));l(b,c.get(0));k(b,c.get(0));m(b,c.get(0));n(b,c.get(0))}})}}}();a.fn.extend({ColorPicker:b.init,ColorPickerHide:b.hidePicker,ColorPickerShow:b.showPicker,ColorPickerSetColor:b.setColor})})(jQuery)
(function($){
	$.fn.displayServ = function(options){
		var selector = $(this);
		
		// Options
		var settings = {
			config: 'config/servers.cfg.php',
			resources: 'resources/',
			timeout: 3,
			refresh: 30,
			color: '',
			links: {
				join: true,
				spectate: true,
				addfavourite: false
			}
		}
		$.extend(settings, options);
		settings.refresh = parseInt(settings.refresh * 1000);
		if(settings.refresh < 10000){
			settings.refresh = 10000;
		}
		if(settings.color){
			settings.color = ' style="color: '+settings.color+';"';
		}
		
		// Refresh
		selector.initialize(settings);
		setInterval(function(){
			selector.initialize(settings);
		}, settings.refresh);
	};
})(jQuery);

(function($){
	$.fn.initialize = function(settings){
		var selector = $(this);
		
		// 1ère étape - Initialiser DisplayServ en créant le html
		$.getJSON(settings.resources+'ajax/ds_initialize.php', {cfg: settings.config}, function(data){
			if(data != null){
				var out = '<ul class="ds-servers-list loading">';
					if(data.servers){
						for(var i = 0; i < data.servers; i++){
							out += '<li id="ds-server-'+i+'" class="ds-server">'
								+ '<table>'
									+ '<tr class="ds-header">'
										+ '<th class="first"'+settings.color+'>'+data.label.server+' n°'+(i+1)+'</th>'
										+ '<th class="middle"></th>'
										+ '<th class="last"'+settings.color+'>'+data.label.players+'</th>'
									+ '</tr>'
									+ '<tr class="ds-space"><td colspan="3"></td></tr>'
									+ '<tr class="ds-content">'
										+ '<td class="ds-part-left">'
											+ '<ul>'
												+ '<li>'+data.label.name+'</li>'
												+ '<li>'+data.label.login+'</li>'
												+ '<li>'+data.label.connect+'</li>'
												+ '<li>'+data.label.status+'</li>'
												+ '<li>'+data.label.gamemode+'</li>'
												+ '<li>'+data.label.currentmap+'</li>'
												+ '<li>'+data.label.players+'</li>'
											+ '</ul>'
										+ '</td>'
										+ '<td class="ds-part-middle">'
											+ '<ul>'
												+ '<li class="ds-server-name"></li>'
												+ '<li class="ds-server-login"></li>'
												+ '<li class="ds-server-connect"></li>'
												+ '<li class="ds-server-protocol"></li>'
												+ '<li class="ds-server-status"></li>'
												+ '<li class="ds-server-gamemode"></li>'
												+ '<li class="ds-server-currentmap"></li>'
												+ '<li class="ds-server-players-count"></li>'
											+ '</ul>'
										+ '</td>'
										+ '<td class="ds-part-right">'
											+ '<div class="ds-servers-players-list"></div>'
										+ '</td>'
									+ '</tr>'
								+ '</table>'
								+ '<div class="ds-server-join-wrap">'
										+ '<ul>';
											if(settings.links.addfavourite){
												out += '<li class="ds-server-favourite"><a href=".">'+data.label.addfavourite+'</a></li>';
											}
											if(settings.links.spectate){
												out += '<li class="ds-server-spectate"><a href=".">'+data.label.accessserverspectate+'</a></li>';
											}
											if(settings.links.join){
												out += '<li class="ds-server-join"><a href=".">'+data.label.accessserverplayer+'</a></li>';
											}
										out += '</ul>'
								+ '</div>'
							+ '</li>';
						}
					}
				out += '</ul>';
				
				// Affichage
				selector.find('.ds-servers-list').remove();
				selector.html(out);
				
				// Calcul de la taille max
				var maxsize = selector.find('.ds-servers-list').width();
				if(maxsize < 380){
					selector.find('.ds-servers-list').addClass("max-width-380");
					if(settings.links.addfavourite){
						selector.find('.ds-servers-list .ds-server-favourite').remove();
					}
					if(settings.links.spectate){
						selector.find('.ds-servers-list .ds-server-spectate').remove();
					}
				}
				else if(maxsize < 580){
					selector.find('.ds-servers-list').addClass('max-width-580');
					if(settings.links.addfavourite){
						selector.find('.ds-servers-list .ds-server-favourite').remove();
					}
				}
				
				// 2ème étape - Récupérer les données serveur
				$.getJSON(settings.resources+'ajax/ds_getservers.php', {cfg: settings.config, rsc: settings.resources}, function(data){
					if(data != null){
						if(data.servers){
							for(var i = 0; i < data.servers.length; i++){
								var serverId = $('#ds-server-'+i);
								
								// Server infos
								if(data.servers[i].error){
									serverId.find('.ds-server-name').html(data.servers[i].error);
									serverId.find('.ds-server-join-wrap').remove();
								}
								else{
									serverId.find('.ds-server-name').html(data.servers[i].name);
									serverId.find('.ds-server-login').html(data.servers[i].serverlogin);
									serverId.find('.ds-server-connect').html(data.servers[i].version.name);
									serverId.find('.ds-server-connect').addClass(data.servers[i].version.name.toLowerCase());
									serverId.find('.ds-server-status').html(data.servers[i].status);
									serverId.find('.ds-server-gamemode').html(data.servers[i].gamemode);
									serverId.find('.ds-server-gamemode').addClass(data.servers[i].gamemode.toLowerCase());
									var envImg = '';
									if(data.servers[i].map.env.filename != null){
										var envImg = ' <img src="'+data.servers[i].map.env.filename+'" alt="('+data.servers[i].map.env.name+')" title="'+data.servers[i].map.env.name+'" />';
									}
									serverId.find('.ds-server-currentmap').html(data.servers[i].map.name + envImg);
									serverId.find('.ds-server-players-count').html(data.players[i].count.current+' / '+data.players[i].count.max);
									
									// Join
									var title = '';
									if(data.servers[i].version.title){
										title += '@'+data.servers[i].version.title;
									}
									if(settings.links.join){
										serverId.find('.ds-server-join a').attr('href', data.servers[i].version.protocol+'://#join='+data.servers[i].serverlogin+title);
									}
									if(settings.links.spectate){
										serverId.find('.ds-server-spectate a').attr('href', data.servers[i].version.protocol+'://#spectate='+data.servers[i].serverlogin+title);
									}
									if(settings.links.addfavourite){
										serverId.find('.ds-server-favourite a').attr('href', data.servers[i].version.protocol+'://#addfavourite='+data.servers[i].serverlogin+title);
									}
									
									// Players
									var playerListTable = '<table>';
										if(data.players[i].count.current > 0){
											$.each(data.players[i].list, function(idPlayer, dataPlayer){
												var teamSpan = '';
												if(data.servers[i].gamemode == 'Team'){
													teamSpan = '<span class="team_'+dataPlayer.teamId+'" title="'+dataPlayer.teamName+'">&nbsp;</span>';
												}
												playerListTable += '<tr>'
													+ '<td>'+teamSpan+dataPlayer.name+'</td>'
													+ '<td>'+dataPlayer.status+'</td>'
												+ '</tr>';
											});
										}
										else{
											playerListTable += '<td class="no-player" colspan="2">'+data.players[i].list+'</td>';
										}
									playerListTable += '</table>';
									serverId.find('.ds-servers-players-list').html(playerListTable);
								}
							}
						}
						
						selector.find('.ds-servers-list').removeClass('loading');
					}
				});
			}
		});
	};
})(jQuery);
/**
 * http://github.com/Valums-File-Uploader/file-uploader
 *
 * Multiple file upload component with progress-bar, drag-and-drop.
 *
 * Have ideas for improving this JS for the general community?
 * Submit your changes at: https://github.com/Valums-File-Uploader/file-uploader
 * Readme at https://github.com/valums/file-uploader/blob/2.0/readme.md
 *
 * VERSION 2.1-SNAPSHOT
 * Original version: 1.0 © 2010 Andrew Valums ( andrew(at)valums.com )
 * Current Maintainer (2.0+): © 2012, Ray Nicholus ( fineuploader(at)garstasio.com )
 *
 * Licensed under MIT license, GNU GPL 2 or later, GNU LGPL 2 or later, see license.txt.
 */
var qq=qq||{};qq.extend=function(a,b){for(var c in b){a[c]=b[c]}};qq.indexOf=function(a,b,c){if(a.indexOf)return a.indexOf(b,c);c=c||0;var d=a.length;if(c<0)c+=d;for(;c<d;c++){if(c in a&&a[c]===b){return c}}return-1};qq.getUniqueId=function(){var a=0;return function(){return a++}}();qq.ie=function(){return navigator.userAgent.indexOf("MSIE")!=-1};qq.safari=function(){return navigator.vendor!=undefined&&navigator.vendor.indexOf("Apple")!=-1};qq.chrome=function(){return navigator.vendor!=undefined&&navigator.vendor.indexOf("Google")!=-1};qq.firefox=function(){return navigator.userAgent.indexOf("Mozilla")!=-1&&navigator.vendor!=undefined&&navigator.vendor==""};qq.windows=function(){return navigator.platform=="Win32"};qq.attach=function(a,b,c){if(a.addEventListener){a.addEventListener(b,c,false)}else if(a.attachEvent){a.attachEvent("on"+b,c)}return function(){qq.detach(a,b,c)}};qq.detach=function(a,b,c){if(a.removeEventListener){a.removeEventListener(b,c,false)}else if(a.attachEvent){a.detachEvent("on"+b,c)}};qq.preventDefault=function(a){if(a.preventDefault){a.preventDefault()}else{a.returnValue=false}};qq.insertBefore=function(a,b){b.parentNode.insertBefore(a,b)};qq.remove=function(a){a.parentNode.removeChild(a)};qq.contains=function(a,b){if(a==b)return true;if(a.contains){return a.contains(b)}else{return!!(b.compareDocumentPosition(a)&8)}};qq.toElement=function(){var a=document.createElement("div");return function(b){a.innerHTML=b;var c=a.firstChild;a.removeChild(c);return c}}();qq.css=function(a,b){if(b.opacity!=null){if(typeof a.style.opacity!="string"&&typeof a.filters!="undefined"){b.filter="alpha(opacity="+Math.round(100*b.opacity)+")"}}qq.extend(a.style,b)};qq.hasClass=function(a,b){var c=new RegExp("(^| )"+b+"( |$)");return c.test(a.className)};qq.addClass=function(a,b){if(!qq.hasClass(a,b)){a.className+=" "+b}};qq.removeClass=function(a,b){var c=new RegExp("(^| )"+b+"( |$)");a.className=a.className.replace(c," ").replace(/^\s+|\s+$/g,"")};qq.setText=function(a,b){a.innerText=b;a.textContent=b};qq.children=function(a){var b=[],c=a.firstChild;while(c){if(c.nodeType==1){b.push(c)}c=c.nextSibling}return b};qq.getByClass=function(a,b){if(a.querySelectorAll){return a.querySelectorAll("."+b)}var c=[];var d=a.getElementsByTagName("*");var e=d.length;for(var f=0;f<e;f++){if(qq.hasClass(d[f],b)){c.push(d[f])}}return c};qq.obj2url=function(a,b,c){var d=[],e="&",f=function(a,c){var e=b?/\[\]$/.test(b)?b:b+"["+c+"]":c;if(e!="undefined"&&c!="undefined"){d.push(typeof a==="object"?qq.obj2url(a,e,true):Object.prototype.toString.call(a)==="[object Function]"?encodeURIComponent(e)+"="+encodeURIComponent(a()):encodeURIComponent(e)+"="+encodeURIComponent(a))}};if(!c&&b){e=/\?/.test(b)?/\?$/.test(b)?"":"&":"?";d.push(b);d.push(qq.obj2url(a))}else if(Object.prototype.toString.call(a)==="[object Array]"&&typeof a!="undefined"){for(var g=0,h=a.length;g<h;++g){f(a[g],g)}}else if(typeof a!="undefined"&&a!==null&&typeof a==="object"){for(var g in a){f(a[g],g)}}else{d.push(encodeURIComponent(b)+"="+encodeURIComponent(a))}return d.join(e).replace(/^&/,"").replace(/%20/g,"+")};var qq=qq||{};qq.FileUploaderBasic=function(a){var b=this;this._options={debug:false,action:"/server/upload",params:{},customHeaders:{},button:null,multiple:true,maxConnections:3,disableCancelForFormUploads:false,autoUpload:true,allowedExtensions:[],acceptFiles:null,sizeLimit:0,minSizeLimit:0,onSubmit:function(a,b){},onComplete:function(a,b,c){},onCancel:function(a,b){},onUpload:function(a,b,c){},onProgress:function(a,b,c,d){},onError:function(a,b,c){},messages:{typeError:"{file} has an invalid extension. Only {extensions} {isAre} allowed.",sizeError:"{file} is too large, maximum file size is {sizeLimit}.",minSizeError:"{file} is too small, minimum file size is {minSizeLimit}.",emptyError:"{file} is empty, please select files again without it.",noFilesError:"No files to upload.",onLeave:"The files are being uploaded, if you leave now the upload will be cancelled."},showMessage:function(a){alert(a)},inputName:"qqfile"};qq.extend(this._options,a);qq.extend(this,qq.DisposeSupport);this._filesInProgress=0;this._storedFileIds=[];this._handler=this._createUploadHandler();if(this._options.button){this._button=this._createUploadButton(this._options.button)}this._preventLeaveInProgress()};qq.FileUploaderBasic.prototype={setParams:function(a){this._options.params=a},getInProgress:function(){return this._filesInProgress},uploadStoredFiles:function(){for(var a=0;a<this._storedFileIds.length;a++){this._filesInProgress++;this._handler.upload(this._storedFileIds[a],this._options.params)}},clearStoredFiles:function(){this._storedFileIds=[]},_createUploadButton:function(a){var b=this;var c=new qq.UploadButton({element:a,multiple:this._options.multiple&&qq.UploadHandlerXhr.isSupported(),acceptFiles:this._options.acceptFiles,onChange:function(a){b._onInputChange(a)}});this.addDisposer(function(){c.dispose()});return c},_createUploadHandler:function(){var a=this,b;if(qq.UploadHandlerXhr.isSupported()){b="UploadHandlerXhr"}else{b="UploadHandlerForm"}var c=new qq[b]({debug:this._options.debug,action:this._options.action,encoding:this._options.encoding,maxConnections:this._options.maxConnections,customHeaders:this._options.customHeaders,inputName:this._options.inputName,demoMode:this._options.demoMode,onProgress:function(b,c,d,e){a._onProgress(b,c,d,e);a._options.onProgress(b,c,d,e)},onComplete:function(b,c,d){a._onComplete(b,c,d);a._options.onComplete(b,c,d)},onCancel:function(b,c){var d=qq.indexOf(a._storedFileIds,b);if(d>=0){a._storedFileIds.splice(d,1)}a._onCancel(b,c);a._options.onCancel(b,c)},onError:a._options.onError,onUpload:function(b,c,d){a._onUpload(b,c,d);a._options.onUpload(b,c,d)}});return c},_preventLeaveInProgress:function(){var a=this;this._attach(window,"beforeunload",function(b){if(!a._filesInProgress){return}var b=b||window.event;b.returnValue=a._options.messages.onLeave;return a._options.messages.onLeave})},_onSubmit:function(a,b){if(this._options.autoUpload){this._filesInProgress++}},_onProgress:function(a,b,c,d){},_onComplete:function(a,b,c){var d=qq.indexOf(this._storedFileIds,a);if(d>=0){this._storedFileIds.splice(d,1)}this._filesInProgress--;if(c.error){this._options.showMessage(c.error)}},_onCancel:function(a,b){if(this._options.autoUpload){this._filesInProgress--}},_onUpload:function(a,b,c){},_onInputChange:function(a){if(this._handler instanceof qq.UploadHandlerXhr){this._uploadFileList(a.files)}else{if(this._validateFile(a)){this._uploadFile(a)}}this._button.reset()},_uploadFileList:function(a){if(a.length>0){for(var b=0;b<a.length;b++){if(!this._validateFile(a[b])){return}}for(var b=0;b<a.length;b++){this._uploadFile(a[b])}}else{this._error("noFilesError","")}},_uploadFile:function(a){var b=this._handler.add(a);var c=this._handler.getName(b);if(this._options.onSubmit(b,c)!==false){this._onSubmit(b,c);if(this._options.autoUpload){this._handler.upload(b,this._options.params)}else{this._storeFileForLater(b)}}},_storeFileForLater:function(a){this._storedFileIds.push(a)},_validateFile:function(a){var b,c;if(a.value){b=a.value.replace(/.*(\/|\\)/,"")}else{b=a.fileName!==null&&a.fileName!==undefined?a.fileName:a.name;c=a.fileSize!==null&&a.fileSize!==undefined?a.fileSize:a.size}if(!this._isAllowedExtension(b)){this._error("typeError",b);return false}else if(c===0){this._error("emptyError",b);return false}else if(c&&this._options.sizeLimit&&c>this._options.sizeLimit){this._error("sizeError",b);return false}else if(c&&c<this._options.minSizeLimit){this._error("minSizeError",b);return false}return true},_error:function(a,b){function d(a,b){c=c.replace(a,b)}var c=this._options.messages[a];var e=this._options.allowedExtensions.join(", ");d("{file}",this._formatFileName(b));d("{extensions}",e);d("{sizeLimit}",this._formatSize(this._options.sizeLimit));d("{minSizeLimit}",this._formatSize(this._options.minSizeLimit));d("{isAre}",e.indexOf(",")!=-1?"are":"is");this._options.showMessage(c)},_formatFileName:function(a){if(a.length>33){a=a.slice(0,19)+"..."+a.slice(-13)}return a},_isAllowedExtension:function(a){var b=-1!==a.indexOf(".")?a.replace(/.*[.]/,"").toLowerCase():"";var c=this._options.allowedExtensions;if(!c.length){return true}for(var d=0;d<c.length;d++){if(c[d].toLowerCase()==b){return true}}return false},_formatSize:function(a){var b=-1;do{a=a/1024;b++}while(a>99);return Math.max(a,.1).toFixed(1)+["kB","MB","GB","TB","PB","EB"][b]}};qq.FileUploader=function(a){qq.FileUploaderBasic.apply(this,arguments);qq.extend(this._options,{element:null,listElement:null,dragText:"Drop files here to upload",extraDropzones:[],uploadButtonText:"Upload a file",cancelButtonText:"Cancel",failUploadText:"Upload failed",template:'<div class="qq-uploader">'+'<div class="qq-upload-drop-area"><span>{dragText}</span></div>'+'<div class="qq-upload-button">{uploadButtonText}</div>'+(!this._options.listElement?'<ul class="qq-upload-list"></ul>':"")+"</div>",fileTemplate:"<li>"+'<span class="qq-progress-bar"></span>'+'<span class="qq-upload-spinner"></span>'+'<span class="qq-upload-finished"></span>'+'<span class="qq-upload-file"></span>'+'<span class="qq-upload-size"></span>'+'<a class="qq-upload-cancel" href="#">{cancelButtonText}</a>'+'<span class="qq-upload-failed-text">{failUploadtext}</span>'+"</li>",classes:{button:"qq-upload-button",drop:"qq-upload-drop-area",dropActive:"qq-upload-drop-area-active",dropDisabled:"qq-upload-drop-area-disabled",list:"qq-upload-list",progressBar:"qq-progress-bar",file:"qq-upload-file",spinner:"qq-upload-spinner",finished:"qq-upload-finished",size:"qq-upload-size",cancel:"qq-upload-cancel",success:"qq-upload-success",fail:"qq-upload-fail",successIcon:null,failIcon:null},extraMessages:{formatProgress:"{percent}% of {total_size}",tooManyFilesError:"You may only drop one file"}});qq.extend(this._options,a);qq.extend(this._options.messages,this._options.extraMessages);this._options.template=this._options.template.replace(/\{dragText\}/g,this._options.dragText);this._options.template=this._options.template.replace(/\{uploadButtonText\}/g,this._options.uploadButtonText);this._options.fileTemplate=this._options.fileTemplate.replace(/\{cancelButtonText\}/g,this._options.cancelButtonText);this._options.fileTemplate=this._options.fileTemplate.replace(/\{failUploadtext\}/g,this._options.failUploadText);this._element=this._options.element;this._element.innerHTML=this._options.template;this._listElement=this._options.listElement||this._find(this._element,"list");this._classes=this._options.classes;this._button=this._createUploadButton(this._find(this._element,"button"));this._bindCancelEvent();this._setupDragDrop()};qq.extend(qq.FileUploader.prototype,qq.FileUploaderBasic.prototype);qq.extend(qq.FileUploader.prototype,{clearStoredFiles:function(){qq.FileUploaderBasic.prototype.clearStoredFiles.apply(this,arguments);this._listElement.innerHTML=""},addExtraDropzone:function(a){this._setupExtraDropzone(a)},removeExtraDropzone:function(a){var b=this._options.extraDropzones;for(var c in b)if(b[c]===a)return this._options.extraDropzones.splice(c,1)},_leaving_document_out:function(a){return(qq.chrome()||qq.safari()&&qq.windows())&&a.clientX==0&&a.clientY==0||qq.firefox()&&!a.relatedTarget},_storeFileForLater:function(a){qq.FileUploaderBasic.prototype._storeFileForLater.apply(this,arguments);var b=this._getItemByFileId(a);this._find(b,"spinner").style.display="none"},_find:function(a,b){var c=qq.getByClass(a,this._options.classes[b])[0];if(!c){throw new Error("element not found "+b)}return c},_setupExtraDropzone:function(a){this._options.extraDropzones.push(a);this._setupDropzone(a)},_setupDropzone:function(a){var b=this;var c=new qq.UploadDropZone({element:a,onEnter:function(c){qq.addClass(a,b._classes.dropActive);c.stopPropagation()},onLeave:function(a){},onLeaveNotDescendants:function(c){qq.removeClass(a,b._classes.dropActive)},onDrop:function(c){a.style.display="none";qq.removeClass(a,b._classes.dropActive);if(c.dataTransfer.files.length>1&&!b._options.multiple){b._error("tooManyFilesError","")}else{b._uploadFileList(c.dataTransfer.files)}}});this.addDisposer(function(){c.dispose()});a.style.display="none"},_setupDragDrop:function(){var a=this._find(this._element,"drop");var b=this;this._options.extraDropzones.push(a);var c=this._options.extraDropzones;var d;for(d=0;d<c.length;d++){this._setupDropzone(c[d])}if(!qq.ie()){this._attach(document,"dragenter",function(e){if(qq.hasClass(a,b._classes.dropDisabled))return;a.style.display="block";for(d=0;d<c.length;d++){c[d].style.display="block"}})}this._attach(document,"dragleave",function(a){var b=document.elementFromPoint(a.clientX,a.clientY);if(qq.FileUploader.prototype._leaving_document_out(a)){for(d=0;d<c.length;d++){c[d].style.display="none"}}});qq.attach(document,"drop",function(a){for(d=0;d<c.length;d++){c[d].style.display="none"}a.preventDefault()})},_onSubmit:function(a,b){qq.FileUploaderBasic.prototype._onSubmit.apply(this,arguments);this._addToList(a,b)},_onProgress:function(a,b,c,d){qq.FileUploaderBasic.prototype._onProgress.apply(this,arguments);var e=this._getItemByFileId(a);if(c===d){var f=this._find(e,"cancel");f.style.display="none"}var g=this._find(e,"size");g.style.display="inline";var h;var i=Math.round(c/d*100);if(c!=d){h=this._formatProgress(c,d)}else{h=this._formatSize(d)}this._find(e,"progressBar").style.width=i+"%";qq.setText(g,h)},_onComplete:function(a,b,c){qq.FileUploaderBasic.prototype._onComplete.apply(this,arguments);var d=this._getItemByFileId(a);if(!this._options.disableCancelForFormUploads||qq.UploadHandlerXhr.isSupported()){qq.remove(this._find(d,"cancel"))}qq.remove(this._find(d,"spinner"));if(c.success){qq.addClass(d,this._classes.success);if(this._classes.successIcon){this._find(d,"finished").style.display="inline-block";qq.addClass(d,this._classes.successIcon)}}else{var e=c.reason?c.reason:"Unknown error";qq.addClass(d,this._classes.fail);if(this._classes.failIcon){this._find(d,"finished").style.display="inline-block";qq.addClass(d,this._classes.failIcon)}d.title=e}},_onUpload:function(a,b,c){qq.FileUploaderBasic.prototype._onUpload.apply(this,arguments);var d=this._getItemByFileId(a);var e=this._find(d,"spinner");if(e.style.display=="none"){e.style.display="inline-block"}},_addToList:function(a,b){var c=qq.toElement(this._options.fileTemplate);if(this._options.disableCancelForFormUploads&&!qq.UploadHandlerXhr.isSupported()){var d=this._find(c,"cancel");qq.remove(d)}c.qqFileId=a;var e=this._find(c,"file");qq.setText(e,this._formatFileName(b));this._find(c,"size").style.display="none";if(!this._options.multiple)this._clearList();this._listElement.appendChild(c)},_clearList:function(){this._listElement.innerHTML="";this.clearStoredFiles()},_getItemByFileId:function(a){var b=this._listElement.firstChild;while(b){if(b.qqFileId==a)return b;b=b.nextSibling}},_bindCancelEvent:function(){var a=this,b=this._listElement;this._attach(b,"click",function(b){b=b||window.event;var c=b.target||b.srcElement;if(qq.hasClass(c,a._classes.cancel)){qq.preventDefault(b);var d=c.parentNode;a._handler.cancel(d.qqFileId);qq.remove(d)}})},_formatProgress:function(a,b){function d(a,b){c=c.replace(a,b)}var c=this._options.messages.formatProgress;d("{percent}",Math.round(a/b*100));d("{total_size}",this._formatSize(b));return c}});qq.UploadDropZone=function(a){this._options={element:null,onEnter:function(a){},onLeave:function(a){},onLeaveNotDescendants:function(a){},onDrop:function(a){}};qq.extend(this._options,a);qq.extend(this,qq.DisposeSupport);this._element=this._options.element;this._disableDropOutside();this._attachEvents()};qq.UploadDropZone.prototype={_dragover_should_be_canceled:function(){return qq.safari()||qq.firefox()&&qq.windows()},_disableDropOutside:function(a){if(!qq.UploadDropZone.dropOutsideDisabled){if(this._dragover_should_be_canceled){qq.attach(document,"dragover",function(a){a.preventDefault()})}else{qq.attach(document,"dragover",function(a){if(a.dataTransfer){a.dataTransfer.dropEffect="none";a.preventDefault()}})}qq.UploadDropZone.dropOutsideDisabled=true}},_attachEvents:function(){var a=this;a._attach(a._element,"dragover",function(b){if(!a._isValidFileDrag(b))return;var c=qq.ie()?null:b.dataTransfer.effectAllowed;if(c=="move"||c=="linkMove"){b.dataTransfer.dropEffect="move"}else{b.dataTransfer.dropEffect="copy"}b.stopPropagation();b.preventDefault()});a._attach(a._element,"dragenter",function(b){if(!a._isValidFileDrag(b))return;a._options.onEnter(b)});a._attach(a._element,"dragleave",function(b){if(!a._isValidFileDrag(b))return;a._options.onLeave(b);var c=document.elementFromPoint(b.clientX,b.clientY);if(qq.contains(this,c))return;a._options.onLeaveNotDescendants(b)});a._attach(a._element,"drop",function(b){if(!a._isValidFileDrag(b))return;b.preventDefault();a._options.onDrop(b)})},_isValidFileDrag:function(a){if(qq.ie())return false;var b=a.dataTransfer,c=qq.safari();return b&&b.effectAllowed!="none"&&(b.files||!c&&b.types.contains&&b.types.contains("Files"))}};qq.UploadButton=function(a){this._options={element:null,multiple:false,acceptFiles:null,name:"file",onChange:function(a){},hoverClass:"qq-upload-button-hover",focusClass:"qq-upload-button-focus"};qq.extend(this._options,a);qq.extend(this,qq.DisposeSupport);this._element=this._options.element;qq.css(this._element,{position:"relative",overflow:"hidden",direction:"ltr"});this._input=this._createInput()};qq.UploadButton.prototype={getInput:function(){return this._input},reset:function(){if(this._input.parentNode){qq.remove(this._input)}qq.removeClass(this._element,this._options.focusClass);this._input=this._createInput()},_createInput:function(){var a=document.createElement("input");if(this._options.multiple){a.setAttribute("multiple","multiple")}if(this._options.acceptFiles)a.setAttribute("accept",this._options.acceptFiles);a.setAttribute("type","file");a.setAttribute("name",this._options.name);qq.css(a,{position:"absolute",right:0,top:0,fontFamily:"Arial",fontSize:"118px",margin:0,padding:0,cursor:"pointer",opacity:0});this._element.appendChild(a);var b=this;this._attach(a,"change",function(){b._options.onChange(a)});this._attach(a,"mouseover",function(){qq.addClass(b._element,b._options.hoverClass)});this._attach(a,"mouseout",function(){qq.removeClass(b._element,b._options.hoverClass)});this._attach(a,"focus",function(){qq.addClass(b._element,b._options.focusClass)});this._attach(a,"blur",function(){qq.removeClass(b._element,b._options.focusClass)});if(window.attachEvent){a.setAttribute("tabIndex","-1")}return a}};qq.UploadHandlerAbstract=function(a){this._options={debug:false,action:"/upload.php",maxConnections:999,onProgress:function(a,b,c,d){},onComplete:function(a,b,c){},onCancel:function(a,b){},onUpload:function(a,b,c){}};qq.extend(this._options,a);this._queue=[];this._params=[]};qq.UploadHandlerAbstract.prototype={log:function(a){if(this._options.debug&&window.console)console.log("[uploader] "+a)},add:function(a){},upload:function(a,b){var c=this._queue.push(a);var d={};qq.extend(d,b);this._params[a]=d;if(c<=this._options.maxConnections){this._upload(a,this._params[a])}},cancel:function(a){this._cancel(a);this._dequeue(a)},cancelAll:function(){for(var a=0;a<this._queue.length;a++){this._cancel(this._queue[a])}this._queue=[]},getName:function(a){},getSize:function(a){},getQueue:function(){return this._queue},_upload:function(a){},_cancel:function(a){},_dequeue:function(a){var b=qq.indexOf(this._queue,a);this._queue.splice(b,1);var c=this._options.maxConnections;if(this._queue.length>=c&&b<c){var d=this._queue[c-1];this._upload(d,this._params[d])}}};qq.UploadHandlerForm=function(a){qq.UploadHandlerAbstract.apply(this,arguments);this._inputs={};this._detach_load_events={}};qq.extend(qq.UploadHandlerForm.prototype,qq.UploadHandlerAbstract.prototype);qq.extend(qq.UploadHandlerForm.prototype,{add:function(a){a.setAttribute("name",this._options.inputName);var b="qq-upload-handler-iframe"+qq.getUniqueId();this._inputs[b]=a;if(a.parentNode){qq.remove(a)}return b},getName:function(a){return this._inputs[a].value.replace(/.*(\/|\\)/,"")},_cancel:function(a){this._options.onCancel(a,this.getName(a));delete this._inputs[a];delete this._detach_load_events[a];var b=document.getElementById(a);if(b){b.setAttribute("src","javascript:false;");qq.remove(b)}},_upload:function(a,b){this._options.onUpload(a,this.getName(a),false);var c=this._inputs[a];if(!c){throw new Error("file with passed id was not added, or already uploaded or cancelled")}var d=this.getName(a);b[this._options.inputName]=d;var e=this._createIframe(a);var f=this._createForm(e,b);f.appendChild(c);var g=this;this._attachLoadEvent(e,function(){g.log("iframe loaded");var b=g._getIframeContentJSON(e);g._options.onComplete(a,d,b);g._dequeue(a);delete g._inputs[a];setTimeout(function(){g._detach_load_events[a]();delete g._detach_load_events[a];qq.remove(e)},1)});f.submit();qq.remove(f);return a},_attachLoadEvent:function(a,b){this._detach_load_events[a.id]=qq.attach(a,"load",function(){if(!a.parentNode){return}try{if(a.contentDocument&&a.contentDocument.body&&a.contentDocument.body.innerHTML=="false"){return}}catch(c){}b()})},_getIframeContentJSON:function(iframe){try{var doc=iframe.contentDocument?iframe.contentDocument:iframe.contentWindow.document,response;var innerHTML=doc.body.innerHTML;this.log("converting iframe's innerHTML to JSON");this.log("innerHTML = "+innerHTML);if(innerHTML.slice(0,5).toLowerCase()=="<pre>"&&innerHTML.slice(-6).toLowerCase()=="</pre>"){innerHTML=doc.body.firstChild.firstChild.nodeValue}response=eval("("+innerHTML+")")}catch(err){response={success:false}}return response},_createIframe:function(a){var b=qq.toElement('<iframe src="javascript:false;" name="'+a+'" />');b.setAttribute("id",a);b.style.display="none";document.body.appendChild(b);return b},_createForm:function(a,b){var c=this._options.demoMode?"GET":"POST";var d=qq.toElement('<form method="'+c+'" enctype="multipart/form-data"></form>');var e=qq.obj2url(b,this._options.action);d.setAttribute("action",e);d.setAttribute("target",a.name);d.style.display="none";document.body.appendChild(d);return d}});qq.UploadHandlerXhr=function(a){qq.UploadHandlerAbstract.apply(this,arguments);this._files=[];this._xhrs=[];this._loaded=[]};qq.UploadHandlerXhr.isSupported=function(){var a=document.createElement("input");a.type="file";return"multiple"in a&&typeof File!="undefined"&&typeof FormData!="undefined"&&typeof (new XMLHttpRequest).upload!="undefined"};qq.extend(qq.UploadHandlerXhr.prototype,qq.UploadHandlerAbstract.prototype);qq.extend(qq.UploadHandlerXhr.prototype,{add:function(a){if(!(a instanceof File)){throw new Error("Passed obj in not a File (in qq.UploadHandlerXhr)")}return this._files.push(a)-1},getName:function(a){var b=this._files[a];return b.fileName!==null&&b.fileName!==undefined?b.fileName:b.name},getSize:function(a){var b=this._files[a];return b.fileSize!=null?b.fileSize:b.size},getLoaded:function(a){return this._loaded[a]||0},_upload:function(a,b){this._options.onUpload(a,this.getName(a),true);var c=this._files[a],d=this.getName(a),e=this.getSize(a);this._loaded[a]=0;var f=this._xhrs[a]=new XMLHttpRequest;var g=this;f.upload.onprogress=function(b){if(b.lengthComputable){g._loaded[a]=b.loaded;g._options.onProgress(a,d,b.loaded,b.total)}};f.onreadystatechange=function(){if(f.readyState==4){g._onComplete(a,f)}};b=b||{};b[this._options.inputName]=d;var h=qq.obj2url(b,this._options.action);var i=this._options.demoMode?"GET":"POST";f.open(i,h,true);f.setRequestHeader("X-Requested-With","XMLHttpRequest");f.setRequestHeader("X-File-Name",encodeURIComponent(d));if(this._options.encoding=="multipart"){var j=new FormData;j.append(this._options.inputName,c);c=j}else{f.setRequestHeader("Content-Type","application/octet-stream");f.setRequestHeader("X-Mime-Type",c.type)}for(key in this._options.customHeaders){f.setRequestHeader(key,this._options.customHeaders[key])}f.send(c)},_onComplete:function(id,xhr){"use strict";if(!this._files[id]){return}var name=this.getName(id);var size=this.getSize(id);var response;this._options.onProgress(id,name,size,size);this.log("xhr - server response received");this.log("responseText = "+xhr.responseText);try{if(typeof JSON.parse==="function"){response=JSON.parse(xhr.responseText)}else{response=eval("("+xhr.responseText+")")}}catch(err){response={}}if(xhr.status!==200){this._options.onError(id,name,xhr)}this._options.onComplete(id,name,response);this._xhrs[id]=null;this._dequeue(id)},_cancel:function(a){this._options.onCancel(a,this.getName(a));this._files[a]=null;if(this._xhrs[a]){this._xhrs[a].abort();this._xhrs[a]=null}}});qq.DisposeSupport={_disposers:[],dispose:function(){var a;while(a=this._disposers.shift()){a()}},addDisposer:function(a){this._disposers.push(a)},_attach:function(){this.addDisposer(qq.attach.apply(this,arguments))}}
/*! jQuery UI - v1.10.3 - 2013-05-03
* http://jqueryui.com
* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
(function(t,e){function i(e,i){var n,o,a,r=e.nodeName.toLowerCase();return"area"===r?(n=e.parentNode,o=n.name,e.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap=#"+o+"]")[0],!!a&&s(a)):!1):(/input|select|textarea|button|object/.test(r)?!e.disabled:"a"===r?e.href||i:i)&&s(e)}function s(e){return t.expr.filters.visible(e)&&!t(e).parents().addBack().filter(function(){return"hidden"===t.css(this,"visibility")}).length}var n=0,o=/^ui-id-\d+$/;t.ui=t.ui||{},t.extend(t.ui,{version:"1.10.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),t.fn.extend({focus:function(e){return function(i,s){return"number"==typeof i?this.each(function(){var e=this;setTimeout(function(){t(e).focus(),s&&s.call(e)},i)}):e.apply(this,arguments)}}(t.fn.focus),scrollParent:function(){var e;return e=t.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(t.css(this,"position"))&&/(auto|scroll)/.test(t.css(this,"overflow")+t.css(this,"overflow-y")+t.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(t.css(this,"overflow")+t.css(this,"overflow-y")+t.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!e.length?t(document):e},zIndex:function(i){if(i!==e)return this.css("zIndex",i);if(this.length)for(var s,n,o=t(this[0]);o.length&&o[0]!==document;){if(s=o.css("position"),("absolute"===s||"relative"===s||"fixed"===s)&&(n=parseInt(o.css("zIndex"),10),!isNaN(n)&&0!==n))return n;o=o.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){o.test(this.id)&&t(this).removeAttr("id")})}}),t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])},focusable:function(e){return i(e,!isNaN(t.attr(e,"tabindex")))},tabbable:function(e){var s=t.attr(e,"tabindex"),n=isNaN(s);return(n||s>=0)&&i(e,!n)}}),t("<a>").outerWidth(1).jquery||t.each(["Width","Height"],function(i,s){function n(e,i,s,n){return t.each(o,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),n&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var o="Width"===s?["Left","Right"]:["Top","Bottom"],a=s.toLowerCase(),r={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+s]=function(i){return i===e?r["inner"+s].call(this):this.each(function(){t(this).css(a,n(this,i)+"px")})},t.fn["outer"+s]=function(e,i){return"number"!=typeof e?r["outer"+s].call(this,e):this.each(function(){t(this).css(a,n(this,e,!0,i)+"px")})}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(t.fn.removeData=function(e){return function(i){return arguments.length?e.call(this,t.camelCase(i)):e.call(this)}}(t.fn.removeData)),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),t.support.selectstart="onselectstart"in document.createElement("div"),t.fn.extend({disableSelection:function(){return this.bind((t.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(t){t.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),t.extend(t.ui,{plugin:{add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i){var s,n=t.plugins[e];if(n&&t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType)for(s=0;n.length>s;s++)t.options[n[s][0]]&&n[s][1].apply(t.element,i)}},hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)}})})(jQuery),function(t,e){var i=0,s=Array.prototype.slice,n=t.cleanData;t.cleanData=function(e){for(var i,s=0;null!=(i=e[s]);s++)try{t(i).triggerHandler("remove")}catch(o){}n(e)},t.widget=function(i,s,n){var o,a,r,h,l={},c=i.split(".")[0];i=i.split(".")[1],o=c+"-"+i,n||(n=s,s=t.Widget),t.expr[":"][o.toLowerCase()]=function(e){return!!t.data(e,o)},t[c]=t[c]||{},a=t[c][i],r=t[c][i]=function(t,i){return this._createWidget?(arguments.length&&this._createWidget(t,i),e):new r(t,i)},t.extend(r,a,{version:n.version,_proto:t.extend({},n),_childConstructors:[]}),h=new s,h.options=t.widget.extend({},h.options),t.each(n,function(i,n){return t.isFunction(n)?(l[i]=function(){var t=function(){return s.prototype[i].apply(this,arguments)},e=function(t){return s.prototype[i].apply(this,t)};return function(){var i,s=this._super,o=this._superApply;return this._super=t,this._superApply=e,i=n.apply(this,arguments),this._super=s,this._superApply=o,i}}(),e):(l[i]=n,e)}),r.prototype=t.widget.extend(h,{widgetEventPrefix:a?h.widgetEventPrefix:i},l,{constructor:r,namespace:c,widgetName:i,widgetFullName:o}),a?(t.each(a._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,r,i._proto)}),delete a._childConstructors):s._childConstructors.push(r),t.widget.bridge(i,r)},t.widget.extend=function(i){for(var n,o,a=s.call(arguments,1),r=0,h=a.length;h>r;r++)for(n in a[r])o=a[r][n],a[r].hasOwnProperty(n)&&o!==e&&(i[n]=t.isPlainObject(o)?t.isPlainObject(i[n])?t.widget.extend({},i[n],o):t.widget.extend({},o):o);return i},t.widget.bridge=function(i,n){var o=n.prototype.widgetFullName||i;t.fn[i]=function(a){var r="string"==typeof a,h=s.call(arguments,1),l=this;return a=!r&&h.length?t.widget.extend.apply(null,[a].concat(h)):a,r?this.each(function(){var s,n=t.data(this,o);return n?t.isFunction(n[a])&&"_"!==a.charAt(0)?(s=n[a].apply(n,h),s!==n&&s!==e?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):e):t.error("no such method '"+a+"' for "+i+" widget instance"):t.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+a+"'")}):this.each(function(){var e=t.data(this,o);e?e.option(a||{})._init():t.data(this,o,new n(a,this))}),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this.bindings=t(),this.hoverable=t(),this.focusable=t(),s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:t.noop,_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(t.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:t.noop,widget:function(){return this.element},option:function(i,s){var n,o,a,r=i;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof i)if(r={},n=i.split("."),i=n.shift(),n.length){for(o=r[i]=t.widget.extend({},this.options[i]),a=0;n.length-1>a;a++)o[n[a]]=o[n[a]]||{},o=o[n[a]];if(i=n.pop(),s===e)return o[i]===e?null:o[i];o[i]=s}else{if(s===e)return this.options[i]===e?null:this.options[i];r[i]=s}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return this.options[t]=e,"disabled"===t&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!e).attr("aria-disabled",e),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var o,a=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=o=t(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,o=this.widget()),t.each(n,function(n,r){function h(){return i||a.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof r?a[r]:r).apply(a,arguments):e}"string"!=typeof r&&(h.guid=r.guid=r.guid||h.guid||t.guid++);var l=n.match(/^(\w+)\s*(.*)$/),c=l[1]+a.eventNamespace,u=l[2];u?o.delegate(u,c,h):s.bind(c,h)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(e).undelegate(e)},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){t(e.currentTarget).addClass("ui-state-hover")},mouseleave:function(e){t(e.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){t(e.currentTarget).addClass("ui-state-focus")},focusout:function(e){t(e.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}})}(jQuery),function(t){var e=!1;t(document).mouseup(function(){e=!1}),t.widget("ui.mouse",{version:"1.10.3",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.bind("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).bind("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!e){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,o="string"==typeof this.options.cancel&&i.target.nodeName?t(i.target).closest(this.options.cancel).length:!1;return n&&!o&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===t.data(i.target,this.widgetName+".preventClickEvent")&&t.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return s._mouseMove(t)},this._mouseUpDelegate=function(t){return s._mouseUp(t)},t(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),e=!0,!0)):!0}},_mouseMove:function(e){return t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button?this._mouseUp(e):this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){return t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),!1},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})}(jQuery),function(t){t.widget("ui.draggable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(t(i.iframeFix===!0?"iframe":i.iframeFix).each(function(){t("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(t(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offsetParent=this.helper.offsetParent(),this.offsetParentCssPosition=this.offsetParent.css("position"),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.offset.scroll=!1,t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_mouseDrag:function(e,i){if("fixed"===this.offsetParentCssPosition&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"original"!==this.options.helper||t.contains(this.element[0].ownerDocument,this.element[0])?("invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1):!1},_mouseUp:function(e){return t("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.element.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;return n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):"document"===n.containment?(this.containment=[0,0,t(document).width()-this.helperProportions.width-this.margins.left,(t(document).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):n.containment.constructor===Array?(this.containment=n.containment,undefined):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e="hidden"!==i.css("overflow"),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i),undefined):(this.containment=null,undefined)},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent;return this.offset.scroll||(this.offset.scroll={top:n.scrollTop(),left:n.scrollLeft()}),{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top)*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)*s}},_generatePosition:function(e){var i,s,n,o,a=this.options,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=e.pageX,l=e.pageY;return this.offset.scroll||(this.offset.scroll={top:r.scrollTop(),left:r.scrollLeft()}),this.originalPosition&&(this.containment&&(this.relative_container?(s=this.relative_container.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),e.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),e.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,h=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s]),"drag"===e&&(this.positionAbs=this._convertPositionTo("absolute")),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i){var s=t(this).data("ui-draggable"),n=s.options,o=t.extend({},i,{item:s.element});s.sortables=[],t(n.connectToSortable).each(function(){var i=t.data(this,"ui-sortable");i&&!i.options.disabled&&(s.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",e,o))})},stop:function(e,i){var s=t(this).data("ui-draggable"),n=t.extend({},i,{item:s.element});t.each(s.sortables,function(){this.instance.isOver?(this.instance.isOver=0,s.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(e),this.instance.options.helper=this.instance.options._helper,"original"===s.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",e,n))})},drag:function(e,i){var s=t(this).data("ui-draggable"),n=this;t.each(s.sortables,function(){var o=!1,a=this;this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(o=!0,t.each(s.sortables,function(){return this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this!==a&&this.instance._intersectsWith(this.instance.containerCache)&&t.contains(a.instance.element[0],this.instance.element[0])&&(o=!1),o})),o?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=t(n).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},e.target=this.instance.currentItem[0],this.instance._mouseCapture(e,!0),this.instance._mouseStart(e,!0,!0),this.instance.offset.click.top=s.offset.click.top,this.instance.offset.click.left=s.offset.click.left,this.instance.offset.parent.left-=s.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=s.offset.parent.top-this.instance.offset.parent.top,s._trigger("toSortable",e),s.dropped=this.instance.element,s.currentItem=s.element,this.instance.fromOutside=s),this.instance.currentItem&&this.instance._mouseDrag(e)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",e,this.instance._uiHash(this.instance)),this.instance._mouseStop(e,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),s._trigger("fromSortable",e),s.dropped=!1)})}}),t.ui.plugin.add("draggable","cursor",{start:function(){var e=t("body"),i=t(this).data("ui-draggable").options;e.css("cursor")&&(i._cursor=e.css("cursor")),e.css("cursor",i.cursor)},stop:function(){var e=t(this).data("ui-draggable").options;e._cursor&&t("body").css("cursor",e._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("opacity")&&(n._opacity=s.css("opacity")),s.css("opacity",n.opacity)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._opacity&&t(i.helper).css("opacity",s._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(){var e=t(this).data("ui-draggable");e.scrollParent[0]!==document&&"HTML"!==e.scrollParent[0].tagName&&(e.overflowOffset=e.scrollParent.offset())},drag:function(e){var i=t(this).data("ui-draggable"),s=i.options,n=!1;i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-e.pageY<s.scrollSensitivity?i.scrollParent[0].scrollTop=n=i.scrollParent[0].scrollTop+s.scrollSpeed:e.pageY-i.overflowOffset.top<s.scrollSensitivity&&(i.scrollParent[0].scrollTop=n=i.scrollParent[0].scrollTop-s.scrollSpeed)),s.axis&&"y"===s.axis||(i.overflowOffset.left+i.scrollParent[0].offsetWidth-e.pageX<s.scrollSensitivity?i.scrollParent[0].scrollLeft=n=i.scrollParent[0].scrollLeft+s.scrollSpeed:e.pageX-i.overflowOffset.left<s.scrollSensitivity&&(i.scrollParent[0].scrollLeft=n=i.scrollParent[0].scrollLeft-s.scrollSpeed))):(s.axis&&"x"===s.axis||(e.pageY-t(document).scrollTop()<s.scrollSensitivity?n=t(document).scrollTop(t(document).scrollTop()-s.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<s.scrollSensitivity&&(n=t(document).scrollTop(t(document).scrollTop()+s.scrollSpeed))),s.axis&&"y"===s.axis||(e.pageX-t(document).scrollLeft()<s.scrollSensitivity?n=t(document).scrollLeft(t(document).scrollLeft()-s.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<s.scrollSensitivity&&(n=t(document).scrollLeft(t(document).scrollLeft()+s.scrollSpeed)))),n!==!1&&t.ui.ddmanager&&!s.dropBehaviour&&t.ui.ddmanager.prepareOffsets(i,e)}}),t.ui.plugin.add("draggable","snap",{start:function(){var e=t(this).data("ui-draggable"),i=e.options;e.snapElements=[],t(i.snap.constructor!==String?i.snap.items||":data(ui-draggable)":i.snap).each(function(){var i=t(this),s=i.offset();this!==e.element[0]&&e.snapElements.push({item:this,width:i.outerWidth(),height:i.outerHeight(),top:s.top,left:s.left})})},drag:function(e,i){var s,n,o,a,r,h,l,c,u,d,p=t(this).data("ui-draggable"),f=p.options,g=f.snapTolerance,m=i.offset.left,v=m+p.helperProportions.width,_=i.offset.top,b=_+p.helperProportions.height;for(u=p.snapElements.length-1;u>=0;u--)r=p.snapElements[u].left,h=r+p.snapElements[u].width,l=p.snapElements[u].top,c=l+p.snapElements[u].height,r-g>v||m>h+g||l-g>b||_>c+g||!t.contains(p.snapElements[u].item.ownerDocument,p.snapElements[u].item)?(p.snapElements[u].snapping&&p.options.snap.release&&p.options.snap.release.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=!1):("inner"!==f.snapMode&&(s=g>=Math.abs(l-b),n=g>=Math.abs(c-_),o=g>=Math.abs(r-v),a=g>=Math.abs(h-m),s&&(i.position.top=p._convertPositionTo("relative",{top:l-p.helperProportions.height,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c,left:0}).top-p.margins.top),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r-p.helperProportions.width}).left-p.margins.left),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h}).left-p.margins.left)),d=s||n||o||a,"outer"!==f.snapMode&&(s=g>=Math.abs(l-_),n=g>=Math.abs(c-b),o=g>=Math.abs(r-m),a=g>=Math.abs(h-v),s&&(i.position.top=p._convertPositionTo("relative",{top:l,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c-p.helperProportions.height,left:0}).top-p.margins.top),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r}).left-p.margins.left),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h-p.helperProportions.width}).left-p.margins.left)),!p.snapElements[u].snapping&&(s||n||o||a||d)&&p.options.snap.snap&&p.options.snap.snap.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=s||n||o||a||d)}}),t.ui.plugin.add("draggable","stack",{start:function(){var e,i=this.data("ui-draggable").options,s=t.makeArray(t(i.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});s.length&&(e=parseInt(t(s[0]).css("zIndex"),10)||0,t(s).each(function(i){t(this).css("zIndex",e+i)}),this.css("zIndex",e+s.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("zIndex")&&(n._zIndex=s.css("zIndex")),s.css("zIndex",n.zIndex)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._zIndex&&t(i.helper).css("zIndex",s._zIndex)}})}(jQuery),function(t){function e(t,e,i){return t>e&&e+i>t}t.widget("ui.droppable",{version:"1.10.3",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e=this.options,i=e.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(i)?i:function(t){return t.is(i)
},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},t.ui.ddmanager.droppables[e.scope]=t.ui.ddmanager.droppables[e.scope]||[],t.ui.ddmanager.droppables[e.scope].push(this),e.addClasses&&this.element.addClass("ui-droppable")},_destroy:function(){for(var e=0,i=t.ui.ddmanager.droppables[this.options.scope];i.length>e;e++)i[e]===this&&i.splice(e,1);this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(e,i){"accept"===e&&(this.accept=t.isFunction(i)?i:function(t){return t.is(i)}),t.Widget.prototype._setOption.apply(this,arguments)},_activate:function(e){var i=t.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var e=t.data(this,"ui-droppable");return e.options.greedy&&!e.options.disabled&&e.options.scope===s.options.scope&&e.accept.call(e.element[0],s.currentItem||s.element)&&t.ui.intersect(s,t.extend(e,{offset:e.element.offset()}),e.options.tolerance)?(n=!0,!1):undefined}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",e,this.ui(s)),this.element):!1):!1},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}}}),t.ui.intersect=function(t,i,s){if(!i.offset)return!1;var n,o,a=(t.positionAbs||t.position.absolute).left,r=a+t.helperProportions.width,h=(t.positionAbs||t.position.absolute).top,l=h+t.helperProportions.height,c=i.offset.left,u=c+i.proportions.width,d=i.offset.top,p=d+i.proportions.height;switch(s){case"fit":return a>=c&&u>=r&&h>=d&&p>=l;case"intersect":return a+t.helperProportions.width/2>c&&u>r-t.helperProportions.width/2&&h+t.helperProportions.height/2>d&&p>l-t.helperProportions.height/2;case"pointer":return n=(t.positionAbs||t.position.absolute).left+(t.clickOffset||t.offset.click).left,o=(t.positionAbs||t.position.absolute).top+(t.clickOffset||t.offset.click).top,e(o,d,i.proportions.height)&&e(n,c,i.proportions.width);case"touch":return(h>=d&&p>=h||l>=d&&p>=l||d>h&&l>p)&&(a>=c&&u>=a||r>=c&&u>=r||c>a&&r>u);default:return!1}},t.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,i){var s,n,o=t.ui.ddmanager.droppables[e.options.scope]||[],a=i?i.type:null,r=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;o.length>s;s++)if(!(o[s].options.disabled||e&&!o[s].accept.call(o[s].element[0],e.currentItem||e.element))){for(n=0;r.length>n;n++)if(r[n]===o[s].element[0]){o[s].proportions.height=0;continue t}o[s].visible="none"!==o[s].element.css("display"),o[s].visible&&("mousedown"===a&&o[s]._activate.call(o[s],i),o[s].offset=o[s].element.offset(),o[s].proportions={width:o[s].element[0].offsetWidth,height:o[s].element[0].offsetHeight})}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&t.ui.intersect(e,this,this.options.tolerance)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").bind("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,o,a=t.ui.intersect(e,this,this.options.tolerance),r=!a&&this.isover?"isout":a&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,o=this.element.parents(":data(ui-droppable)").filter(function(){return t.data(this,"ui-droppable").options.scope===n}),o.length&&(s=t.data(o[0],"ui-droppable"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").unbind("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}}}(jQuery),function(t){function e(t){return parseInt(t,10)||0}function i(t){return!isNaN(parseInt(t,10))}t.widget("ui.resizable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var e,i,s,n,o,a=this,r=this.options;if(this.element.addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),e=this.handles.split(","),this.handles={},i=0;e.length>i;i++)s=t.trim(e[i]),o="ui-resizable-"+s,n=t("<div class='ui-resizable-handle "+o+"'></div>"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=t(this.handles[i],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),t(this.handles[i]).length},this._renderAxis(this.element),this._handles=t(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){a.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),a.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),t(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(t(this).removeClass("ui-resizable-autohide"),a._handles.show())}).mouseleave(function(){r.disabled||a.resizing||(t(this).addClass("ui-resizable-autohide"),a._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(i){var s,n,o,a=this.options,r=this.element.position(),h=this.element;return this.resizing=!0,/absolute/.test(h.css("position"))?h.css({position:"absolute",top:h.css("top"),left:h.css("left")}):h.is(".ui-draggable")&&h.css({position:"absolute",top:r.top,left:r.left}),this._renderProxy(),s=e(this.helper.css("left")),n=e(this.helper.css("top")),a.containment&&(s+=t(a.containment).scrollLeft()||0,n+=t(a.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:s,top:n},this.size=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalSize=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalPosition={left:s,top:n},this.sizeDiff={width:h.outerWidth()-h.width(),height:h.outerHeight()-h.height()},this.originalMousePosition={left:i.pageX,top:i.pageY},this.aspectRatio="number"==typeof a.aspectRatio?a.aspectRatio:this.originalSize.width/this.originalSize.height||1,o=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===o?this.axis+"-resize":o),h.addClass("ui-resizable-resizing"),this._propagate("start",i),!0},_mouseDrag:function(e){var i,s=this.helper,n={},o=this.originalMousePosition,a=this.axis,r=this.position.top,h=this.position.left,l=this.size.width,c=this.size.height,u=e.pageX-o.left||0,d=e.pageY-o.top||0,p=this._change[a];return p?(i=p.apply(this,[e,u,d]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),this.position.top!==r&&(n.top=this.position.top+"px"),this.position.left!==h&&(n.left=this.position.left+"px"),this.size.width!==l&&(n.width=this.size.width+"px"),this.size.height!==c&&(n.height=this.size.height+"px"),s.css(n),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(n)||this._trigger("resize",e,this.ui()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&t.ui.hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null,h=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(t){var e,s,n,o,a,r=this.options;a={minWidth:i(r.minWidth)?r.minWidth:0,maxWidth:i(r.maxWidth)?r.maxWidth:1/0,minHeight:i(r.minHeight)?r.minHeight:0,maxHeight:i(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||t)&&(e=a.minHeight*this.aspectRatio,n=a.minWidth/this.aspectRatio,s=a.maxHeight*this.aspectRatio,o=a.maxWidth/this.aspectRatio,e>a.minWidth&&(a.minWidth=e),n>a.minHeight&&(a.minHeight=n),a.maxWidth>s&&(a.maxWidth=s),a.maxHeight>o&&(a.maxHeight=o)),this._vBoundaries=a},_updateCache:function(t){this.offset=this.helper.offset(),i(t.left)&&(this.position.left=t.left),i(t.top)&&(this.position.top=t.top),i(t.height)&&(this.size.height=t.height),i(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,s=this.size,n=this.axis;return i(t.height)?t.width=t.height*this.aspectRatio:i(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===n&&(t.left=e.left+(s.width-t.width),t.top=null),"nw"===n&&(t.top=e.top+(s.height-t.height),t.left=e.left+(s.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,s=this.axis,n=i(t.width)&&e.maxWidth&&e.maxWidth<t.width,o=i(t.height)&&e.maxHeight&&e.maxHeight<t.height,a=i(t.width)&&e.minWidth&&e.minWidth>t.width,r=i(t.height)&&e.minHeight&&e.minHeight>t.height,h=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,c=/sw|nw|w/.test(s),u=/nw|ne|n/.test(s);return a&&(t.width=e.minWidth),r&&(t.height=e.minHeight),n&&(t.width=e.maxWidth),o&&(t.height=e.maxHeight),a&&c&&(t.left=h-e.minWidth),n&&c&&(t.left=h-e.maxWidth),r&&u&&(t.top=l-e.minHeight),o&&u&&(t.top=l-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var t,e,i,s,n,o=this.helper||this.element;for(t=0;this._proportionallyResizeElements.length>t;t++){if(n=this._proportionallyResizeElements[t],!this.borderDif)for(this.borderDif=[],i=[n.css("borderTopWidth"),n.css("borderRightWidth"),n.css("borderBottomWidth"),n.css("borderLeftWidth")],s=[n.css("paddingTop"),n.css("paddingRight"),n.css("paddingBottom"),n.css("paddingLeft")],e=0;i.length>e;e++)this.borderDif[e]=(parseInt(i[e],10)||0)+(parseInt(s[e],10)||0);n.css({height:o.height()-this.borderDif[0]-this.borderDif[2]||0,width:o.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).data("ui-resizable"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&t.ui.hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,c=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var i,s,n,o,a,r,h,l=t(this).data("ui-resizable"),c=l.options,u=l.element,d=c.containment,p=d instanceof t?d.get(0):/parent/.test(d)?u.parent().get(0):d;p&&(l.containerElement=t(p),/document/.test(d)||d===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(i=t(p),s=[],t(["Top","Right","Left","Bottom"]).each(function(t,n){s[t]=e(i.css("padding"+n))}),l.containerOffset=i.offset(),l.containerPosition=i.position(),l.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},n=l.containerOffset,o=l.containerSize.height,a=l.containerSize.width,r=t.ui.hasScroll(p,"left")?p.scrollWidth:a,h=t.ui.hasScroll(p)?p.scrollHeight:o,l.parentData={element:p,left:n.left,top:n.top,width:r,height:h}))},resize:function(e){var i,s,n,o,a=t(this).data("ui-resizable"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio),a.position.top=a._helper?h.top:0),a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top,i=Math.abs((a._helper?a.offset.left-u.left:a.offset.left-u.left)+a.sizeDiff.width),s=Math.abs((a._helper?a.offset.top-u.top:a.offset.top-h.top)+a.sizeDiff.height),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o&&(i-=a.parentData.left),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio))},stop:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=function(e){t(e).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseInt(e.width(),10),height:parseInt(e.height(),10),left:parseInt(e.css("left"),10),top:parseInt(e.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):t.each(i.alsoResize,function(t){s(t)})},resize:function(e,i){var s=t(this).data("ui-resizable"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0},h=function(e,s){t(e).each(function(){var e=t(this),n=t(this).data("ui-resizable-alsoresize"),o={},a=s&&s.length?s:e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(a,function(t,e){var i=(n[e]||0)+(r[e]||0);i&&i>=0&&(o[e]=i||null)}),e.css(o)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):t.each(n.alsoResize,function(t,e){h(t,e)})},stop:function(){t(this).removeData("resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).data("ui-resizable");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).data("ui-resizable");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,a=e.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=r[0]||1,l=r[1]||1,c=Math.round((s.width-n.width)/h)*h,u=Math.round((s.height-n.height)/l)*l,d=n.width+c,p=n.height+u,f=i.maxWidth&&d>i.maxWidth,g=i.maxHeight&&p>i.maxHeight,m=i.minWidth&&i.minWidth>d,v=i.minHeight&&i.minHeight>p;i.grid=r,m&&(d+=h),v&&(p+=l),f&&(d-=h),g&&(p-=l),/^(se|s|e)$/.test(a)?(e.size.width=d,e.size.height=p):/^(ne)$/.test(a)?(e.size.width=d,e.size.height=p,e.position.top=o.top-u):/^(sw)$/.test(a)?(e.size.width=d,e.size.height=p,e.position.left=o.left-c):(e.size.width=d,e.size.height=p,e.position.top=o.top-u,e.position.left=o.left-c)}})}(jQuery),function(t){t.widget("ui.selectable",t.ui.mouse,{version:"1.10.3",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e,i=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e=t(i.options.filter,i.element[0]),e.addClass("ui-selectee"),e.each(function(){var e=t(this),i=e.offset();t.data(this,"selectable-item",{element:this,$element:e,left:i.left,top:i.top,right:i.left+e.outerWidth(),bottom:i.top+e.outerHeight(),startselected:!1,selected:e.hasClass("ui-selected"),selecting:e.hasClass("ui-selecting"),unselecting:e.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=e.addClass("ui-selectee"),this._mouseInit(),this.helper=t("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,n=t.data(this,"selectable-item");return n?(s=!e.metaKey&&!e.ctrlKey||!n.$element.hasClass("ui-selected"),n.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",e,{selecting:n.element}):i._trigger("unselecting",e,{unselecting:n.element}),!1):undefined}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,o=this.opos[0],a=this.opos[1],r=e.pageX,h=e.pageY;return o>r&&(i=r,r=o,o=i),a>h&&(i=h,h=a,a=i),this.helper.css({left:o,top:a,width:r-o,height:h-a}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1;i&&i.element!==s.element[0]&&("touch"===n.tolerance?l=!(i.left>r||o>i.right||i.top>h||a>i.bottom):"fit"===n.tolerance&&(l=i.left>o&&r>i.right&&i.top>a&&h>i.bottom),l?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}})}(jQuery),function(t){function e(t,e,i){return t>e&&e+i>t}function i(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))}t.widget("ui.sortable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var t=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===t.axis||i(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_setOption:function(e,i){"disabled"===e?(this.options[e]=i,this.widget().toggleClass("ui-sortable-disabled",!!i)):t.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):undefined}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("<style>*{ cursor: "+a.cursor+" !important; }</style>").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<a.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+a.scrollSpeed:e.pageY-this.overflowOffset.top<a.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-a.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<a.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+a.scrollSpeed:e.pageX-this.overflowOffset.left<a.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-a.scrollSpeed)):(e.pageY-t(document).scrollTop()<a.scrollSensitivity?r=t(document).scrollTop(t(document).scrollTop()-a.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<a.scrollSensitivity&&(r=t(document).scrollTop(t(document).scrollTop()+a.scrollSpeed)),e.pageX-t(document).scrollLeft()<a.scrollSensitivity?r=t(document).scrollLeft(t(document).scrollLeft()-a.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<a.scrollSensitivity&&(r=t(document).scrollLeft(t(document).scrollLeft()+a.scrollSpeed))),r!==!1&&t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;
this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var i="x"===this.options.axis||e(this.positionAbs.top+this.offset.click.top,t.top,t.height),s="y"===this.options.axis||e(this.positionAbs.left+this.offset.click.left,t.left,t.width),n=i&&s,o=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return n?this.floating?a&&"right"===a||"down"===o?2:1:o&&("down"===o?2:1):!1},_intersectsWithSides:function(t){var i=e(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),s=e(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),n=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return this.floating&&o?"right"===o&&s||"left"===o&&!s:n&&("down"===n&&i||"up"===n&&!i)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){var i,s,n,o,a=[],r=[],h=this._connectWith();if(h&&e)for(i=h.length-1;i>=0;i--)for(n=t(h[i]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&r.push([t.isFunction(o.options.items)?o.options.items.call(o.element):t(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);for(r.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),i=r.length-1;i>=0;i--)r[i][0].each(function(){a.push(this)});return t(a)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]).addClass(i||e.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?e.currentItem.children().each(function(){t("<td>&#160;</td>",e.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(n)}):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_contactContainers:function(s){var n,o,a,r,h,l,c,u,d,p,f=null,g=null;for(n=this.containers.length-1;n>=0;n--)if(!t.contains(this.currentItem[0],this.containers[n].element[0]))if(this._intersectsWith(this.containers[n].containerCache)){if(f&&t.contains(this.containers[n].element[0],f.element[0]))continue;f=this.containers[n],g=n}else this.containers[n].containerCache.over&&(this.containers[n]._trigger("out",s,this._uiHash(this)),this.containers[n].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[g].containerCache.over||(this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1);else{for(a=1e4,r=null,p=f.floating||i(this.currentItem),h=p?"left":"top",l=p?"width":"height",c=this.positionAbs[h]+this.offset.click[h],o=this.items.length-1;o>=0;o--)t.contains(this.containers[g].element[0],this.items[o].item[0])&&this.items[o].item[0]!==this.currentItem[0]&&(!p||e(this.positionAbs.top+this.offset.click.top,this.items[o].top,this.items[o].height))&&(u=this.items[o].item.offset()[h],d=!1,Math.abs(u-c)>Math.abs(u+this.items[o][l]-c)&&(d=!0,u+=this.items[o][l]),a>Math.abs(u-c)&&(a=Math.abs(u-c),r=this.items[o],this.direction=d?"up":"down"));if(!r&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[g])return;r?this._rearrange(s,r,null,!0):this._rearrange(s,null,this.containers[g].element,!0),this._trigger("change",s,this._uiHash()),this.containers[g]._trigger("change",s,this._uiHash(this)),this.currentContainer=this.containers[g],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,t("document"===n.containment?document:window).width()-this.helperProportions.width-this.margins.left,(t("document"===n.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(o=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(a=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)("auto"===this._storedCSS[i]||"static"===this._storedCSS[i])&&(this._storedCSS[i]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;i>=0;i--)e||s.push(function(t){return function(e){t._trigger("deactivate",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(function(t){return function(e){t._trigger("out",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!e){for(this._trigger("beforeStop",t,this._uiHash()),i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}if(e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!e){for(i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}})}(jQuery),function(t,e){var i="ui-effects-";t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,o){var a,r=o.re.exec(i),h=r&&o.parse(r),l=o.space||"rgba";return h?(a=s[l](h),s[c[l].cache]=a[c[l].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("<p>")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),l.fn=t.extend(l.prototype,{parse:function(n,a,r,h){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,h],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof l?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=l(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=l(t),n=s._space(),o=c[n],a=0===this.alpha()?l("transparent"):this,r=a[o.cache]||o.to(a._rgba),h=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],l=s[o],c=u[n.type]||{};null!==l&&(null===a?h[o]=l:(c.mod&&(l-a>c.mod/2?a+=c.mod:a-l>c.mod/2&&(a-=c.mod)),h[o]=i((l-a)*e+a,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),h=Math.min(s,n,o),l=r-h,c=r+h,u=.5*c;return e=h===r?0:s===r?60*(n-o)/l+360:n===r?60*(o-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=u?l/c:l/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,h=n.to,c=n.from;l.fn[s]=function(s){if(h&&!this[a]&&(this[a]=h(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=l(c(d)),n[a]=d,n):l(d)},f(o,function(e,i){l.fn[e]||(l.fn[e]=function(n){var o,a=t.type(n),h="alpha"===e?this._hsla?"hsla":"rgba":s,l=this[h](),c=l[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=l(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(h){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=l(e.elem,i),e.end=l(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},l.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function s(e,i){var s,n,a={};for(s in i)n=i[s],e[s]!==n&&(o[s]||(t.fx.step[s]||!isNaN(parseFloat(n)))&&(a[s]=n));return a}var n=["add","remove","toggle"],o={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(jQuery.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(e,o,a,r){var h=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",l=h.children?a.find("*").addBack():a;l=l.map(function(){var e=t(this);return{el:e,start:i(this)}}),o=function(){t.each(n,function(t,i){e[i]&&a[i+"Class"](e[i])})},o(),l=l.map(function(){return this.end=i(this.el[0]),this.diff=s(this.start,this.end),this}),a.attr("class",r),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(i){return function(s,n,o,a,r){return"boolean"==typeof n||n===e?o?t.effects.animateClass.call(this,n?{add:s}:{remove:s},o,a,r):i.apply(this,arguments):t.effects.animateClass.call(this,{toggle:s},n,o,a)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function s(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function n(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}t.extend(t.effects,{version:"1.10.3",save:function(t,e){for(var s=0;e.length>s;s++)null!==e[s]&&t.data(i+e[s],t[0].style[e[s]])},restore:function(t,s){var n,o;for(o=0;s.length>o;o++)null!==s[o]&&(n=t.data(i+s[o]),n===e&&(n=""),t.css(s[o],n))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).focus(),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).focus()),e},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function e(e){function s(){t.isFunction(o)&&o.call(n[0]),t.isFunction(e)&&e()}var n=t(this),o=i.complete,r=i.mode;(n.is(":hidden")?"hide"===r:"show"===r)?(n[r](),s()):a.call(n[0],i,s)}var i=s.apply(this,arguments),n=i.mode,o=i.queue,a=t.effects.effect[i.effect];return t.fx.off||!a?n?this[n](i.duration,i.complete):this.each(function(){i.complete&&i.complete.call(this)}):o===!1?this.each(e):this.queue(o||"fx",e)},show:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="show",this.effect.call(this,i)}}(t.fn.show),hide:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="hide",this.effect.call(this,i)}}(t.fn.hide),toggle:function(t){return function(e){if(n(e)||"boolean"==typeof e)return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="toggle",this.effect.call(this,i)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s}})}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}()}(jQuery),function(t){var e=0,i={},s={};i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="hide",s.height=s.paddingTop=s.paddingBottom=s.borderTopWidth=s.borderBottomWidth="show",t.widget("ui.accordion",{version:"1.10.3",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t(),content:this.active.length?this.active.next():t()}},_createIcons:function(){var e=this.options.icons;e&&(t("<span>").addClass("ui-accordion-header-icon ui-icon "+e.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(e.header).addClass(e.activeHeader),this.headers.addClass("ui-accordion-icons"))
},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),undefined):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),"disabled"===t&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!e),undefined)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),o.focus(),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().focus()},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var i,s=this.options,n=s.heightStyle,o=this.element.parent(),a=this.accordionId="ui-accordion-"+(this.element.attr("id")||++e);this.active=this._findActive(s.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(e){var i=t(this),s=i.attr("id"),n=i.next(),o=n.attr("id");s||(s=a+"-header-"+e,i.attr("id",s)),o||(o=a+"-panel-"+e,n.attr("id",o)),i.attr("aria-controls",o),n.attr("aria-labelledby",s)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(s.event),"fill"===n?(i=o.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.headers.each(function(){i-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===n&&(i=0,this.headers.next().each(function(){i=Math.max(i,t(this).css("height","").height())}).height(i))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n[0]===s[0],a=o&&i.collapsible,r=a?t():n.next(),h=s.next(),l={oldHeader:s,oldPanel:h,newHeader:a?t():n,newPanel:r};e.preventDefault(),o&&!i.collapsible||this._trigger("beforeActivate",e,l)===!1||(i.active=a?!1:this.headers.index(n),this.active=o?t():n,this._toggle(l),s.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),o||(n.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&n.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),n.next().addClass("ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-expanded":"false","aria-hidden":"true"}),s.prev().attr("aria-selected","false"),i.length&&s.length?s.prev().attr("tabIndex",-1):i.length&&this.headers.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(t,e,n){var o,a,r,h=this,l=0,c=t.length&&(!e.length||t.index()<e.index()),u=this.options.animate||{},d=c&&u.down||u,p=function(){h._toggleComplete(n)};return"number"==typeof d&&(r=d),"string"==typeof d&&(a=d),a=a||d.easing||u.easing,r=r||d.duration||u.duration,e.length?t.length?(o=t.show().outerHeight(),e.animate(i,{duration:r,easing:a,step:function(t,e){e.now=Math.round(t)}}),t.hide().animate(s,{duration:r,easing:a,complete:p,step:function(t,i){i.now=Math.round(t),"height"!==i.prop?l+=i.now:"content"!==h.options.heightStyle&&(i.now=Math.round(o-e.outerHeight()-l),l=0)}}),undefined):e.animate(i,r,a,p):t.animate(s,r,a,p)},_toggleComplete:function(t){var e=t.oldPanel;e.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),e.length&&(e.parent()[0].className=e.parent()[0].className),this._trigger("activate",null,t)}})}(jQuery),function(t){var e=0;t.widget("ui.autocomplete",{version:"1.10.3",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;this.isMultiLine=o?!0:a?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,undefined;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:case o.NUMPAD_ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),undefined;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),undefined):(this._searchTimeout(t),undefined)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,undefined):(clearTimeout(this.searching),this.close(t),this._change(t),undefined)}}),this._initSource(),this.menu=t("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().data("ui-menu"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];t(e.target).closest(".ui-menu-item").length||this._delay(function(){var e=this;this.document.one("mousedown",function(s){s.target===e.element[0]||s.target===i||t.contains(i,s.target)||e.close()})})},menufocus:function(e,i){if(this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type)))return this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),undefined;var s=i.item.data("ui-autocomplete-item");!1!==this._trigger("focus",e,{item:s})?e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(s.value):this.liveRegion.text(s.value)},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=t("<span>",{role:"status","aria-live":"polite"}).addClass("ui-helper-hidden-accessible").insertBefore(this.element),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e||(e=this.element.closest(".ui-front")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){this.term!==this._value()&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length<this.options.minLength?this.close(e):this._trigger("search",e)!==!1?this._search(t):undefined},_search:function(t){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:t},this._response())},_response:function(){var t=this,i=++e;return function(s){i===e&&t.__response(s),t.pending--,t.pending||t.element.removeClass("ui-autocomplete-loading")}},__response:function(t){t&&(t=this._normalize(t)),this._trigger("response",null,{content:t}),!this.options.disabled&&t&&t.length&&!this.cancelSearch?(this._suggest(t),this._trigger("open")):this._close()},close:function(t){this.cancelSearch=!0,this._close(t)},_close:function(t){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",t))},_change:function(t){this.previous!==this._value()&&this._trigger("change",t,{item:this.selectedItem})},_normalize:function(e){return e.length&&e[0].label&&e[0].value?e:t.map(e,function(e){return"string"==typeof e?{label:e,value:e}:t.extend({label:e.label||e.value,value:e.value||e.label},e)})},_suggest:function(e){var i=this.menu.element.empty();this._renderMenu(i,e),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(t.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var t=this.menu.element;t.outerWidth(Math.max(t.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(e,i){var s=this;t.each(i,function(t,i){s._renderItemData(e,i)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-autocomplete-item",e)},_renderItem:function(e,i){return t("<li>").append(t("<a>").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this._value(this.term),this.menu.blur(),undefined):(this.menu[t](e),undefined):(this.search(null,e),undefined)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(t){var e;this._superApply(arguments),this.options.disabled||this.cancelSearch||(e=t&&t.length?this.options.messages.results(t.length):this.options.messages.noResults,this.liveRegion.text(e))}})}(jQuery),function(t){var e,i,s,n,o="ui-button ui-widget ui-state-default ui-corner-all",a="ui-state-hover ui-state-active ",r="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",h=function(){var e=t(this);setTimeout(function(){e.find(":ui-button").button("refresh")},1)},l=function(e){var i=e.name,s=e.form,n=t([]);return i&&(i=i.replace(/'/g,"\\'"),n=s?t(s).find("[name='"+i+"']"):t("[name='"+i+"']",e.ownerDocument).filter(function(){return!this.form})),n};t.widget("ui.button",{version:"1.10.3",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,h),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var a=this,r=this.options,c="checkbox"===this.type||"radio"===this.type,u=c?"":"ui-state-active",d="ui-state-focus";null===r.label&&(r.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(o).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){r.disabled||this===e&&t(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){r.disabled||t(this).removeClass(u)}).bind("click"+this.eventNamespace,function(t){r.disabled&&(t.preventDefault(),t.stopImmediatePropagation())}),this.element.bind("focus"+this.eventNamespace,function(){a.buttonElement.addClass(d)}).bind("blur"+this.eventNamespace,function(){a.buttonElement.removeClass(d)}),c&&(this.element.bind("change"+this.eventNamespace,function(){n||a.refresh()}),this.buttonElement.bind("mousedown"+this.eventNamespace,function(t){r.disabled||(n=!1,i=t.pageX,s=t.pageY)}).bind("mouseup"+this.eventNamespace,function(t){r.disabled||(i!==t.pageX||s!==t.pageY)&&(n=!0)})),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return r.disabled||n?!1:undefined}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(r.disabled||n)return!1;t(this).addClass("ui-state-active"),a.buttonElement.attr("aria-pressed","true");var e=a.element[0];l(e).not(e).map(function(){return t(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return r.disabled?!1:(t(this).addClass("ui-state-active"),e=this,a.document.one("mouseup",function(){e=null}),undefined)}).bind("mouseup"+this.eventNamespace,function(){return r.disabled?!1:(t(this).removeClass("ui-state-active"),undefined)}).bind("keydown"+this.eventNamespace,function(e){return r.disabled?!1:((e.keyCode===t.ui.keyCode.SPACE||e.keyCode===t.ui.keyCode.ENTER)&&t(this).addClass("ui-state-active"),undefined)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){t(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(e){e.keyCode===t.ui.keyCode.SPACE&&t(this).click()})),this._setOption("disabled",r.disabled),this._resetButton()},_determineButtonType:function(){var t,e,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(t=this.element.parents().last(),e="label[for='"+this.element.attr("id")+"']",this.buttonElement=t.find(e),this.buttonElement.length||(t=t.length?t.siblings():this.element.siblings(),this.buttonElement=t.filter(e),this.buttonElement.length||(this.buttonElement=t.find(e))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(o+" "+a+" "+r).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(t,e){return this._super(t,e),"disabled"===t?(e?this.element.prop("disabled",!0):this.element.prop("disabled",!1),undefined):(this._resetButton(),undefined)},refresh:function(){var e=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");e!==this.options.disabled&&this._setOption("disabled",e),"radio"===this.type?l(this.element[0]).each(function(){t(this).is(":checked")?t(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):t(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),undefined;var e=this.buttonElement.removeClass(r),i=t("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(e.empty()).text(),s=this.options.icons,n=s.primary&&s.secondary,o=[];s.primary||s.secondary?(this.options.text&&o.push("ui-button-text-icon"+(n?"s":s.primary?"-primary":"-secondary")),s.primary&&e.prepend("<span class='ui-button-icon-primary ui-icon "+s.primary+"'></span>"),s.secondary&&e.append("<span class='ui-button-icon-secondary ui-icon "+s.secondary+"'></span>"),this.options.text||(o.push(n?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||e.attr("title",t.trim(i)))):o.push("ui-button-text-only"),e.addClass(o.join(" "))}}),t.widget("ui.buttonset",{version:"1.10.3",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(t,e){"disabled"===t&&this.buttons.button("option",t,e),this._super(t,e)},refresh:function(){var e="rtl"===this.element.css("direction");this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return t(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(e?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(e?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return t(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}})}(jQuery),function(t,e){function i(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.dpDiv=s(t("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function s(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.delegate(i,"mouseout",function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",function(){t.datepicker._isDisabledDatepicker(o.inline?e.parent()[0]:o.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))})}function n(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}t.extend(t.ui,{datepicker:{version:"1.10.3"}});var o,a="datepicker";t.extend(i.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(t){return n(this._defaults,t||{}),this},_attachDatepicker:function(e,i){var s,n,o;s=e.nodeName.toLowerCase(),n="div"===s||"span"===s,e.id||(this.uuid+=1,e.id="dp"+this.uuid),o=this._newInst(t(e),n),o.settings=t.extend({},i||{}),"input"===s?this._connectDatepicker(e,o):n&&this._inlineDatepicker(e,o)},_newInst:function(e,i){var n=e[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:n,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?s(t("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(e,i){var s=t(e);i.append=t([]),i.trigger=t([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),t.data(e,a,i),i.settings.disabled&&this._disableDatepicker(e))},_attachments:function(e,i){var s,n,o,a=this._get(i,"appendText"),r=this._get(i,"isRTL");i.append&&i.append.remove(),a&&(i.append=t("<span class='"+this._appendClass+"'>"+a+"</span>"),e[r?"before":"after"](i.append)),e.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&e.focus(this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),o=this._get(i,"buttonImage"),i.trigger=t(this._get(i,"buttonImageOnly")?t("<img/>").addClass(this._triggerClass).attr({src:o,alt:n,title:n}):t("<button type='button'></button>").addClass(this._triggerClass).html(o?t("<img/>").attr({src:o,alt:n,title:n}):n)),e[r?"before":"after"](i.trigger),i.trigger.click(function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,o=new Date(2009,11,20),a=this._get(t,"dateFormat");a.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},o.setMonth(e(this._get(t,a.match(/MM/)?"monthNames":"monthNamesShort"))),o.setDate(e(this._get(t,a.match(/DD/)?"dayNames":"dayNamesShort"))+20-o.getDay())),t.input.attr("size",this._formatDate(t,o).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,a,i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,o,r){var h,l,c,u,d,p=this._dialogInst;return p||(this.uuid+=1,h="dp"+this.uuid,this._dialogInput=t("<input type='text' id='"+h+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),t("body").append(this._dialogInput),p=this._dialogInst=this._newInst(this._dialogInput,!1),p.settings={},t.data(this._dialogInput[0],a,p)),n(p.settings,o||{}),i=i&&i.constructor===Date?this._formatDate(p,i):i,this._dialogInput.val(i),this._pos=r?r.length?r:[r.pageX,r.pageY]:null,this._pos||(l=document.documentElement.clientWidth,c=document.documentElement.clientHeight,u=document.documentElement.scrollLeft||document.body.scrollLeft,d=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[l/2-100+u,c/2-150+d]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),p.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],a,p),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,a);s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,a),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty())},_enableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,a);n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,o.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,a);n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,o.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,a)}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(i,s,o){var a,r,h,l,c=this._getInst(i);return 2===arguments.length&&"string"==typeof s?"defaults"===s?t.extend({},t.datepicker._defaults):c?"all"===s?t.extend({},c.settings):this._get(c,s):null:(a=s||{},"string"==typeof s&&(a={},a[s]=o),c&&(this._curInst===c&&this._hideDatepicker(),r=this._getDateDatepicker(i,!0),h=this._getMinMaxDate(c,"min"),l=this._getMinMaxDate(c,"max"),n(c.settings,a),null!==h&&a.dateFormat!==e&&a.minDate===e&&(c.settings.minDate=this._formatDate(c,h)),null!==l&&a.dateFormat!==e&&a.maxDate===e&&(c.settings.maxDate=this._formatDate(c,l)),"disabled"in a&&(a.disabled?this._disableDatepicker(i):this._enableDatepicker(i)),this._attachments(t(i),c),this._autoSize(c),this._setDate(c,r),this._updateAlternate(c),this._updateDatepicker(c)),e)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,o=t.datepicker._getInst(e.target),a=!0,r=o.dpDiv.is(".ui-datepicker-rtl");if(o._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),a=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",o.dpDiv),n[0]&&t.datepicker._selectDay(e.target,o.selectedMonth,o.selectedYear,n[0]),i=t.datepicker._get(o,"onSelect"),i?(s=t.datepicker._formatDate(o),i.apply(o.input?o.input[0]:null,[s,o])):t.datepicker._hideDatepicker(),!1;
case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),a=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),a=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?1:-1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),a=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?-1:1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),a=e.ctrlKey||e.metaKey;break;default:a=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):a=!1;a&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(i){var s,n,o=t.datepicker._getInst(i.target);return t.datepicker._get(o,"constrainInput")?(s=t.datepicker._possibleChars(t.datepicker._get(o,"dateFormat")),n=String.fromCharCode(null==i.charCode?i.keyCode:i.charCode),i.ctrlKey||i.metaKey||" ">n||!s||s.indexOf(n)>-1):e},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var i,s,o,a,r,h,l;i=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==i&&(t.datepicker._curInst.dpDiv.stop(!0,!0),i&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),s=t.datepicker._get(i,"beforeShow"),o=s?s.apply(e,[e,i]):{},o!==!1&&(n(i.settings,o),i.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(i),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),a=!1,t(e).parents().each(function(){return a|="fixed"===t(this).css("position"),!a}),r={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(i),r=t.datepicker._checkOffset(i,r,a),i.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":a?"fixed":"absolute",display:"none",left:r.left+"px",top:r.top+"px"}),i.inline||(h=t.datepicker._get(i,"showAnim"),l=t.datepicker._get(i,"duration"),i.dpDiv.zIndex(t(e).zIndex()+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[h]?i.dpDiv.show(h,t.datepicker._get(i,"showOptions"),l):i.dpDiv[h||"show"](h?l:null),t.datepicker._shouldFocusInput(i)&&i.input.focus(),t.datepicker._curInst=i))}},_updateDatepicker:function(e){this.maxRows=4,o=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var i,s=this._getNumberOfMonths(e),n=s[1],a=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&t.datepicker._shouldFocusInput(e)&&e.input.focus(),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),o=e.dpDiv.outerHeight(),a=e.input?e.input.outerWidth():0,r=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-a:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+r?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+o>l&&l>o?Math.abs(o+r):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,o,r=this._curInst;!r||e&&r!==t.data(e,a)||this._datepickerShowing&&(i=this._get(r,"showAnim"),s=this._get(r,"duration"),n=function(){t.datepicker._tidyDialog(r)},t.effects&&(t.effects.effect[i]||t.effects[i])?r.dpDiv.hide(i,t.datepicker._get(r,"showOptions"),s,n):r.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,o=this._get(r,"onClose"),o&&o.apply(r.input?r.input[0]:null,[r.input?r.input.val():"",r]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),o=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(o,i+("M"===s?this._get(o,"showCurrentAtPos"):0),s),this._updateDatepicker(o))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),o=this._getInst(n[0]);o["selected"+("M"===s?"Month":"Year")]=o["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(o),this._adjustDate(n)},_selectDay:function(e,i,s,n){var o,a=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(a[0])||(o=this._getInst(a[0]),o.selectedDay=o.currentDay=t("a",n).html(),o.selectedMonth=o.currentMonth=i,o.selectedYear=o.currentYear=s,this._selectDate(e,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),o=this._getInst(n[0]);i=null!=i?i:this._formatDate(o),o.input&&o.input.val(i),this._updateAlternate(o),s=this._get(o,"onSelect"),s?s.apply(o.input?o.input[0]:null,[i,o]):o.input&&o.input.trigger("change"),o.inline?this._updateDatepicker(o):(this._hideDatepicker(),this._lastInput=o.input[0],"object"!=typeof o.input[0]&&o.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,o=this._get(e,"altField");o&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(o).each(function(){t(this).val(n)}))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(i,s,n){if(null==i||null==s)throw"Invalid arguments";if(s="object"==typeof s?""+s:s+"",""===s)return null;var o,a,r,h,l=0,c=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff,u="string"!=typeof c?c:(new Date).getFullYear()%100+parseInt(c,10),d=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,p=(n?n.dayNames:null)||this._defaults.dayNames,f=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,g=(n?n.monthNames:null)||this._defaults.monthNames,m=-1,v=-1,_=-1,b=-1,y=!1,w=function(t){var e=i.length>o+1&&i.charAt(o+1)===t;return e&&o++,e},k=function(t){var e=w(t),i="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n=RegExp("^\\d{1,"+i+"}"),o=s.substring(l).match(n);if(!o)throw"Missing number at position "+l;return l+=o[0].length,parseInt(o[0],10)},x=function(i,n,o){var a=-1,r=t.map(w(i)?o:n,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(r,function(t,i){var n=i[1];return s.substr(l,n.length).toLowerCase()===n.toLowerCase()?(a=i[0],l+=n.length,!1):e}),-1!==a)return a+1;throw"Unknown name at position "+l},D=function(){if(s.charAt(l)!==i.charAt(o))throw"Unexpected literal at position "+l;l++};for(o=0;i.length>o;o++)if(y)"'"!==i.charAt(o)||w("'")?D():y=!1;else switch(i.charAt(o)){case"d":_=k("d");break;case"D":x("D",d,p);break;case"o":b=k("o");break;case"m":v=k("m");break;case"M":v=x("M",f,g);break;case"y":m=k("y");break;case"@":h=new Date(k("@")),m=h.getFullYear(),v=h.getMonth()+1,_=h.getDate();break;case"!":h=new Date((k("!")-this._ticksTo1970)/1e4),m=h.getFullYear(),v=h.getMonth()+1,_=h.getDate();break;case"'":w("'")?D():y=!0;break;default:D()}if(s.length>l&&(r=s.substr(l),!/^\s+/.test(r)))throw"Extra/unparsed characters found in date: "+r;if(-1===m?m=(new Date).getFullYear():100>m&&(m+=(new Date).getFullYear()-(new Date).getFullYear()%100+(u>=m?0:-100)),b>-1)for(v=1,_=b;;){if(a=this._getDaysInMonth(m,v-1),a>=_)break;v++,_-=a}if(h=this._daylightSavingAdjust(new Date(m,v-1,_)),h.getFullYear()!==m||h.getMonth()+1!==v||h.getDate()!==_)throw"Invalid date";return h},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,o=(i?i.dayNames:null)||this._defaults.dayNames,a=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,o);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),a,r);break;case"y":u+=h("y")?e.getFullYear():(10>e.getYear()%100?"0":"")+e.getYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,i){return t.settings[i]!==e?t.settings[i]:this._defaults[i]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),o=n,a=this._getFormatConfig(t);try{o=this.parseDate(i,s,a)||n}catch(r){s=e?"":s}t.selectedDay=o.getDate(),t.drawMonth=t.selectedMonth=o.getMonth(),t.drawYear=t.selectedYear=o.getFullYear(),t.currentDay=s?o.getDate():0,t.currentMonth=s?o.getMonth():0,t.currentYear=s?o.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},o=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,o=n.getFullYear(),a=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":a+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a));break;case"y":case"Y":o+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a))}l=h.exec(i)}return new Date(o,a,r)},a=null==i||""===i?s:"string"==typeof i?o(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return a=a&&"Invalid Date"==""+a?s:a,a&&(a.setHours(0),a.setMinutes(0),a.setSeconds(0),a.setMilliseconds(0)),this._daylightSavingAdjust(a)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,o=t.selectedYear,a=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=a.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=a.getMonth(),t.drawYear=t.selectedYear=t.currentYear=a.getFullYear(),n===t.selectedMonth&&o===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){t.datepicker._adjustDate(s,-i,"M")},next:function(){t.datepicker._adjustDate(s,+i,"M")},hide:function(){t.datepicker._hideDatepicker()},today:function(){t.datepicker._gotoToday(s)},selectDay:function(){return t.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return t.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return t.datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,o,a,r,h,l,c,u,d,p,f,g,m,v,_,b,y,w,k,x,D,C,I,P,T,M,S,z,A,H,E,N,W,O,F,R,L=new Date,j=this._daylightSavingAdjust(new Date(L.getFullYear(),L.getMonth(),L.getDate())),Y=this._get(t,"isRTL"),B=this._get(t,"showButtonPanel"),V=this._get(t,"hideIfNoPrevNext"),K=this._get(t,"navigationAsDateFormat"),U=this._getNumberOfMonths(t),q=this._get(t,"showCurrentAtPos"),Q=this._get(t,"stepMonths"),X=1!==U[0]||1!==U[1],$=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),G=this._getMinMaxDate(t,"min"),J=this._getMinMaxDate(t,"max"),Z=t.drawMonth-q,te=t.drawYear;if(0>Z&&(Z+=12,te--),J)for(e=this._daylightSavingAdjust(new Date(J.getFullYear(),J.getMonth()-U[0]*U[1]+1,J.getDate())),e=G&&G>e?G:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=K?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-Q,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":V?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(t,"nextText"),n=K?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+Q,1)),this._getFormatConfig(t)):n,o=this._canAdjustMonth(t,1,te,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":V?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",a=this._get(t,"currentText"),r=this._get(t,"gotoCurrent")&&t.currentDay?$:j,a=K?this.formatDate(a,r,this._getFormatConfig(t)):a,h=t.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(t,"closeText")+"</button>",l=B?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(t,r)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+a+"</button>":"")+(Y?"":h)+"</div>":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),g=this._get(t,"monthNamesShort"),m=this._get(t,"beforeShowDay"),v=this._get(t,"showOtherMonths"),_=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;U[0]>k;k++){for(x="",this.maxRows=4,D=0;U[1]>D;D++){if(C=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),I=" ui-corner-all",P="",X){if(P+="<div class='ui-datepicker-group",U[1]>1)switch(D){case 0:P+=" ui-datepicker-group-first",I=" ui-corner-"+(Y?"right":"left");break;case U[1]-1:P+=" ui-datepicker-group-last",I=" ui-corner-"+(Y?"left":"right");break;default:P+=" ui-datepicker-group-middle",I=""}P+="'>"}for(P+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+I+"'>"+(/all|left/.test(I)&&0===k?Y?o:s:"")+(/all|right/.test(I)&&0===k?Y?s:o:"")+this._generateMonthYearHeader(t,Z,te,G,J,k>0||D>0,f,g)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",T=u?"<th class='ui-datepicker-week-col'>"+this._get(t,"weekHeader")+"</th>":"",w=0;7>w;w++)M=(w+c)%7,T+="<th"+((w+c+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+d[M]+"'>"+p[M]+"</span></th>";for(P+=T+"</tr></thead><tbody>",S=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,S)),z=(this._getFirstDayOfMonth(te,Z)-c+7)%7,A=Math.ceil((z+S)/7),H=X?this.maxRows>A?this.maxRows:A:A,this.maxRows=H,E=this._daylightSavingAdjust(new Date(te,Z,1-z)),N=0;H>N;N++){for(P+="<tr>",W=u?"<td class='ui-datepicker-week-col'>"+this._get(t,"calculateWeek")(E)+"</td>":"",w=0;7>w;w++)O=m?m.apply(t.input?t.input[0]:null,[E]):[!0,""],F=E.getMonth()!==Z,R=F&&!_||!O[0]||G&&G>E||J&&E>J,W+="<td class='"+((w+c+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(E.getTime()===C.getTime()&&Z===t.selectedMonth&&t._keyEvent||b.getTime()===E.getTime()&&b.getTime()===C.getTime()?" "+this._dayOverClass:"")+(R?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!v?"":" "+O[1]+(E.getTime()===$.getTime()?" "+this._currentClass:"")+(E.getTime()===j.getTime()?" ui-datepicker-today":""))+"'"+(F&&!v||!O[2]?"":" title='"+O[2].replace(/'/g,"&#39;")+"'")+(R?"":" data-handler='selectDay' data-event='click' data-month='"+E.getMonth()+"' data-year='"+E.getFullYear()+"'")+">"+(F&&!v?"&#xa0;":R?"<span class='ui-state-default'>"+E.getDate()+"</span>":"<a class='ui-state-default"+(E.getTime()===j.getTime()?" ui-state-highlight":"")+(E.getTime()===$.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+"' href='#'>"+E.getDate()+"</a>")+"</td>",E.setDate(E.getDate()+1),E=this._daylightSavingAdjust(E);P+=W+"</tr>"}Z++,Z>11&&(Z=0,te++),P+="</tbody></table>"+(X?"</div>"+(U[0]>0&&D===U[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),x+=P}y+=x}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var h,l,c,u,d,p,f,g,m=this._get(t,"changeMonth"),v=this._get(t,"changeYear"),_=this._get(t,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",y="";if(o||!m)y+="<span class='ui-datepicker-month'>"+a[e]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",c=0;12>c;c++)(!h||c>=s.getMonth())&&(!l||n.getMonth()>=c)&&(y+="<option value='"+c+"'"+(c===e?" selected='selected'":"")+">"+r[c]+"</option>");y+="</select>"}if(_||(b+=y+(!o&&m&&v?"":"&#xa0;")),!t.yearshtml)if(t.yearshtml="",o||!v)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);return isNaN(e)?d:e},f=p(u[0]),g=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,g=n?Math.min(g,n.getFullYear()):g,t.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";g>=f;f++)t.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";t.yearshtml+="</select>",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),_&&(b+=(!o&&m&&v?"":"&#xa0;")+y),b+="</div>"},_adjustInstDate:function(t,e,i){var s=t.drawYear+("Y"===i?e:0),n=t.drawMonth+("M"===i?e:0),o=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),a=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,o)));t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),o=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&o.setDate(this._getDaysInMonth(o.getFullYear(),o.getMonth())),this._isInRange(t,o)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),o=this._getMinMaxDate(t,"max"),a=null,r=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),a=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(a+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||e.getTime()>=n.getTime())&&(!o||e.getTime()<=o.getTime())&&(!a||e.getFullYear()>=a)&&(!r||r>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).mousedown(t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new i,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.10.3"}(jQuery),function(t){var e={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};t.widget("ui.dialog",{version:"1.10.3",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:t.noop,enable:t.noop,close:function(e){var i=this;this._isOpen&&this._trigger("beforeClose",e)!==!1&&(this._isOpen=!1,this._destroyOverlay(),this.opener.filter(":focusable").focus().length||t(this.document[0].activeElement).blur(),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,e){var i=!!this.uiDialog.nextAll(":visible").insertBefore(this.uiDialog).length;return i&&!e&&this._trigger("focus",t),i},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),undefined):(this._isOpen=!0,this.opener=t(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._trigger("open"),undefined)},_focusTabbable:function(){var t=this.element.find("[autofocus]");t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).focus()},_keepFocus:function(e){function i(){var e=this.document[0].activeElement,i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),undefined;if(e.keyCode===t.ui.keyCode.TAB){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(n.focus(1),e.preventDefault()):(s.focus(1),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=t("<button></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(e),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title||t.html("&#160;"),t.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=t("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),undefined):(t.each(i,function(i,s){var n,o;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,s.click=function(){n.apply(e.element[0],arguments)},o={icons:s.icons,text:s.showText},delete s.icons,delete s.showText,t("<button></button>",s).button(o).appendTo(e.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),undefined)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){t(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,o){s.position=[o.position.left-i.document.scrollLeft(),o.position.top-i.document.scrollTop()],t(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(o))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}
}var i=this,s=this.options,n=s.resizable,o=this.uiDialog.css("position"),a="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:a,start:function(s,n){t(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,o){s.height=t(this).height(),s.width=t(this).width(),t(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(o))}}).css("position",o)},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(s){var n=this,o=!1,a={};t.each(s,function(t,s){n._setOption(t,s),t in e&&(o=!0),t in i&&(a[t]=s)}),o&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",a)},_setOption:function(t,e){var i,s,n=this.uiDialog;"dialogClass"===t&&n.removeClass(this.options.dialogClass).addClass(e),"disabled"!==t&&(this._super(t,e),"appendTo"===t&&this.uiDialog.appendTo(this._appendTo()),"buttons"===t&&this._createButtons(),"closeText"===t&&this.uiDialogTitlebarClose.button({label:""+e}),"draggable"===t&&(i=n.is(":data(ui-draggable)"),i&&!e&&n.draggable("destroy"),!i&&e&&this._makeDraggable()),"position"===t&&this._position(),"resizable"===t&&(s=n.is(":data(ui-resizable)"),s&&!e&&n.resizable("destroy"),s&&"string"==typeof e&&n.resizable("option","handles",e),s||e===!1||this._makeResizable()),"title"===t&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("<div>").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=this,i=this.widgetFullName;t.ui.dialog.overlayInstances||this._delay(function(){t.ui.dialog.overlayInstances&&this.document.bind("focusin.dialog",function(s){e._allowInteraction(s)||(s.preventDefault(),t(".ui-dialog:visible:last .ui-dialog-content").data(i)._focusTabbable())})}),this.overlay=t("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),t.ui.dialog.overlayInstances++}},_destroyOverlay:function(){this.options.modal&&this.overlay&&(t.ui.dialog.overlayInstances--,t.ui.dialog.overlayInstances||this.document.unbind("focusin.dialog"),this.overlay.remove(),this.overlay=null)}}),t.ui.dialog.overlayInstances=0,t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{_position:function(){var e,i=this.options.position,s=[],n=[0,0];i?(("string"==typeof i||"object"==typeof i&&"0"in i)&&(s=i.split?i.split(" "):[i[0],i[1]],1===s.length&&(s[1]=s[0]),t.each(["left","top"],function(t,e){+s[t]===s[t]&&(n[t]=s[t],s[t]=e)}),i={my:s[0]+(0>n[0]?n[0]:"+"+n[0])+" "+s[1]+(0>n[1]?n[1]:"+"+n[1]),at:s.join(" ")}),i=t.extend({},t.ui.dialog.prototype.options.position,i)):i=t.ui.dialog.prototype.options.position,e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.position(i),e||this.uiDialog.hide()}})}(jQuery),function(t){var e=/up|down|vertical/,i=/up|left|vertical|horizontal/;t.effects.effect.blind=function(s,n){var o,a,r,h=t(this),l=["position","top","bottom","left","right","height","width"],c=t.effects.setMode(h,s.mode||"hide"),u=s.direction||"up",d=e.test(u),p=d?"height":"width",f=d?"top":"left",g=i.test(u),m={},v="show"===c;h.parent().is(".ui-effects-wrapper")?t.effects.save(h.parent(),l):t.effects.save(h,l),h.show(),o=t.effects.createWrapper(h).css({overflow:"hidden"}),a=o[p](),r=parseFloat(o.css(f))||0,m[p]=v?a:0,g||(h.css(d?"bottom":"right",0).css(d?"top":"left","auto").css({position:"absolute"}),m[f]=v?r:a+r),v&&(o.css(p,0),g||o.css(f,r+a)),o.animate(m,{duration:s.duration,easing:s.easing,queue:!1,complete:function(){"hide"===c&&h.hide(),t.effects.restore(h,l),t.effects.removeWrapper(h),n()}})}}(jQuery),function(t){t.effects.effect.bounce=function(e,i){var s,n,o,a=t(this),r=["position","top","bottom","left","right","height","width"],h=t.effects.setMode(a,e.mode||"effect"),l="hide"===h,c="show"===h,u=e.direction||"up",d=e.distance,p=e.times||5,f=2*p+(c||l?1:0),g=e.duration/f,m=e.easing,v="up"===u||"down"===u?"top":"left",_="up"===u||"left"===u,b=a.queue(),y=b.length;for((c||l)&&r.push("opacity"),t.effects.save(a,r),a.show(),t.effects.createWrapper(a),d||(d=a["top"===v?"outerHeight":"outerWidth"]()/3),c&&(o={opacity:1},o[v]=0,a.css("opacity",0).css(v,_?2*-d:2*d).animate(o,g,m)),l&&(d/=Math.pow(2,p-1)),o={},o[v]=0,s=0;p>s;s++)n={},n[v]=(_?"-=":"+=")+d,a.animate(n,g,m).animate(o,g,m),d=l?2*d:d/2;l&&(n={opacity:0},n[v]=(_?"-=":"+=")+d,a.animate(n,g,m)),a.queue(function(){l&&a.hide(),t.effects.restore(a,r),t.effects.removeWrapper(a),i()}),y>1&&b.splice.apply(b,[1,0].concat(b.splice(y,f+1))),a.dequeue()}}(jQuery),function(t){t.effects.effect.clip=function(e,i){var s,n,o,a=t(this),r=["position","top","bottom","left","right","height","width"],h=t.effects.setMode(a,e.mode||"hide"),l="show"===h,c=e.direction||"vertical",u="vertical"===c,d=u?"height":"width",p=u?"top":"left",f={};t.effects.save(a,r),a.show(),s=t.effects.createWrapper(a).css({overflow:"hidden"}),n="IMG"===a[0].tagName?s:a,o=n[d](),l&&(n.css(d,0),n.css(p,o/2)),f[d]=l?o:0,f[p]=l?0:o/2,n.animate(f,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){l||a.hide(),t.effects.restore(a,r),t.effects.removeWrapper(a),i()}})}}(jQuery),function(t){t.effects.effect.drop=function(e,i){var s,n=t(this),o=["position","top","bottom","left","right","opacity","height","width"],a=t.effects.setMode(n,e.mode||"hide"),r="show"===a,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h?"pos":"neg",u={opacity:r?1:0};t.effects.save(n,o),n.show(),t.effects.createWrapper(n),s=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0)/2,r&&n.css("opacity",0).css(l,"pos"===c?-s:s),u[l]=(r?"pos"===c?"+=":"-=":"pos"===c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===a&&n.hide(),t.effects.restore(n,o),t.effects.removeWrapper(n),i()}})}}(jQuery),function(t){t.effects.effect.explode=function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),g||p.hide(),i()}var o,a,r,h,l,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=t.effects.setMode(p,e.mode||"hide"),g="show"===f,m=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/d),_=Math.ceil(p.outerHeight()/u),b=[];for(o=0;u>o;o++)for(h=m.top+o*_,c=o-(u-1)/2,a=0;d>a;a++)r=m.left+a*v,l=a-(d-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-a*v,top:-o*_}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:_,left:r+(g?l*v:0),top:h+(g?c*_:0),opacity:g?0:1}).animate({left:r+(g?0:l*v),top:h+(g?0:c*_),opacity:g?1:0},e.duration||500,e.easing,s)}}(jQuery),function(t){t.effects.effect.fade=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"toggle");s.animate({opacity:n},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}}(jQuery),function(t){t.effects.effect.fold=function(e,i){var s,n,o=t(this),a=["position","top","bottom","left","right","height","width"],r=t.effects.setMode(o,e.mode||"hide"),h="show"===r,l="hide"===r,c=e.size||15,u=/([0-9]+)%/.exec(c),d=!!e.horizFirst,p=h!==d,f=p?["width","height"]:["height","width"],g=e.duration/2,m={},v={};t.effects.save(o,a),o.show(),s=t.effects.createWrapper(o).css({overflow:"hidden"}),n=p?[s.width(),s.height()]:[s.height(),s.width()],u&&(c=parseInt(u[1],10)/100*n[l?0:1]),h&&s.css(d?{height:0,width:c}:{height:c,width:0}),m[f[0]]=h?n[0]:c,v[f[1]]=h?n[1]:0,s.animate(m,g,e.easing).animate(v,g,e.easing,function(){l&&o.hide(),t.effects.restore(o,a),t.effects.removeWrapper(o),i()})}}(jQuery),function(t){t.effects.effect.highlight=function(e,i){var s=t(this),n=["backgroundImage","backgroundColor","opacity"],o=t.effects.setMode(s,e.mode||"show"),a={backgroundColor:s.css("backgroundColor")};"hide"===o&&(a.opacity=0),t.effects.save(s,n),s.show().css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(a,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===o&&s.hide(),t.effects.restore(s,n),i()}})}}(jQuery),function(t){t.effects.effect.pulsate=function(e,i){var s,n=t(this),o=t.effects.setMode(n,e.mode||"show"),a="show"===o,r="hide"===o,h=a||"hide"===o,l=2*(e.times||5)+(h?1:0),c=e.duration/l,u=0,d=n.queue(),p=d.length;for((a||!n.is(":visible"))&&(n.css("opacity",0).show(),u=1),s=1;l>s;s++)n.animate({opacity:u},c,e.easing),u=1-u;n.animate({opacity:u},c,e.easing),n.queue(function(){r&&n.hide(),i()}),p>1&&d.splice.apply(d,[1,0].concat(d.splice(p,l+1))),n.dequeue()}}(jQuery),function(t){t.effects.effect.puff=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"hide"),o="hide"===n,a=parseInt(e.percent,10)||150,r=a/100,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};t.extend(e,{effect:"scale",queue:!1,fade:!0,mode:n,complete:i,percent:o?a:100,from:o?h:{height:h.height*r,width:h.width*r,outerHeight:h.outerHeight*r,outerWidth:h.outerWidth*r}}),s.effect(e)},t.effects.effect.scale=function(e,i){var s=t(this),n=t.extend(!0,{},e),o=t.effects.setMode(s,e.mode||"effect"),a=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"hide"===o?0:100),r=e.direction||"both",h=e.origin,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},c={y:"horizontal"!==r?a/100:1,x:"vertical"!==r?a/100:1};n.effect="size",n.queue=!1,n.complete=i,"effect"!==o&&(n.origin=h||["middle","center"],n.restore=!0),n.from=e.from||("show"===o?{height:0,width:0,outerHeight:0,outerWidth:0}:l),n.to={height:l.height*c.y,width:l.width*c.x,outerHeight:l.outerHeight*c.y,outerWidth:l.outerWidth*c.x},n.fade&&("show"===o&&(n.from.opacity=0,n.to.opacity=1),"hide"===o&&(n.from.opacity=1,n.to.opacity=0)),s.effect(n)},t.effects.effect.size=function(e,i){var s,n,o,a=t(this),r=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],l=["width","height","overflow"],c=["fontSize"],u=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],d=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=t.effects.setMode(a,e.mode||"effect"),f=e.restore||"effect"!==p,g=e.scale||"both",m=e.origin||["middle","center"],v=a.css("position"),_=f?r:h,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&a.show(),s={height:a.height(),width:a.width(),outerHeight:a.outerHeight(),outerWidth:a.outerWidth()},"toggle"===e.mode&&"show"===p?(a.from=e.to||b,a.to=e.from||s):(a.from=e.from||("show"===p?b:s),a.to=e.to||("hide"===p?b:s)),o={from:{y:a.from.height/s.height,x:a.from.width/s.width},to:{y:a.to.height/s.height,x:a.to.width/s.width}},("box"===g||"both"===g)&&(o.from.y!==o.to.y&&(_=_.concat(u),a.from=t.effects.setTransition(a,u,o.from.y,a.from),a.to=t.effects.setTransition(a,u,o.to.y,a.to)),o.from.x!==o.to.x&&(_=_.concat(d),a.from=t.effects.setTransition(a,d,o.from.x,a.from),a.to=t.effects.setTransition(a,d,o.to.x,a.to))),("content"===g||"both"===g)&&o.from.y!==o.to.y&&(_=_.concat(c).concat(l),a.from=t.effects.setTransition(a,c,o.from.y,a.from),a.to=t.effects.setTransition(a,c,o.to.y,a.to)),t.effects.save(a,_),a.show(),t.effects.createWrapper(a),a.css("overflow","hidden").css(a.from),m&&(n=t.effects.getBaseline(m,s),a.from.top=(s.outerHeight-a.outerHeight())*n.y,a.from.left=(s.outerWidth-a.outerWidth())*n.x,a.to.top=(s.outerHeight-a.to.outerHeight)*n.y,a.to.left=(s.outerWidth-a.to.outerWidth)*n.x),a.css(a.from),("content"===g||"both"===g)&&(u=u.concat(["marginTop","marginBottom"]).concat(c),d=d.concat(["marginLeft","marginRight"]),l=r.concat(u).concat(d),a.find("*[width]").each(function(){var i=t(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};f&&t.effects.save(i,l),i.from={height:s.height*o.from.y,width:s.width*o.from.x,outerHeight:s.outerHeight*o.from.y,outerWidth:s.outerWidth*o.from.x},i.to={height:s.height*o.to.y,width:s.width*o.to.x,outerHeight:s.height*o.to.y,outerWidth:s.width*o.to.x},o.from.y!==o.to.y&&(i.from=t.effects.setTransition(i,u,o.from.y,i.from),i.to=t.effects.setTransition(i,u,o.to.y,i.to)),o.from.x!==o.to.x&&(i.from=t.effects.setTransition(i,d,o.from.x,i.from),i.to=t.effects.setTransition(i,d,o.to.x,i.to)),i.css(i.from),i.animate(i.to,e.duration,e.easing,function(){f&&t.effects.restore(i,l)})})),a.animate(a.to,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){0===a.to.opacity&&a.css("opacity",a.from.opacity),"hide"===p&&a.hide(),t.effects.restore(a,_),f||("static"===v?a.css({position:"relative",top:a.to.top,left:a.to.left}):t.each(["top","left"],function(t,e){a.css(e,function(e,i){var s=parseInt(i,10),n=t?a.to.left:a.to.top;return"auto"===i?n+"px":s+n+"px"})})),t.effects.removeWrapper(a),i()}})}}(jQuery),function(t){t.effects.effect.shake=function(e,i){var s,n=t(this),o=["position","top","bottom","left","right","height","width"],a=t.effects.setMode(n,e.mode||"effect"),r=e.direction||"left",h=e.distance||20,l=e.times||3,c=2*l+1,u=Math.round(e.duration/c),d="up"===r||"down"===r?"top":"left",p="up"===r||"left"===r,f={},g={},m={},v=n.queue(),_=v.length;for(t.effects.save(n,o),n.show(),t.effects.createWrapper(n),f[d]=(p?"-=":"+=")+h,g[d]=(p?"+=":"-=")+2*h,m[d]=(p?"-=":"+=")+2*h,n.animate(f,u,e.easing),s=1;l>s;s++)n.animate(g,u,e.easing).animate(m,u,e.easing);n.animate(g,u,e.easing).animate(f,u/2,e.easing).queue(function(){"hide"===a&&n.hide(),t.effects.restore(n,o),t.effects.removeWrapper(n),i()}),_>1&&v.splice.apply(v,[1,0].concat(v.splice(_,c+1))),n.dequeue()}}(jQuery),function(t){t.effects.effect.slide=function(e,i){var s,n=t(this),o=["position","top","bottom","left","right","width","height"],a=t.effects.setMode(n,e.mode||"show"),r="show"===a,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,u={};t.effects.save(n,o),n.show(),s=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0),t.effects.createWrapper(n).css({overflow:"hidden"}),r&&n.css(l,c?isNaN(s)?"-"+s:-s:s),u[l]=(r?c?"+=":"-=":c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===a&&n.hide(),t.effects.restore(n,o),t.effects.removeWrapper(n),i()}})}}(jQuery),function(t){t.effects.effect.transfer=function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,h=o?a.scrollLeft():0,l=n.offset(),c={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("<div class='ui-effects-transfer'></div>").appendTo(document.body).addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),i()})}}(jQuery),function(t){t.widget("ui.menu",{version:"1.10.3",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,t.proxy(function(t){this.options.disabled&&t.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(t){t.preventDefault()},"click .ui-state-disabled > a":function(t){t.preventDefault()},"click .ui-menu-item:has(a)":function(e){var i=t(e.target).closest(".ui-menu-item");!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.mouseHandled=!0,this.select(e),i.has(".ui-menu").length?this.expand(e):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){var i=t(e.currentTarget);i.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(e,i)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.children(".ui-menu-item").eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){t.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(e){t(e.target).closest(".ui-menu").length||this.collapseAll(e),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var e=t(this);e.data("ui-menu-submenu-carat")&&e.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(e){function i(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var s,n,o,a,r,h=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:h=!1,n=this.previousFilter||"",o=String.fromCharCode(e.keyCode),a=!1,clearTimeout(this.filterTimer),o===n?a=!0:o=n+o,r=RegExp("^"+i(o),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return r.test(t(this).children("a").text())}),s=a&&-1!==s.index(this.active.next())?this.active.nextAll(".ui-menu-item"):s,s.length||(o=String.fromCharCode(e.keyCode),r=RegExp("^"+i(o),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return r.test(t(this).children("a").text())})),s.length?(this.focus(e,s),s.length>1?(this.previousFilter=o,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}h&&e.preventDefault()},_activate:function(t){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i=this.options.icons.submenu,s=this.element.find(this.options.menus);s.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),s=e.prev("a"),n=t("<span>").addClass("ui-menu-icon ui-icon "+i).data("ui-menu-submenu-carat",!0);s.attr("aria-haspopup","true").prepend(n),e.attr("aria-labelledby",s.attr("id"))}),e=s.add(this.element),e.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),e.children(":not(.ui-menu-item)").each(function(){var e=t(this);/[^\-\u2014\u2013\s]/.test(e.text())||e.addClass("ui-widget-content ui-menu-divider")}),e.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){"icons"===t&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(e.submenu),this._super(t,e)},focus:function(t,e){var i,s;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.height(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",t,{item:this.active}))},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.children(".ui-menu-item")[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())),undefined):(this.next(e),undefined)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.children(".ui-menu-item").first())),undefined):(this.next(e),undefined)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(e){this.active=this.active||t(e.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(e,!0),this._trigger("select",e,i)}})}(jQuery),function(t,e){function i(t,e,i){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?i/100:1)]}function s(e,i){return parseInt(t.css(e,i),10)||0}function n(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}t.ui=t.ui||{};var o,a=Math.max,r=Math.abs,h=Math.round,l=/left|center|right/,c=/top|center|bottom/,u=/[\+\-]\d+(\.[\d]+)?%?/,d=/^\w+/,p=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(o!==e)return o;var i,s,n=t("<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),a=n.children()[0];return t("body").append(n),i=a.offsetWidth,n.css("overflow","scroll"),s=a.offsetWidth,i===s&&(s=n[0].clientWidth),n.remove(),o=i-s},getScrollInfo:function(e){var i=e.isWindow?"":e.element.css("overflow-x"),s=e.isWindow?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,o="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:o?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]);return{element:i,isWindow:s,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s?i.width():i.outerWidth(),height:s?i.height():i.outerHeight()}}},t.fn.position=function(e){if(!e||!e.of)return f.apply(this,arguments);e=t.extend({},e);var o,p,g,m,v,_,b=t(e.of),y=t.position.getWithinInfo(e.within),w=t.position.getScrollInfo(y),k=(e.collision||"flip").split(" "),x={};return _=n(b),b[0].preventDefault&&(e.at="left top"),p=_.width,g=_.height,m=_.offset,v=t.extend({},m),t.each(["my","at"],function(){var t,i,s=(e[this]||"").split(" ");1===s.length&&(s=l.test(s[0])?s.concat(["center"]):c.test(s[0])?["center"].concat(s):["center","center"]),s[0]=l.test(s[0])?s[0]:"center",s[1]=c.test(s[1])?s[1]:"center",t=u.exec(s[0]),i=u.exec(s[1]),x[this]=[t?t[0]:0,i?i[0]:0],e[this]=[d.exec(s[0])[0],d.exec(s[1])[0]]}),1===k.length&&(k[1]=k[0]),"right"===e.at[0]?v.left+=p:"center"===e.at[0]&&(v.left+=p/2),"bottom"===e.at[1]?v.top+=g:"center"===e.at[1]&&(v.top+=g/2),o=i(x.at,p,g),v.left+=o[0],v.top+=o[1],this.each(function(){var n,l,c=t(this),u=c.outerWidth(),d=c.outerHeight(),f=s(this,"marginLeft"),_=s(this,"marginTop"),D=u+f+s(this,"marginRight")+w.width,C=d+_+s(this,"marginBottom")+w.height,I=t.extend({},v),P=i(x.my,c.outerWidth(),c.outerHeight());"right"===e.my[0]?I.left-=u:"center"===e.my[0]&&(I.left-=u/2),"bottom"===e.my[1]?I.top-=d:"center"===e.my[1]&&(I.top-=d/2),I.left+=P[0],I.top+=P[1],t.support.offsetFractions||(I.left=h(I.left),I.top=h(I.top)),n={marginLeft:f,marginTop:_},t.each(["left","top"],function(i,s){t.ui.position[k[i]]&&t.ui.position[k[i]][s](I,{targetWidth:p,targetHeight:g,elemWidth:u,elemHeight:d,collisionPosition:n,collisionWidth:D,collisionHeight:C,offset:[o[0]+P[0],o[1]+P[1]],my:e.my,at:e.at,within:y,elem:c})}),e.using&&(l=function(t){var i=m.left-I.left,s=i+p-u,n=m.top-I.top,o=n+g-d,h={target:{element:b,left:m.left,top:m.top,width:p,height:g},element:{element:c,left:I.left,top:I.top,width:u,height:d},horizontal:0>s?"left":i>0?"right":"center",vertical:0>o?"top":n>0?"bottom":"middle"};u>p&&p>r(i+s)&&(h.horizontal="center"),d>g&&g>r(n+o)&&(h.vertical="middle"),h.important=a(r(i),r(s))>a(r(n),r(o))?"horizontal":"vertical",e.using.call(this,t,h)}),c.offset(t.extend(I,{using:l}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,o=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-o-n;e.collisionWidth>o?h>0&&0>=l?(i=t.left+h+e.collisionWidth-o-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+o-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=a(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,o=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-o-n;e.collisionHeight>o?h>0&&0>=l?(i=t.top+h+e.collisionHeight-o-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+o-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=a(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,a=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-a-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-a-o,(0>i||r(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>r(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,a=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-a-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-a-o,t.top+p+f+g>c&&(0>s||r(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-h,t.top+p+f+g>u&&(i>0||u>r(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}},function(){var e,i,s,n,o,a=document.getElementsByTagName("body")[0],r=document.createElement("div");e=document.createElement(a?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},a&&t.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(o in s)e.style[o]=s[o];e.appendChild(r),i=a||document.documentElement,i.insertBefore(e,i.firstChild),r.style.cssText="position: absolute; left: 10.7432222px;",n=t(r).offset().left,t.support.offsetFractions=n>10&&11>n,e.innerHTML="",i.removeChild(e)}()}(jQuery),function(t,e){t.widget("ui.progressbar",{version:"1.10.3",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=t("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()
},value:function(t){return t===e?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),e)},_constrainedValue:function(t){return t===e&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(i.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}})}(jQuery),function(t){var e=5;t.widget("ui.slider",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),o="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e)})},_createRange:function(){var e=this.options,i="";e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=t("<div></div>").appendTo(this.element),i="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(i+("min"===e.range||"max"===e.range?" ui-slider-range-"+e.range:""))):this.range=t([])},_setupEvents:function(){var t=this.handles.add(this.range).filter("a");this._off(t),this._on(t,this._handleEvents),this._hoverable(t),this._focusable(t)},_destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,h,l,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,o.addClass("ui-state-active").focus(),h=o.offset(),l=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:e.pageX-h.left-o.width()/2,top:e.pageY-h.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_start:function(t,e){var i={handle:this.handles[e],value:this.value()};return this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._trigger("start",t,i)},_slide:function(t,e,i){var s,n,o;this.options.values&&this.options.values.length?(s=this.values(e?0:1),2===this.options.values.length&&this.options.range===!0&&(0===e&&i>s||1===e&&s>i)&&(i=s),i!==this.values(e)&&(n=this.values(),n[e]=i,o=this._trigger("slide",t,{handle:this.handles[e],value:i,values:n}),s=this.values(e?0:1),o!==!1&&this.values(e,i,!0))):i!==this.value()&&(o=this._trigger("slide",t,{handle:this.handles[e],value:i}),o!==!1&&this.value(i))},_stop:function(t,e){var i={handle:this.handles[e],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._trigger("stop",t,i)},_change:function(t,e){if(!this._keySliding&&!this._mouseSliding){var i={handle:this.handles[e],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._lastChangedValue=e,this._trigger("change",t,i)}},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),undefined):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),undefined;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),t.Widget.prototype._setOption.apply(this,arguments),e){case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=0;n>s;s+=1)this._change(null,s);this._animateOff=!1;break;case"min":case"max":this._animateOff=!0,this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this.options.values&&this.options.values.length){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,c={};this.options.values&&this.options.values.length?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),c["horizontal"===h.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[l?"animate":"css"](c,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range[l?"animate":"css"]({width:100-i+"%"},{queue:!1,duration:r.animate}),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range[l?"animate":"css"]({height:100-i+"%"},{queue:!1,duration:r.animate}))},_handleEvents:{keydown:function(i){var s,n,o,a,r=t(i.target).data("ui-slider-handle-index");switch(i.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(i.preventDefault(),!this._keySliding&&(this._keySliding=!0,t(i.target).addClass("ui-state-active"),s=this._start(i,r),s===!1))return}switch(a=this.options.step,n=o=this.options.values&&this.options.values.length?this.values(r):this.value(),i.keyCode){case t.ui.keyCode.HOME:o=this._valueMin();break;case t.ui.keyCode.END:o=this._valueMax();break;case t.ui.keyCode.PAGE_UP:o=this._trimAlignValue(n+(this._valueMax()-this._valueMin())/e);break;case t.ui.keyCode.PAGE_DOWN:o=this._trimAlignValue(n-(this._valueMax()-this._valueMin())/e);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(n===this._valueMax())return;o=this._trimAlignValue(n+a);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(n===this._valueMin())return;o=this._trimAlignValue(n-a)}this._slide(i,r,o)},click:function(t){t.preventDefault()},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),t(e.target).removeClass("ui-state-active"))}}})}(jQuery),function(t){function e(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.widget("ui.spinner",{version:"1.10.3",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e={},i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);void 0!==n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var t=this.element[0]===this.document[0].activeElement;t||(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var t=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=t.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*t.height())&&t.height()>0&&t.height(t.height()),this.options.disabled&&this.disable()},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>&#9650;</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>&#9660;</span>"+"</a>"},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){if("culture"===t||"numberFormat"===t){var i=this._parse(this.element.val());return this.options[t]=e,this.element.val(this._format(i)),void 0}("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(this.buttons.first().find(".ui-icon").removeClass(this.options.icons.up).addClass(e.up),this.buttons.last().find(".ui-icon").removeClass(this.options.icons.down).addClass(e.down)),this._super(t,e),"disabled"===t&&(e?(this.element.prop("disabled",!0),this.buttons.button("disable")):(this.element.prop("disabled",!1),this.buttons.button("enable")))},_setOptions:e(function(t){this._super(t),this._value(this.element.val())}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:e(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:e(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:e(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:e(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(e(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}})}(jQuery),function(t,e){function i(){return++n}function s(t){return t.hash.length>1&&decodeURIComponent(t.href.replace(o,""))===decodeURIComponent(location.href.replace(o,""))}var n=0,o=/#.*$/;t.widget("ui.tabs",{version:"1.10.3",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var e=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var i=this.options.active,s=this.options.collapsible,n=location.hash.substring(1);return null===i&&(n&&this.tabs.each(function(s,o){return t(o).attr("aria-controls")===n?(i=s,!1):e}),null===i&&(i=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===i||-1===i)&&(i=this.tabs.length?0:!1)),i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),-1===i&&(i=s?!1:0)),!s&&i===!1&&this.anchors.length&&(i=0),i},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(i){var s=t(this.document[0].activeElement).closest("li"),n=this.tabs.index(s),o=!0;if(!this._handlePageNav(i)){switch(i.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:n++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:o=!1,n--;break;case t.ui.keyCode.END:n=this.anchors.length-1;break;case t.ui.keyCode.HOME:n=0;break;case t.ui.keyCode.SPACE:return i.preventDefault(),clearTimeout(this.activating),this._activate(n),e;case t.ui.keyCode.ENTER:return i.preventDefault(),clearTimeout(this.activating),this._activate(n===this.options.active?!1:n),e;default:return}i.preventDefault(),clearTimeout(this.activating),n=this._focusNextTab(n,o),i.ctrlKey||(s.attr("aria-selected","false"),this.tabs.eq(n).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",n)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.focus())},_handlePageNav:function(i){return i.altKey&&i.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):i.altKey&&i.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):e},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).focus(),t},_setOption:function(t,i){return"active"===t?(this._activate(i),e):"disabled"===t?(this._setupDisabled(i),e):(this._super(t,i),"collapsible"===t&&(this.element.toggleClass("ui-tabs-collapsible",i),i||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(i),"heightStyle"===t&&this._setupHeightStyle(i),e)},_tabId:function(t){return t.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=t(),this.anchors.each(function(i,n){var o,a,r,h=t(n).uniqueId().attr("id"),l=t(n).closest("li"),c=l.attr("aria-controls");s(n)?(o=n.hash,a=e.element.find(e._sanitizeSelector(o))):(r=e._tabId(l),o="#"+r,a=e.element.find(o),a.length||(a=e._createPanel(r),a.insertAfter(e.panels[i-1]||e.tablist)),a.attr("aria-live","polite")),a.length&&(e.panels=e.panels.add(a)),c&&l.data("ui-tabs-aria-controls",c),l.attr({"aria-controls":o.substring(1),"aria-labelledby":h}),a.attr("aria-labelledby",h)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(e){t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1);for(var i,s=0;i=this.tabs[s];s++)e===!0||-1!==t.inArray(s,e)?t(i).addClass("ui-state-disabled").attr("aria-disabled","true"):t(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=e},_setupEvents:function(e){var i={click:function(t){t.preventDefault()}};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,h=r?t():this._getPanelForTab(o),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():o,newPanel:h};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr({"aria-expanded":"false","aria-hidden":"true"}),i.oldTab.attr("aria-selected","false"),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr({"aria-expanded":"true","aria-hidden":"false"}),i.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(t){return"string"==typeof t&&(t=this.anchors.index(this.anchors.filter("[href$='"+t+"']"))),t},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var s=this.options.disabled;s!==!1&&(i===e?s=!1:(i=this._getIndex(i),s=t.isArray(s)?t.map(s,function(t){return t!==i?t:null}):t.map(this.tabs,function(t,e){return e!==i?e:null})),this._setupDisabled(s))},disable:function(i){var s=this.options.disabled;if(s!==!0){if(i===e)s=!0;else{if(i=this._getIndex(i),-1!==t.inArray(i,s))return;s=t.isArray(s)?t.merge([i],s).sort():[i]}this._setupDisabled(s)}},load:function(e,i){e=this._getIndex(e);var n=this,o=this.tabs.eq(e),a=o.find(".ui-tabs-anchor"),r=this._getPanelForTab(o),h={tab:o,panel:r};s(a[0])||(this.xhr=t.ajax(this._ajaxSettings(a,i,h)),this.xhr&&"canceled"!==this.xhr.statusText&&(o.addClass("ui-tabs-loading"),r.attr("aria-busy","true"),this.xhr.success(function(t){setTimeout(function(){r.html(t),n._trigger("load",i,h)},1)}).complete(function(t,e){setTimeout(function(){"abort"===e&&n.panels.stop(!1,!0),o.removeClass("ui-tabs-loading"),r.removeAttr("aria-busy"),t===n.xhr&&delete n.xhr},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href"),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})}(jQuery),function(t){function e(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))}function i(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")}var s=0;t.widget("ui.tooltip",{version:"1.10.3",options:{content:function(){var e=t(this).attr("title")||"";return t("<a>").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(e,i){var s=this;return"disabled"===e?(this[i?"_disable":"_enable"](),this.options[e]=i,void 0):(this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e)}),void 0)},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0)}),this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.is("[title]")&&e.data("ui-tooltip-title",e.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))})},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s?this._open(e,t,s):(i=s.call(t[0],function(i){t.data("ui-tooltip-open")&&n._delay(function(){e&&(e.type=o),this._open(e,t,i)})}),i&&this._open(e,t,i),void 0)},_open:function(i,s,n){function o(t){l.of=t,a.is(":hidden")||a.position(l)}var a,r,h,l=t.extend({},this.options.position);
if(n){if(a=this._find(s),a.length)return a.find(".ui-tooltip-content").html(n),void 0;s.is("[title]")&&(i&&"mouseover"===i.type?s.attr("title",""):s.removeAttr("title")),a=this._tooltip(s),e(s,a.attr("id")),a.find(".ui-tooltip-content").html(n),this.options.track&&i&&/^mouse/.test(i.type)?(this._on(this.document,{mousemove:o}),o(i)):a.position(t.extend({of:s},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.show&&this.options.show.delay&&(h=this.delayedShow=setInterval(function(){a.is(":visible")&&(o(l.of),clearInterval(h))},t.fx.interval)),this._trigger("open",i,{tooltip:a}),r={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var i=t.Event(e);i.currentTarget=s[0],this.close(i,!0)}},remove:function(){this._removeTooltip(a)}},i&&"mouseover"!==i.type||(r.mouseleave="close"),i&&"focusin"!==i.type||(r.focusout="close"),this._on(!0,s,r)}},close:function(e){var s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);this.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&n.attr("title",n.data("ui-tooltip-title")),i(n),o.stop(!0),this._hide(o,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]}),this.closing=!0,this._trigger("close",e,{tooltip:o}),this.closing=!1)},_tooltip:function(e){var i="ui-tooltip-"+s++,n=t("<div>").attr({id:i,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return t("<div>").addClass("ui-tooltip-content").appendTo(n),n.appendTo(this.document[0].body),this.tooltips[i]=e,n},_find:function(e){var i=e.data("ui-tooltip-id");return i?t("#"+i):t()},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0),t("#"+i).remove(),s.data("ui-tooltip-title")&&(s.attr("title",s.data("ui-tooltip-title")),s.removeData("ui-tooltip-title"))})}})}(jQuery);
/*! jQuery v2.0.3 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
//@ sourceMappingURL=jquery-2.0.3.min.map
*/
(function(e,undefined){var t,n,r=typeof undefined,i=e.location,o=e.document,s=o.documentElement,a=e.jQuery,u=e.$,l={},c=[],p="2.0.3",f=c.concat,h=c.push,d=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,x=function(e,n){return new x.fn.init(e,n,t)},b=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^-ms-/,N=/-([\da-z])/gi,E=function(e,t){return t.toUpperCase()},S=function(){o.removeEventListener("DOMContentLoaded",S,!1),e.removeEventListener("load",S,!1),x.ready()};x.fn=x.prototype={jquery:p,constructor:x,init:function(e,t,n){var r,i;if(!e)return this;if("string"==typeof e){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:T.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof x?t[0]:t,x.merge(this,x.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:o,!0)),C.test(r[1])&&x.isPlainObject(t))for(r in t)x.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=o.getElementById(r[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?n.ready(e):(e.selector!==undefined&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return d.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,t,n,r,i,o,s=arguments[0]||{},a=1,u=arguments.length,l=!1;for("boolean"==typeof s&&(l=s,s=arguments[1]||{},a=2),"object"==typeof s||x.isFunction(s)||(s={}),u===a&&(s=this,--a);u>a;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],r=e[t],s!==r&&(l&&r&&(x.isPlainObject(r)||(i=x.isArray(r)))?(i?(i=!1,o=n&&x.isArray(n)?n:[]):o=n&&x.isPlainObject(n)?n:{},s[t]=x.extend(l,o,r)):r!==undefined&&(s[t]=r));return s},x.extend({expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=a),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){(e===!0?--x.readyWait:x.isReady)||(x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(o,[x]),x.fn.trigger&&x(o).trigger("ready").off("ready")))},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if("object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}return!0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:JSON.parse,parseXML:function(e){var t,n;if(!e||"string"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(r){t=undefined}return(!t||t.getElementsByTagName("parsererror").length)&&x.error("Invalid XML: "+e),t},noop:function(){},globalEval:function(e){var t,n=eval;e=x.trim(e),e&&(1===e.indexOf("use strict")?(t=o.createElement("script"),t.text=e,o.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(k,"ms-").replace(N,E)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,s=j(e);if(n){if(s){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(s){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:function(e){return null==e?"":v.call(e)},makeArray:function(e,t){var n=t||[];return null!=e&&(j(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:g.call(t,e,n)},merge:function(e,t){var n=t.length,r=e.length,i=0;if("number"==typeof n)for(;n>i;i++)e[r++]=t[i];else while(t[i]!==undefined)e[r++]=t[i++];return e.length=r,e},grep:function(e,t,n){var r,i=[],o=0,s=e.length;for(n=!!n;s>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,s=j(e),a=[];if(s)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(a[a.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(a[a.length]=r);return f.apply([],a)},guid:1,proxy:function(e,t){var n,r,i;return"string"==typeof t&&(n=e[t],t=e,e=n),x.isFunction(e)?(r=d.call(arguments,2),i=function(){return e.apply(t||this,r.concat(d.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):undefined},access:function(e,t,n,r,i,o,s){var a=0,u=e.length,l=null==n;if("object"===x.type(n)){i=!0;for(a in n)x.access(e,t,a,n[a],!0,o,s)}else if(r!==undefined&&(i=!0,x.isFunction(r)||(s=!0),l&&(s?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(x(e),n)})),t))for(;u>a;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return i?e:l?t.call(e):u?t(e[0],n):o},now:Date.now,swap:function(e,t,n,r){var i,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=s[o];return i}}),x.ready.promise=function(t){return n||(n=x.Deferred(),"complete"===o.readyState?setTimeout(x.ready):(o.addEventListener("DOMContentLoaded",S,!1),e.addEventListener("load",S,!1))),n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function j(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}t=x(o),function(e,undefined){var t,n,r,i,o,s,a,u,l,c,p,f,h,d,g,m,y,v="sizzle"+-new Date,b=e.document,w=0,T=0,C=st(),k=st(),N=st(),E=!1,S=function(e,t){return e===t?(E=!0,0):0},j=typeof undefined,D=1<<31,A={}.hasOwnProperty,L=[],q=L.pop,H=L.push,O=L.push,F=L.slice,P=L.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",W="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",$=W.replace("w","w#"),B="\\["+M+"*("+W+")"+M+"*(?:([*^$|!~]?=)"+M+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+$+")|)|)"+M+"*\\]",I=":("+W+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+B.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=RegExp("^"+M+"*,"+M+"*"),X=RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=RegExp(M+"*[+~]"),Y=RegExp("="+M+"*([^\\]'\"]*)"+M+"*\\]","g"),V=RegExp(I),G=RegExp("^"+$+"$"),J={ID:RegExp("^#("+W+")"),CLASS:RegExp("^\\.("+W+")"),TAG:RegExp("^("+W.replace("w","w*")+")"),ATTR:RegExp("^"+B),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:RegExp("^(?:"+R+")$","i"),needsContext:RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Q=/^[^{]+\{\s*\[native \w/,K=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Z=/^(?:input|select|textarea|button)$/i,et=/^h\d$/i,tt=/'|\\/g,nt=RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),rt=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{O.apply(L=F.call(b.childNodes),b.childNodes),L[b.childNodes.length].nodeType}catch(it){O={apply:L.length?function(e,t){H.apply(e,F.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function ot(e,t,r,i){var o,s,a,u,l,f,g,m,x,w;if((t?t.ownerDocument||t:b)!==p&&c(t),t=t||p,r=r||[],!e||"string"!=typeof e)return r;if(1!==(u=t.nodeType)&&9!==u)return[];if(h&&!i){if(o=K.exec(e))if(a=o[1]){if(9===u){if(s=t.getElementById(a),!s||!s.parentNode)return r;if(s.id===a)return r.push(s),r}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(a))&&y(t,s)&&s.id===a)return r.push(s),r}else{if(o[2])return O.apply(r,t.getElementsByTagName(e)),r;if((a=o[3])&&n.getElementsByClassName&&t.getElementsByClassName)return O.apply(r,t.getElementsByClassName(a)),r}if(n.qsa&&(!d||!d.test(e))){if(m=g=v,x=t,w=9===u&&e,1===u&&"object"!==t.nodeName.toLowerCase()){f=gt(e),(g=t.getAttribute("id"))?m=g.replace(tt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",l=f.length;while(l--)f[l]=m+mt(f[l]);x=U.test(e)&&t.parentNode||t,w=f.join(",")}if(w)try{return O.apply(r,x.querySelectorAll(w)),r}catch(T){}finally{g||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,r,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>i.cacheLength&&delete t[e.shift()],t[n]=r}return t}function at(e){return e[v]=!0,e}function ut(e){var t=p.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function lt(e,t){var n=e.split("|"),r=e.length;while(r--)i.attrHandle[n[r]]=t}function ct(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return at(function(t){return t=+t,at(function(n,r){var i,o=e([],n.length,t),s=o.length;while(s--)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}s=ot.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},n=ot.support={},c=ot.setDocument=function(e){var t=e?e.ownerDocument||e:b,r=t.defaultView;return t!==p&&9===t.nodeType&&t.documentElement?(p=t,f=t.documentElement,h=!s(t),r&&r.attachEvent&&r!==r.top&&r.attachEvent("onbeforeunload",function(){c()}),n.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ut(function(e){return e.appendChild(t.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),n.getById=ut(function(e){return f.appendChild(e).id=v,!t.getElementsByName||!t.getElementsByName(v).length}),n.getById?(i.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){return e.getAttribute("id")===t}}):(delete i.find.ID,i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=n.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==j?t.getElementsByTagName(e):undefined}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.CLASS=n.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==j&&h?t.getElementsByClassName(e):undefined},g=[],d=[],(n.qsa=Q.test(t.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||d.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll(":checked").length||d.push(":checked")}),ut(function(e){var n=t.createElement("input");n.setAttribute("type","hidden"),e.appendChild(n).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&d.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||d.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),d.push(",.*:")})),(n.matchesSelector=Q.test(m=f.webkitMatchesSelector||f.mozMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&ut(function(e){n.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",I)}),d=d.length&&RegExp(d.join("|")),g=g.length&&RegExp(g.join("|")),y=Q.test(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},S=f.compareDocumentPosition?function(e,r){if(e===r)return E=!0,0;var i=r.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(r);return i?1&i||!n.sortDetached&&r.compareDocumentPosition(e)===i?e===t||y(b,e)?-1:r===t||y(b,r)?1:l?P.call(l,e)-P.call(l,r):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,n){var r,i=0,o=e.parentNode,s=n.parentNode,a=[e],u=[n];if(e===n)return E=!0,0;if(!o||!s)return e===t?-1:n===t?1:o?-1:s?1:l?P.call(l,e)-P.call(l,n):0;if(o===s)return ct(e,n);r=e;while(r=r.parentNode)a.unshift(r);r=n;while(r=r.parentNode)u.unshift(r);while(a[i]===u[i])i++;return i?ct(a[i],u[i]):a[i]===b?-1:u[i]===b?1:0},t):p},ot.matches=function(e,t){return ot(e,null,null,t)},ot.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Y,"='$1']"),!(!n.matchesSelector||!h||g&&g.test(t)||d&&d.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return ot(t,p,null,[e]).length>0},ot.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},ot.attr=function(e,t){(e.ownerDocument||e)!==p&&c(e);var r=i.attrHandle[t.toLowerCase()],o=r&&A.call(i.attrHandle,t.toLowerCase())?r(e,t,!h):undefined;return o===undefined?n.attributes||!h?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null:o},ot.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},ot.uniqueSort=function(e){var t,r=[],i=0,o=0;if(E=!n.detectDuplicates,l=!n.sortStable&&e.slice(0),e.sort(S),E){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return e},o=ot.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=ot.selectors={cacheLength:50,createPseudo:at,match:J,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(nt,rt),e[3]=(e[4]||e[5]||"").replace(nt,rt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ot.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ot.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return J.CHILD.test(e[0])?null:(e[3]&&e[4]!==undefined?e[2]=e[4]:n&&V.test(n)&&(t=gt(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(nt,rt).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=C[e+" "];return t||(t=RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&C(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=ot.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,h,d,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,y=a&&t.nodeName.toLowerCase(),x=!u&&!a;if(m){if(o){while(g){p=t;while(p=p[g])if(a?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;d=g="only"===e&&!d&&"nextSibling"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&x){c=m[v]||(m[v]={}),l=c[e]||[],h=l[0]===w&&l[1],f=l[0]===w&&l[2],p=h&&m.childNodes[h];while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[w,h,f];break}}else if(x&&(l=(t[v]||(t[v]={}))[e])&&l[0]===w)f=l[1];else while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if((a?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(x&&((p[v]||(p[v]={}))[e]=[w,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||ot.error("unsupported pseudo: "+e);return r[v]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?at(function(e,n){var i,o=r(e,t),s=o.length;while(s--)i=P.call(e,o[s]),e[i]=!(n[i]=o[s])}):function(e){return r(e,0,n)}):r}},pseudos:{not:at(function(e){var t=[],n=[],r=a(e.replace(z,"$1"));return r[v]?at(function(e,t,n,i){var o,s=r(e,null,i,[]),a=e.length;while(a--)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:at(function(e){return function(t){return ot(e,t).length>0}}),contains:at(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:at(function(e){return G.test(e||"")||ot.error("unsupported lang: "+e),e=e.replace(nt,rt).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return et.test(e.nodeName)},input:function(e){return Z.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},i.pseudos.nth=i.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[t]=pt(t);for(t in{submit:!0,reset:!0})i.pseudos[t]=ft(t);function dt(){}dt.prototype=i.filters=i.pseudos,i.setFilters=new dt;function gt(e,t){var n,r,o,s,a,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);a=e,u=[],l=i.preFilter;while(a){(!n||(r=_.exec(a)))&&(r&&(a=a.slice(r[0].length)||a),u.push(o=[])),n=!1,(r=X.exec(a))&&(n=r.shift(),o.push({value:n,type:r[0].replace(z," ")}),a=a.slice(n.length));for(s in i.filter)!(r=J[s].exec(a))||l[s]&&!(r=l[s](r))||(n=r.shift(),o.push({value:n,type:s,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?ot.error(e):k(e,u).slice(0)}function mt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function yt(e,t,n){var i=t.dir,o=n&&"parentNode"===i,s=T++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,a){var u,l,c,p=w+" "+s;if(a){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,a))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[v]||(t[v]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,a)||r,l[1]===!0)return!0}}function vt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,s=[],a=0,u=e.length,l=null!=t;for(;u>a;a++)(o=e[a])&&(!n||n(o,r,i))&&(s.push(o),l&&t.push(a));return s}function bt(e,t,n,r,i,o){return r&&!r[v]&&(r=bt(r)),i&&!i[v]&&(i=bt(i,o)),at(function(o,s,a,u){var l,c,p,f=[],h=[],d=s.length,g=o||Ct(t||"*",a.nodeType?[a]:a,[]),m=!e||!o&&t?g:xt(g,f,e,a,u),y=n?i||(o?e:d||r)?[]:s:m;if(n&&n(m,y,a,u),r){l=xt(y,h),r(l,[],a,u),c=l.length;while(c--)(p=l[c])&&(y[h[c]]=!(m[h[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?P.call(o,p):f[c])>-1&&(o[l]=!(s[l]=p))}}else y=xt(y===s?y.splice(d,y.length):y),i?i(null,s,y,u):O.apply(s,y)})}function wt(e){var t,n,r,o=e.length,s=i.relative[e[0].type],a=s||i.relative[" "],l=s?1:0,c=yt(function(e){return e===t},a,!0),p=yt(function(e){return P.call(t,e)>-1},a,!0),f=[function(e,n,r){return!s&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>l;l++)if(n=i.relative[e[l].type])f=[yt(vt(f),n)];else{if(n=i.filter[e[l].type].apply(null,e[l].matches),n[v]){for(r=++l;o>r;r++)if(i.relative[e[r].type])break;return bt(l>1&&vt(f),l>1&&mt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&wt(e.slice(l,r)),o>r&&wt(e=e.slice(r)),o>r&&mt(e))}f.push(n)}return vt(f)}function Tt(e,t){var n=0,o=t.length>0,s=e.length>0,a=function(a,l,c,f,h){var d,g,m,y=[],v=0,x="0",b=a&&[],T=null!=h,C=u,k=a||s&&i.find.TAG("*",h&&l.parentNode||l),N=w+=null==C?1:Math.random()||.1;for(T&&(u=l!==p&&l,r=n);null!=(d=k[x]);x++){if(s&&d){g=0;while(m=e[g++])if(m(d,l,c)){f.push(d);break}T&&(w=N,r=++n)}o&&((d=!m&&d)&&v--,a&&b.push(d))}if(v+=x,o&&x!==v){g=0;while(m=t[g++])m(b,y,l,c);if(a){if(v>0)while(x--)b[x]||y[x]||(y[x]=q.call(f));y=xt(y)}O.apply(f,y),T&&!a&&y.length>0&&v+t.length>1&&ot.uniqueSort(f)}return T&&(w=N,u=C),b};return o?at(a):a}a=ot.compile=function(e,t){var n,r=[],i=[],o=N[e+" "];if(!o){t||(t=gt(e)),n=t.length;while(n--)o=wt(t[n]),o[v]?r.push(o):i.push(o);o=N(e,Tt(i,r))}return o};function Ct(e,t,n){var r=0,i=t.length;for(;i>r;r++)ot(e,t[r],n);return n}function kt(e,t,r,o){var s,u,l,c,p,f=gt(e);if(!o&&1===f.length){if(u=f[0]=f[0].slice(0),u.length>2&&"ID"===(l=u[0]).type&&n.getById&&9===t.nodeType&&h&&i.relative[u[1].type]){if(t=(i.find.ID(l.matches[0].replace(nt,rt),t)||[])[0],!t)return r;e=e.slice(u.shift().value.length)}s=J.needsContext.test(e)?0:u.length;while(s--){if(l=u[s],i.relative[c=l.type])break;if((p=i.find[c])&&(o=p(l.matches[0].replace(nt,rt),U.test(u[0].type)&&t.parentNode||t))){if(u.splice(s,1),e=o.length&&mt(u),!e)return O.apply(r,o),r;break}}}return a(e,f)(o,t,!h,r,U.test(e)),r}n.sortStable=v.split("").sort(S).join("")===v,n.detectDuplicates=E,c(),n.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(p.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||lt("type|href|height|width",function(e,t,n){return n?undefined:e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||lt("value",function(e,t,n){return n||"input"!==e.nodeName.toLowerCase()?undefined:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||lt(R,function(e,t,n){var r;return n?undefined:(r=e.getAttributeNode(t))&&r.specified?r.value:e[t]===!0?t.toLowerCase():null}),x.find=ot,x.expr=ot.selectors,x.expr[":"]=x.expr.pseudos,x.unique=ot.uniqueSort,x.text=ot.getText,x.isXMLDoc=ot.isXML,x.contains=ot.contains}(e);var D={};function A(e){var t=D[e]={};return x.each(e.match(w)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?D[e]||A(e):x.extend({},e);var t,n,r,i,o,s,a=[],u=!e.once&&[],l=function(p){for(t=e.memory&&p,n=!0,s=i||0,i=0,o=a.length,r=!0;a&&o>s;s++)if(a[s].apply(p[0],p[1])===!1&&e.stopOnFalse){t=!1;break}r=!1,a&&(u?u.length&&l(u.shift()):t?a=[]:c.disable())},c={add:function(){if(a){var n=a.length;(function s(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&c.has(n)||a.push(n):n&&n.length&&"string"!==r&&s(n)})})(arguments),r?o=a.length:t&&(i=n,l(t))}return this},remove:function(){return a&&x.each(arguments,function(e,t){var n;while((n=x.inArray(t,a,n))>-1)a.splice(n,1),r&&(o>=n&&o--,s>=n&&s--)}),this},has:function(e){return e?x.inArray(e,a)>-1:!(!a||!a.length)},empty:function(){return a=[],o=0,this},disable:function(){return a=u=t=undefined,this},disabled:function(){return!a},lock:function(){return u=undefined,t||c.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!a||n&&!u||(t=t||[],t=[e,t.slice?t.slice():t],r?u.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!n}};return c},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var s=o[0],a=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var s=o[2],a=o[3];r[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=s.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=d.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),s=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?d.call(arguments):r,n===a?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},a,u,l;if(r>1)for(a=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(s(t,l,n)).fail(o.reject).progress(s(t,u,a)):--i;return i||o.resolveWith(l,n),o.promise()}}),x.support=function(t){var n=o.createElement("input"),r=o.createDocumentFragment(),i=o.createElement("div"),s=o.createElement("select"),a=s.appendChild(o.createElement("option"));return n.type?(n.type="checkbox",t.checkOn=""!==n.value,t.optSelected=a.selected,t.reliableMarginRight=!0,t.boxSizingReliable=!0,t.pixelPosition=!1,n.checked=!0,t.noCloneChecked=n.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!a.disabled,n=o.createElement("input"),n.value="t",n.type="radio",t.radioValue="t"===n.value,n.setAttribute("checked","t"),n.setAttribute("name","t"),r.appendChild(n),t.checkClone=r.cloneNode(!0).cloneNode(!0).lastChild.checked,t.focusinBubbles="onfocusin"in e,i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===i.style.backgroundClip,x(function(){var n,r,s="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",a=o.getElementsByTagName("body")[0];a&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",a.appendChild(n).appendChild(i),i.innerHTML="",i.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",x.swap(a,null!=a.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===i.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(i,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(i,null)||{width:"4px"}).width,r=i.appendChild(o.createElement("div")),r.style.cssText=i.style.cssText=s,r.style.marginRight=r.style.width="0",i.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),a.removeChild(n))}),t):t}({});var L,q,H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,O=/([A-Z])/g;function F(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=x.expando+Math.random()}F.uid=1,F.accepts=function(e){return e.nodeType?1===e.nodeType||9===e.nodeType:!0},F.prototype={key:function(e){if(!F.accepts(e))return 0;var t={},n=e[this.expando];if(!n){n=F.uid++;try{t[this.expando]={value:n},Object.defineProperties(e,t)}catch(r){t[this.expando]=n,x.extend(e,t)}}return this.cache[n]||(this.cache[n]={}),n},set:function(e,t,n){var r,i=this.key(e),o=this.cache[i];if("string"==typeof t)o[t]=n;else if(x.isEmptyObject(o))x.extend(this.cache[i],t);else for(r in t)o[r]=t[r];return o},get:function(e,t){var n=this.cache[this.key(e)];return t===undefined?n:n[t]},access:function(e,t,n){var r;return t===undefined||t&&"string"==typeof t&&n===undefined?(r=this.get(e,t),r!==undefined?r:this.get(e,x.camelCase(t))):(this.set(e,t,n),n!==undefined?n:t)},remove:function(e,t){var n,r,i,o=this.key(e),s=this.cache[o];if(t===undefined)this.cache[o]={};else{x.isArray(t)?r=t.concat(t.map(x.camelCase)):(i=x.camelCase(t),t in s?r=[t,i]:(r=i,r=r in s?[r]:r.match(w)||[])),n=r.length;while(n--)delete s[r[n]]}},hasData:function(e){return!x.isEmptyObject(this.cache[e[this.expando]]||{})},discard:function(e){e[this.expando]&&delete this.cache[e[this.expando]]}},L=new F,q=new F,x.extend({acceptData:F.accepts,hasData:function(e){return L.hasData(e)||q.hasData(e)},data:function(e,t,n){return L.access(e,t,n)},removeData:function(e,t){L.remove(e,t)},_data:function(e,t,n){return q.access(e,t,n)},_removeData:function(e,t){q.remove(e,t)}}),x.fn.extend({data:function(e,t){var n,r,i=this[0],o=0,s=null;if(e===undefined){if(this.length&&(s=L.get(i),1===i.nodeType&&!q.get(i,"hasDataAttrs"))){for(n=i.attributes;n.length>o;o++)r=n[o].name,0===r.indexOf("data-")&&(r=x.camelCase(r.slice(5)),P(i,r,s[r]));q.set(i,"hasDataAttrs",!0)}return s}return"object"==typeof e?this.each(function(){L.set(this,e)}):x.access(this,function(t){var n,r=x.camelCase(e);if(i&&t===undefined){if(n=L.get(i,e),n!==undefined)return n;if(n=L.get(i,r),n!==undefined)return n;if(n=P(i,r,undefined),n!==undefined)return n}else this.each(function(){var n=L.get(this,r);L.set(this,r,t),-1!==e.indexOf("-")&&n!==undefined&&L.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){L.remove(this,e)})}});function P(e,t,n){var r;if(n===undefined&&1===e.nodeType)if(r="data-"+t.replace(O,"-$1").toLowerCase(),n=e.getAttribute(r),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:H.test(n)?JSON.parse(n):n}catch(i){}L.set(e,t,n)}else n=undefined;return n}x.extend({queue:function(e,t,n){var r;return e?(t=(t||"fx")+"queue",r=q.get(e,t),n&&(!r||x.isArray(n)?r=q.access(e,t,x.makeArray(n)):r.push(n)),r||[]):undefined},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),s=function(){x.dequeue(e,t)
};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,s,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return q.get(e,n)||q.access(e,n,{empty:x.Callbacks("once memory").add(function(){q.remove(e,[t+"queue",n])})})}}),x.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),n>arguments.length?x.queue(this[0],e):t===undefined?this:this.each(function(){var n=x.queue(this,e,t);x._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=x.Deferred(),o=this,s=this.length,a=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=undefined),e=e||"fx";while(s--)n=q.get(o[s],e+"queueHooks"),n&&n.empty&&(r++,n.empty.add(a));return a(),i.promise(t)}});var R,M,W=/[\t\r\n\f]/g,$=/\r/g,B=/^(?:input|select|textarea|button)$/i;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[x.propFix[e]||e]})},addClass:function(e){var t,n,r,i,o,s=0,a=this.length,u="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,s=0,a=this.length,u=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,i=0,o=x(this),s=e.match(w)||[];while(t=s[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===r||"boolean"===n)&&(this.className&&q.set(this,"__className__",this.className),this.className=this.className||e===!1?"":q.get(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(W," ").indexOf(t)>=0)return!0;return!1},val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=x.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,x(this).val()):e,null==i?i="":"number"==typeof i?i+="":x.isArray(i)&&(i=x.map(i,function(e){return null==e?"":e+""})),t=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&t.set(this,i,"value")!==undefined||(this.value=i))});if(i)return t=x.valHooks[i.type]||x.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&(n=t.get(i,"value"))!==undefined?n:(n=i.value,"string"==typeof n?n.replace($,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,s=o?null:[],a=o?i+1:r.length,u=0>i?a:o?i:0;for(;a>u;u++)if(n=r[u],!(!n.selected&&u!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),s=i.length;while(s--)r=i[s],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,t,n){var i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===r?x.prop(e,t,n):(1===s&&x.isXMLDoc(e)||(t=t.toLowerCase(),i=x.attrHooks[t]||(x.expr.match.bool.test(t)?M:R)),n===undefined?i&&"get"in i&&null!==(o=i.get(e,t))?o:(o=x.find.attr(e,t),null==o?undefined:o):null!==n?i&&"set"in i&&(o=i.set(e,n,t))!==undefined?o:(e.setAttribute(t,n+""),n):(x.removeAttr(e,t),undefined))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)&&(e[r]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,t,n){var r,i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return o=1!==s||!x.isXMLDoc(e),o&&(t=x.propFix[t]||t,i=x.propHooks[t]),n!==undefined?i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||B.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),M={set:function(e,t,n){return t===!1?x.removeAttr(e,n):e.setAttribute(n,n),n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,t){var n=x.expr.attrHandle[t]||x.find.attr;x.expr.attrHandle[t]=function(e,t,r){var i=x.expr.attrHandle[t],o=r?undefined:(x.expr.attrHandle[t]=undefined)!=n(e,t,r)?t.toLowerCase():null;return x.expr.attrHandle[t]=i,o}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,t){return x.isArray(t)?e.checked=x.inArray(x(e).val(),t)>=0:undefined}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var I=/^key/,z=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,X=/^([^.]*)(?:\.(.+)|)$/;function U(){return!0}function Y(){return!1}function V(){try{return o.activeElement}catch(e){}}x.event={global:{},add:function(e,t,n,i,o){var s,a,u,l,c,p,f,h,d,g,m,y=q.get(e);if(y){n.handler&&(s=n,n=s.handler,o=s.selector),n.guid||(n.guid=x.guid++),(l=y.events)||(l=y.events={}),(a=y.handle)||(a=y.handle=function(e){return typeof x===r||e&&x.event.triggered===e.type?undefined:x.event.dispatch.apply(a.elem,arguments)},a.elem=e),t=(t||"").match(w)||[""],c=t.length;while(c--)u=X.exec(t[c])||[],d=m=u[1],g=(u[2]||"").split(".").sort(),d&&(f=x.event.special[d]||{},d=(o?f.delegateType:f.bindType)||d,f=x.event.special[d]||{},p=x.extend({type:d,origType:m,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&x.expr.match.needsContext.test(o),namespace:g.join(".")},s),(h=l[d])||(h=l[d]=[],h.delegateCount=0,f.setup&&f.setup.call(e,i,g,a)!==!1||e.addEventListener&&e.addEventListener(d,a,!1)),f.add&&(f.add.call(e,p),p.handler.guid||(p.handler.guid=n.guid)),o?h.splice(h.delegateCount++,0,p):h.push(p),x.event.global[d]=!0);e=null}},remove:function(e,t,n,r,i){var o,s,a,u,l,c,p,f,h,d,g,m=q.hasData(e)&&q.get(e);if(m&&(u=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(a=X.exec(t[l])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h){p=x.event.special[h]||{},h=(r?p.delegateType:p.bindType)||h,f=u[h]||[],a=a[2]&&RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=f.length;while(o--)c=f[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(f.splice(o,1),c.selector&&f.delegateCount--,p.remove&&p.remove.call(e,c));s&&!f.length&&(p.teardown&&p.teardown.call(e,d,m.handle)!==!1||x.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)x.event.remove(e,h+t[l],n,r,!0);x.isEmptyObject(u)&&(delete m.handle,q.remove(e,"events"))}},trigger:function(t,n,r,i){var s,a,u,l,c,p,f,h=[r||o],d=y.call(t,"type")?t.type:t,g=y.call(t,"namespace")?t.namespace.split("."):[];if(a=u=r=r||o,3!==r.nodeType&&8!==r.nodeType&&!_.test(d+x.event.triggered)&&(d.indexOf(".")>=0&&(g=d.split("."),d=g.shift(),g.sort()),c=0>d.indexOf(":")&&"on"+d,t=t[x.expando]?t:new x.Event(d,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=g.join("."),t.namespace_re=t.namespace?RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=undefined,t.target||(t.target=r),n=null==n?[t]:x.makeArray(n,[t]),f=x.event.special[d]||{},i||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!i&&!f.noBubble&&!x.isWindow(r)){for(l=f.delegateType||d,_.test(l+d)||(a=a.parentNode);a;a=a.parentNode)h.push(a),u=a;u===(r.ownerDocument||o)&&h.push(u.defaultView||u.parentWindow||e)}s=0;while((a=h[s++])&&!t.isPropagationStopped())t.type=s>1?l:f.bindType||d,p=(q.get(a,"events")||{})[t.type]&&q.get(a,"handle"),p&&p.apply(a,n),p=c&&a[c],p&&x.acceptData(a)&&p.apply&&p.apply(a,n)===!1&&t.preventDefault();return t.type=d,i||t.isDefaultPrevented()||f._default&&f._default.apply(h.pop(),n)!==!1||!x.acceptData(r)||c&&x.isFunction(r[d])&&!x.isWindow(r)&&(u=r[c],u&&(r[c]=null),x.event.triggered=d,r[d](),x.event.triggered=undefined,u&&(r[c]=u)),t.result}},dispatch:function(e){e=x.event.fix(e);var t,n,r,i,o,s=[],a=d.call(arguments),u=(q.get(this,"events")||{})[e.type]||[],l=x.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),t=0;while((i=s[t++])&&!e.isPropagationStopped()){e.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(o.namespace))&&(e.handleObj=o,e.data=o.data,r=((x.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,a),r!==undefined&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!==this;u=u.parentNode||this)if(u.disabled!==!0||"click"!==e.type){for(r=[],n=0;a>n;n++)o=t[n],i=o.selector+" ",r[i]===undefined&&(r[i]=o.needsContext?x(i,this).index(u)>=0:x.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&s.push({elem:u,handlers:r})}return t.length>a&&s.push({elem:this,handlers:t.slice(a)}),s},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,t){var n,r,i,s=t.button;return null==e.pageX&&null!=t.clientX&&(n=e.target.ownerDocument||o,r=n.documentElement,i=n.body,e.pageX=t.clientX+(r&&r.scrollLeft||i&&i.scrollLeft||0)-(r&&r.clientLeft||i&&i.clientLeft||0),e.pageY=t.clientY+(r&&r.scrollTop||i&&i.scrollTop||0)-(r&&r.clientTop||i&&i.clientTop||0)),e.which||s===undefined||(e.which=1&s?1:2&s?3:4&s?2:0),e}},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,s=e,a=this.fixHooks[i];a||(this.fixHooks[i]=a=z.test(i)?this.mouseHooks:I.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new x.Event(s),t=r.length;while(t--)n=r[t],e[n]=s[n];return e.target||(e.target=o),3===e.target.nodeType&&(e.target=e.target.parentNode),a.filter?a.filter(e,s):e},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==V()&&this.focus?(this.focus(),!1):undefined},delegateType:"focusin"},blur:{trigger:function(){return this===V()&&this.blur?(this.blur(),!1):undefined},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&x.nodeName(this,"input")?(this.click(),!1):undefined},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==undefined&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)},x.Event=function(e,t){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.getPreventDefault&&e.getPreventDefault()?U:Y):this.type=e,t&&x.extend(this,t),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,undefined):new x.Event(e,t)},x.Event.prototype={isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=U,e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=U,e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=U,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,t,n,r,i){var o,s;if("object"==typeof e){"string"!=typeof t&&(n=n||t,t=undefined);for(s in e)this.on(s,t,n,e[s],i);return this}if(null==n&&null==r?(r=t,n=t=undefined):null==r&&("string"==typeof t?(r=n,n=undefined):(r=n,n=t,t=undefined)),r===!1)r=Y;else if(!r)return this;return 1===i&&(o=r,r=function(e){return x().off(e),o.apply(this,arguments)},r.guid=o.guid||(o.guid=x.guid++)),this.each(function(){x.event.add(this,e,r,n,t)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,x(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return(t===!1||"function"==typeof t)&&(n=t,t=undefined),n===!1&&(n=Y),this.each(function(){x.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];return n?x.event.trigger(e,t,n,!0):undefined}});var G=/^.[^:#\[\.,]*$/,J=/^(?:parents|prev(?:Until|All))/,Q=x.expr.match.needsContext,K={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t=x(e,this),n=t.length;return this.filter(function(){var e=0;for(;n>e;e++)if(x.contains(this,t[e]))return!0})},not:function(e){return this.pushStack(et(this,e||[],!0))},filter:function(e){return this.pushStack(et(this,e||[],!1))},is:function(e){return!!et(this,"string"==typeof e&&Q.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],s=Q.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(s?s.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?g.call(x(e),this[0]):g.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function Z(e,t){while((e=e[t])&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return Z(e,"nextSibling")},prev:function(e){return Z(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return e.contentDocument||x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(K[e]||x.unique(i),J.test(e)&&i.reverse()),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,t,n){var r=[],i=n!==undefined;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&x(e).is(n))break;r.push(e)}return r},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function et(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(G.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return g.call(t,e)>=0!==n})}var tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,nt=/<([\w:]+)/,rt=/<|&#?\w+;/,it=/<(?:script|style|link)/i,ot=/^(?:checkbox|radio)$/i,st=/checked\s*(?:[^=]|=\s*.checked.)/i,at=/^$|\/(?:java|ecma)script/i,ut=/^true\/(.*)/,lt=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ct={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ct.optgroup=ct.option,ct.tbody=ct.tfoot=ct.colgroup=ct.caption=ct.thead,ct.th=ct.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===undefined?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(mt(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&dt(mt(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++)1===e.nodeType&&(x.cleanData(mt(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var t=this[0]||{},n=0,r=this.length;if(e===undefined&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!it.test(e)&&!ct[(nt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(tt,"<$1></$2>");try{for(;r>n;n++)t=this[n]||{},1===t.nodeType&&(x.cleanData(mt(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=f.apply([],e);var r,i,o,s,a,u,l=0,c=this.length,p=this,h=c-1,d=e[0],g=x.isFunction(d);if(g||!(1>=c||"string"!=typeof d||x.support.checkClone)&&st.test(d))return this.each(function(r){var i=p.eq(r);g&&(e[0]=d.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(r=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),i=r.firstChild,1===r.childNodes.length&&(r=i),i)){for(o=x.map(mt(r,"script"),ft),s=o.length;c>l;l++)a=r,l!==h&&(a=x.clone(a,!0,!0),s&&x.merge(o,mt(a,"script"))),t.call(this[l],a,l);if(s)for(u=o[o.length-1].ownerDocument,x.map(o,ht),l=0;s>l;l++)a=o[l],at.test(a.type||"")&&!q.access(a,"globalEval")&&x.contains(u,a)&&(a.src?x._evalUrl(a.src):x.globalEval(a.textContent.replace(lt,"")))}return this}}),x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=[],i=x(e),o=i.length-1,s=0;for(;o>=s;s++)n=s===o?this:this.clone(!0),x(i[s])[t](n),h.apply(r,n.get());return this.pushStack(r)}}),x.extend({clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=x.contains(e.ownerDocument,e);if(!(x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(s=mt(a),o=mt(e),r=0,i=o.length;i>r;r++)yt(o[r],s[r]);if(t)if(n)for(o=o||mt(e),s=s||mt(a),r=0,i=o.length;i>r;r++)gt(o[r],s[r]);else gt(e,a);return s=mt(a,"script"),s.length>0&&dt(s,!u&&mt(e,"script")),a},buildFragment:function(e,t,n,r){var i,o,s,a,u,l,c=0,p=e.length,f=t.createDocumentFragment(),h=[];for(;p>c;c++)if(i=e[c],i||0===i)if("object"===x.type(i))x.merge(h,i.nodeType?[i]:i);else if(rt.test(i)){o=o||f.appendChild(t.createElement("div")),s=(nt.exec(i)||["",""])[1].toLowerCase(),a=ct[s]||ct._default,o.innerHTML=a[1]+i.replace(tt,"<$1></$2>")+a[2],l=a[0];while(l--)o=o.lastChild;x.merge(h,o.childNodes),o=f.firstChild,o.textContent=""}else h.push(t.createTextNode(i));f.textContent="",c=0;while(i=h[c++])if((!r||-1===x.inArray(i,r))&&(u=x.contains(i.ownerDocument,i),o=mt(f.appendChild(i),"script"),u&&dt(o),n)){l=0;while(i=o[l++])at.test(i.type||"")&&n.push(i)}return f},cleanData:function(e){var t,n,r,i,o,s,a=x.event.special,u=0;for(;(n=e[u])!==undefined;u++){if(F.accepts(n)&&(o=n[q.expando],o&&(t=q.cache[o]))){if(r=Object.keys(t.events||{}),r.length)for(s=0;(i=r[s])!==undefined;s++)a[i]?x.event.remove(n,i):x.removeEvent(n,i,t.handle);q.cache[o]&&delete q.cache[o]}delete L.cache[n[L.expando]]}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}});function pt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function ft(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function ht(e){var t=ut.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function dt(e,t){var n=e.length,r=0;for(;n>r;r++)q.set(e[r],"globalEval",!t||q.get(t[r],"globalEval"))}function gt(e,t){var n,r,i,o,s,a,u,l;if(1===t.nodeType){if(q.hasData(e)&&(o=q.access(e),s=q.set(t,o),l=o.events)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;r>n;n++)x.event.add(t,i,l[i][n])}L.hasData(e)&&(a=L.access(e),u=x.extend({},a),L.set(t,u))}}function mt(e,t){var n=e.getElementsByTagName?e.getElementsByTagName(t||"*"):e.querySelectorAll?e.querySelectorAll(t||"*"):[];return t===undefined||t&&x.nodeName(e,t)?x.merge([e],n):n}function yt(e,t){var n=t.nodeName.toLowerCase();"input"===n&&ot.test(e.type)?t.checked=e.checked:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}x.fn.extend({wrapAll:function(e){var t;return x.isFunction(e)?this.each(function(t){x(this).wrapAll(e.call(this,t))}):(this[0]&&(t=x(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var vt,xt,bt=/^(none|table(?!-c[ea]).+)/,wt=/^margin/,Tt=RegExp("^("+b+")(.*)$","i"),Ct=RegExp("^("+b+")(?!px)[a-z%]+$","i"),kt=RegExp("^([+-])=("+b+")","i"),Nt={BODY:"block"},Et={position:"absolute",visibility:"hidden",display:"block"},St={letterSpacing:0,fontWeight:400},jt=["Top","Right","Bottom","Left"],Dt=["Webkit","O","Moz","ms"];function At(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Dt.length;while(i--)if(t=Dt[i]+n,t in e)return t;return r}function Lt(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function qt(t){return e.getComputedStyle(t,null)}function Ht(e,t){var n,r,i,o=[],s=0,a=e.length;for(;a>s;s++)r=e[s],r.style&&(o[s]=q.get(r,"olddisplay"),n=r.style.display,t?(o[s]||"none"!==n||(r.style.display=""),""===r.style.display&&Lt(r)&&(o[s]=q.access(r,"olddisplay",Rt(r.nodeName)))):o[s]||(i=Lt(r),(n&&"none"!==n||!i)&&q.set(r,"olddisplay",i?n:x.css(r,"display"))));for(s=0;a>s;s++)r=e[s],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[s]||"":"none"));return e}x.fn.extend({css:function(e,t){return x.access(this,function(e,t,n){var r,i,o={},s=0;if(x.isArray(t)){for(r=qt(e),i=t.length;i>s;s++)o[t[s]]=x.css(e,t[s],!1,r);return o}return n!==undefined?x.style(e,t,n):x.css(e,t)},e,t,arguments.length>1)},show:function(){return Ht(this,!0)},hide:function(){return Ht(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Lt(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=vt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=x.camelCase(t),u=e.style;return t=x.cssProps[a]||(x.cssProps[a]=At(u,a)),s=x.cssHooks[t]||x.cssHooks[a],n===undefined?s&&"get"in s&&(i=s.get(e,!1,r))!==undefined?i:u[t]:(o=typeof n,"string"===o&&(i=kt.exec(n))&&(n=(i[1]+1)*i[2]+parseFloat(x.css(e,t)),o="number"),null==n||"number"===o&&isNaN(n)||("number"!==o||x.cssNumber[a]||(n+="px"),x.support.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),s&&"set"in s&&(n=s.set(e,n,r))===undefined||(u[t]=n)),undefined)}},css:function(e,t,n,r){var i,o,s,a=x.camelCase(t);return t=x.cssProps[a]||(x.cssProps[a]=At(e.style,a)),s=x.cssHooks[t]||x.cssHooks[a],s&&"get"in s&&(i=s.get(e,!0,n)),i===undefined&&(i=vt(e,t,r)),"normal"===i&&t in St&&(i=St[t]),""===n||n?(o=parseFloat(i),n===!0||x.isNumeric(o)?o||0:i):i}}),vt=function(e,t,n){var r,i,o,s=n||qt(e),a=s?s.getPropertyValue(t)||s[t]:undefined,u=e.style;return s&&(""!==a||x.contains(e.ownerDocument,e)||(a=x.style(e,t)),Ct.test(a)&&wt.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=s.width,u.width=r,u.minWidth=i,u.maxWidth=o)),a};function Ot(e,t,n){var r=Tt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function Ft(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,s=0;for(;4>o;o+=2)"margin"===n&&(s+=x.css(e,n+jt[o],!0,i)),r?("content"===n&&(s-=x.css(e,"padding"+jt[o],!0,i)),"margin"!==n&&(s-=x.css(e,"border"+jt[o]+"Width",!0,i))):(s+=x.css(e,"padding"+jt[o],!0,i),"padding"!==n&&(s+=x.css(e,"border"+jt[o]+"Width",!0,i)));return s}function Pt(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=qt(e),s=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=vt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Ct.test(i))return i;r=s&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+Ft(e,t,n||(s?"border":"content"),r,o)+"px"}function Rt(e){var t=o,n=Nt[e];return n||(n=Mt(e,t),"none"!==n&&n||(xt=(xt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(xt[0].contentWindow||xt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=Mt(e,t),xt.detach()),Nt[e]=n),n}function Mt(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,t){x.cssHooks[t]={get:function(e,n,r){return n?0===e.offsetWidth&&bt.test(x.css(e,"display"))?x.swap(e,Et,function(){return Pt(e,t,r)}):Pt(e,t,r):undefined},set:function(e,n,r){var i=r&&qt(e);return Ot(e,n,r?Ft(e,t,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,t){return t?x.swap(e,{display:"inline-block"},vt,[e,"marginRight"]):undefined}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,t){x.cssHooks[t]={get:function(e,n){return n?(n=vt(e,t),Ct.test(n)?x(e).position()[t]+"px":n):undefined}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+jt[r]+t]=o[r]||o[r-2]||o[0];return i}},wt.test(e)||(x.cssHooks[e+t].set=Ot)});var Wt=/%20/g,$t=/\[\]$/,Bt=/\r?\n/g,It=/^(?:submit|button|image|reset|file)$/i,zt=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&zt.test(this.nodeName)&&!It.test(e)&&(this.checked||!ot.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(Bt,"\r\n")}}):{name:t.name,value:n.replace(Bt,"\r\n")}}).get()}}),x.param=function(e,t){var n,r=[],i=function(e,t){t=x.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(t===undefined&&(t=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){i(this.name,this.value)});else for(n in e)_t(n,e[n],t,i);return r.join("&").replace(Wt,"+")};function _t(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||$t.test(e)?r(e,i):_t(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)_t(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)
},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var Xt,Ut,Yt=x.now(),Vt=/\?/,Gt=/#.*$/,Jt=/([?&])_=[^&]*/,Qt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Kt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Zt=/^(?:GET|HEAD)$/,en=/^\/\//,tn=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,nn=x.fn.load,rn={},on={},sn="*/".concat("*");try{Ut=i.href}catch(an){Ut=o.createElement("a"),Ut.href="",Ut=Ut.href}Xt=tn.exec(Ut.toLowerCase())||[];function un(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function ln(e,t,n,r){var i={},o=e===on;function s(a){var u;return i[a]=!0,x.each(e[a]||[],function(e,a){var l=a(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):undefined:(t.dataTypes.unshift(l),s(l),!1)}),u}return s(t.dataTypes[0])||!i["*"]&&s("*")}function cn(e,t){var n,r,i=x.ajaxSettings.flatOptions||{};for(n in t)t[n]!==undefined&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,t,n){if("string"!=typeof e&&nn)return nn.apply(this,arguments);var r,i,o,s=this,a=e.indexOf(" ");return a>=0&&(r=e.slice(a),e=e.slice(0,a)),x.isFunction(t)?(n=t,t=undefined):t&&"object"==typeof t&&(i="POST"),s.length>0&&x.ajax({url:e,type:i,dataType:"html",data:t}).done(function(e){o=arguments,s.html(r?x("<div>").append(x.parseHTML(e)).find(r):e)}).complete(n&&function(e,t){s.each(n,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ut,type:"GET",isLocal:Kt.test(Xt[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":sn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?cn(cn(e,x.ajaxSettings),t):cn(x.ajaxSettings,e)},ajaxPrefilter:un(rn),ajaxTransport:un(on),ajax:function(e,t){"object"==typeof e&&(t=e,e=undefined),t=t||{};var n,r,i,o,s,a,u,l,c=x.ajaxSetup({},t),p=c.context||c,f=c.context&&(p.nodeType||p.jquery)?x(p):x.event,h=x.Deferred(),d=x.Callbacks("once memory"),g=c.statusCode||{},m={},y={},v=0,b="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===v){if(!o){o={};while(t=Qt.exec(i))o[t[1].toLowerCase()]=t[2]}t=o[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===v?i:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return v||(e=y[n]=y[n]||e,m[e]=t),this},overrideMimeType:function(e){return v||(c.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>v)for(t in e)g[t]=[g[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||b;return n&&n.abort(t),k(0,t),this}};if(h.promise(T).complete=d.add,T.success=T.done,T.error=T.fail,c.url=((e||c.url||Ut)+"").replace(Gt,"").replace(en,Xt[1]+"//"),c.type=t.method||t.type||c.method||c.type,c.dataTypes=x.trim(c.dataType||"*").toLowerCase().match(w)||[""],null==c.crossDomain&&(a=tn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===Xt[1]&&a[2]===Xt[2]&&(a[3]||("http:"===a[1]?"80":"443"))===(Xt[3]||("http:"===Xt[1]?"80":"443")))),c.data&&c.processData&&"string"!=typeof c.data&&(c.data=x.param(c.data,c.traditional)),ln(rn,c,t,T),2===v)return T;u=c.global,u&&0===x.active++&&x.event.trigger("ajaxStart"),c.type=c.type.toUpperCase(),c.hasContent=!Zt.test(c.type),r=c.url,c.hasContent||(c.data&&(r=c.url+=(Vt.test(r)?"&":"?")+c.data,delete c.data),c.cache===!1&&(c.url=Jt.test(r)?r.replace(Jt,"$1_="+Yt++):r+(Vt.test(r)?"&":"?")+"_="+Yt++)),c.ifModified&&(x.lastModified[r]&&T.setRequestHeader("If-Modified-Since",x.lastModified[r]),x.etag[r]&&T.setRequestHeader("If-None-Match",x.etag[r])),(c.data&&c.hasContent&&c.contentType!==!1||t.contentType)&&T.setRequestHeader("Content-Type",c.contentType),T.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+("*"!==c.dataTypes[0]?", "+sn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)T.setRequestHeader(l,c.headers[l]);if(c.beforeSend&&(c.beforeSend.call(p,T,c)===!1||2===v))return T.abort();b="abort";for(l in{success:1,error:1,complete:1})T[l](c[l]);if(n=ln(on,c,t,T)){T.readyState=1,u&&f.trigger("ajaxSend",[T,c]),c.async&&c.timeout>0&&(s=setTimeout(function(){T.abort("timeout")},c.timeout));try{v=1,n.send(m,k)}catch(C){if(!(2>v))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,t,o,a){var l,m,y,b,w,C=t;2!==v&&(v=2,s&&clearTimeout(s),n=undefined,i=a||"",T.readyState=e>0?4:0,l=e>=200&&300>e||304===e,o&&(b=pn(c,T,o)),b=fn(c,b,T,l),l?(c.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(x.lastModified[r]=w),w=T.getResponseHeader("etag"),w&&(x.etag[r]=w)),204===e||"HEAD"===c.type?C="nocontent":304===e?C="notmodified":(C=b.state,m=b.data,y=b.error,l=!y)):(y=C,(e||!C)&&(C="error",0>e&&(e=0))),T.status=e,T.statusText=(t||C)+"",l?h.resolveWith(p,[m,C,T]):h.rejectWith(p,[T,C,y]),T.statusCode(g),g=undefined,u&&f.trigger(l?"ajaxSuccess":"ajaxError",[T,c,l?m:y]),d.fireWith(p,[T,C]),u&&(f.trigger("ajaxComplete",[T,c]),--x.active||x.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,t){return x.get(e,undefined,t,"script")}}),x.each(["get","post"],function(e,t){x[t]=function(e,n,r,i){return x.isFunction(n)&&(i=i||r,r=n,n=undefined),x.ajax({url:e,type:t,dataType:i,data:n,success:r})}});function pn(e,t,n){var r,i,o,s,a=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),r===undefined&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in a)if(a[i]&&a[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}s||(s=i)}o=o||s}return o?(o!==u[0]&&u.unshift(o),n[o]):undefined}function fn(e,t,n,r){var i,o,s,a,u,l={},c=e.dataTypes.slice();if(c[1])for(s in e.converters)l[s.toLowerCase()]=e.converters[s];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(s=l[u+" "+o]||l["* "+o],!s)for(i in l)if(a=i.split(" "),a[1]===o&&(s=l[u+" "+a[0]]||l["* "+a[0]])){s===!0?s=l[i]:l[i]!==!0&&(o=a[0],c.unshift(a[1]));break}if(s!==!0)if(s&&e["throws"])t=s(t);else try{t=s(t)}catch(p){return{state:"parsererror",error:s?p:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===undefined&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),x.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=x("<script>").prop({async:!0,charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&i("error"===e.type?404:200,e.type)}),o.head.appendChild(t[0])},abort:function(){n&&n()}}}});var hn=[],dn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=hn.pop()||x.expando+"_"+Yt++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,s,a=t.jsonp!==!1&&(dn.test(t.url)?"url":"string"==typeof t.data&&!(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&dn.test(t.data)&&"data");return a||"jsonp"===t.dataTypes[0]?(i=t.jsonpCallback=x.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,a?t[a]=t[a].replace(dn,"$1"+i):t.jsonp!==!1&&(t.url+=(Vt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return s||x.error(i+" was not called"),s[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){s=arguments},r.always(function(){e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,hn.push(i)),s&&x.isFunction(o)&&o(s[0]),s=o=undefined}),"script"):undefined}),x.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(e){}};var gn=x.ajaxSettings.xhr(),mn={0:200,1223:204},yn=0,vn={};e.ActiveXObject&&x(e).on("unload",function(){for(var e in vn)vn[e]();vn=undefined}),x.support.cors=!!gn&&"withCredentials"in gn,x.support.ajax=gn=!!gn,x.ajaxTransport(function(e){var t;return x.support.cors||gn&&!e.crossDomain?{send:function(n,r){var i,o,s=e.xhr();if(s.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(i in e.xhrFields)s[i]=e.xhrFields[i];e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(i in n)s.setRequestHeader(i,n[i]);t=function(e){return function(){t&&(delete vn[o],t=s.onload=s.onerror=null,"abort"===e?s.abort():"error"===e?r(s.status||404,s.statusText):r(mn[s.status]||s.status,s.statusText,"string"==typeof s.responseText?{text:s.responseText}:undefined,s.getAllResponseHeaders()))}},s.onload=t(),s.onerror=t("error"),t=vn[o=yn++]=t("abort"),s.send(e.hasContent&&e.data||null)},abort:function(){t&&t()}}:undefined});var xn,bn,wn=/^(?:toggle|show|hide)$/,Tn=RegExp("^(?:([+-])=|)("+b+")([a-z%]*)$","i"),Cn=/queueHooks$/,kn=[An],Nn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Tn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),s=(x.cssNumber[e]||"px"!==o&&+r)&&Tn.exec(x.css(n.elem,e)),a=1,u=20;if(s&&s[3]!==o){o=o||s[3],i=i||[],s=+r||1;do a=a||".5",s/=a,x.style(n.elem,e,s+o);while(a!==(a=n.cur()/r)&&1!==a&&--u)}return i&&(s=n.start=+s||+r||0,n.unit=o,n.end=i[1]?s+(i[1]+1)*i[2]:+i[2]),n}]};function En(){return setTimeout(function(){xn=undefined}),xn=x.now()}function Sn(e,t,n){var r,i=(Nn[t]||[]).concat(Nn["*"]),o=0,s=i.length;for(;s>o;o++)if(r=i[o].call(n,t,e))return r}function jn(e,t,n){var r,i,o=0,s=kn.length,a=x.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=xn||En(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,s=0,u=l.tweens.length;for(;u>s;s++)l.tweens[s].run(o);return a.notifyWith(e,[l,o,n]),1>o&&u?n:(a.resolveWith(e,[l]),!1)},l=a.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:xn||En(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?a.resolveWith(e,[l,t]):a.rejectWith(e,[l,t]),this}}),c=l.props;for(Dn(c,l.opts.specialEasing);s>o;o++)if(r=kn[o].call(l,e,c,l.opts))return r;return x.map(c,Sn,l),x.isFunction(l.opts.start)&&l.opts.start.call(e,l),x.fx.timer(x.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function Dn(e,t){var n,r,i,o,s;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),s=x.cssHooks[r],s&&"expand"in s){o=s.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(jn,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Nn[n]=Nn[n]||[],Nn[n].unshift(t)},prefilter:function(e,t){t?kn.unshift(e):kn.push(e)}});function An(e,t,n){var r,i,o,s,a,u,l=this,c={},p=e.style,f=e.nodeType&&Lt(e),h=q.get(e,"fxshow");n.queue||(a=x._queueHooks(e,"fx"),null==a.unqueued&&(a.unqueued=0,u=a.empty.fire,a.empty.fire=function(){a.unqueued||u()}),a.unqueued++,l.always(function(){l.always(function(){a.unqueued--,x.queue(e,"fx").length||a.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(p.display="inline-block")),n.overflow&&(p.overflow="hidden",l.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],wn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show")){if("show"!==i||!h||h[r]===undefined)continue;f=!0}c[r]=h&&h[r]||x.style(e,r)}if(!x.isEmptyObject(c)){h?"hidden"in h&&(f=h.hidden):h=q.access(e,"fxshow",{}),o&&(h.hidden=!f),f?x(e).show():l.done(function(){x(e).hide()}),l.done(function(){var t;q.remove(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)s=Sn(f?h[r]:0,r,l),r in h||(h[r]=s.start,f&&(s.end=s.start,s.start="width"===r||"height"===r?1:0))}}function Ln(e,t,n,r,i){return new Ln.prototype.init(e,t,n,r,i)}x.Tween=Ln,Ln.prototype={constructor:Ln,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=Ln.propHooks[this.prop];return e&&e.get?e.get(this):Ln.propHooks._default.get(this)},run:function(e){var t,n=Ln.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Ln.propHooks._default.set(this),this}},Ln.prototype.init.prototype=Ln.prototype,Ln.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Ln.propHooks.scrollTop=Ln.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(qn(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Lt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),s=function(){var t=jn(this,x.extend({},e),o);(i||q.get(this,"finish"))&&t.stop(!0)};return s.finish=s,i||o.queue===!1?this.each(s):this.queue(o.queue,s)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=undefined),t&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=x.timers,s=q.get(this);if(i)s[i]&&s[i].stop&&r(s[i]);else for(i in s)s[i]&&s[i].stop&&Cn.test(i)&&r(s[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));(t||!n)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=q.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,s=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;s>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function qn(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=jt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:qn("show"),slideUp:qn("hide"),slideToggle:qn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=Ln.prototype.init,x.fx.tick=function(){var e,t=x.timers,n=0;for(xn=x.now();t.length>n;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||x.fx.stop(),xn=undefined},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){bn||(bn=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(bn),bn=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===undefined?this:this.each(function(t){x.offset.setOffset(this,e,t)});var t,n,i=this[0],o={top:0,left:0},s=i&&i.ownerDocument;if(s)return t=s.documentElement,x.contains(t,i)?(typeof i.getBoundingClientRect!==r&&(o=i.getBoundingClientRect()),n=Hn(s),{top:o.top+n.pageYOffset-t.clientTop,left:o.left+n.pageXOffset-t.clientLeft}):o},x.offset={setOffset:function(e,t,n){var r,i,o,s,a,u,l,c=x.css(e,"position"),p=x(e),f={};"static"===c&&(e.style.position="relative"),a=p.offset(),o=x.css(e,"top"),u=x.css(e,"left"),l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1,l?(r=p.position(),s=r.top,i=r.left):(s=parseFloat(o)||0,i=parseFloat(u)||0),x.isFunction(t)&&(t=t.call(e,n,a)),null!=t.top&&(f.top=t.top-a.top+s),null!=t.left&&(f.left=t.left-a.left+i),"using"in t?t.using.call(e,f):p.css(f)}},x.fn.extend({position:function(){if(this[0]){var e,t,n=this[0],r={top:0,left:0};return"fixed"===x.css(n,"position")?t=n.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(r=e.offset()),r.top+=x.css(e[0],"borderTopWidth",!0),r.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-r.top-x.css(n,"marginTop",!0),left:t.left-r.left-x.css(n,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,n){var r="pageYOffset"===n;x.fn[t]=function(i){return x.access(this,function(t,i,o){var s=Hn(t);return o===undefined?s?s[n]:t[i]:(s?s.scrollTo(r?e.pageXOffset:o,r?o:e.pageYOffset):t[i]=o,undefined)},t,i,arguments.length,null)}});function Hn(e){return x.isWindow(e)?e:9===e.nodeType&&e.defaultView}x.each({Height:"height",Width:"width"},function(e,t){x.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){x.fn[r]=function(r,i){var o=arguments.length&&(n||"boolean"!=typeof r),s=n||(r===!0||i===!0?"margin":"border");return x.access(this,function(t,n,r){var i;return x.isWindow(t)?t.document.documentElement["client"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body["scroll"+e],i["scroll"+e],t.body["offset"+e],i["offset"+e],i["client"+e])):r===undefined?x.css(t,n,s):x.style(t,n,r,s)},t,o?r:undefined,o,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}),"object"==typeof e&&"object"==typeof e.document&&(e.jQuery=e.$=x)})(window);
﻿<?php
/**
* Deutsch translation
*
* @author   Revo
* @author   Nero51282
* @version  1.1
*/
$translate = array(
	'Access server' => 'Auf Server zugreifen',
	'Access relay' => 'Auf Relay zugreifen',
	'Disconnect' => 'Trennen',
	'Servers' => 'Server',
	'Server' => 'Server',
	'Password' => 'Passwort',
	'Admin level' => 'Admin Level',
	'Connection' => 'Verbindung',
	'Please put a password.' => 'Bitte erstellen Sie ein Passwort.',
	'Connection error' => 'Verbindungs Fehler',
	'Connection error: invalid session.' => 'Verbindungs Fehler : invalid Session.',
	'Servers configuration' => 'Server Konfiguration',
	'Online configuration' => 'Online Konfiguration',
	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'Es ist Ihre erste Verbindung und kein Server ist konfiguriert. Wählen Sie ein Passwort, um Ihre Server zu konfigurieren.',
	'Unable to save password.' => 'Passwort kann nicht gespeichert werden.',
	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Online Konfiguration is deaktiviert. Benutzen Sie "./config/servers.cfg.php".',
	'Offline server.' => 'Offline Server.',
	'Authentication error.' => 'Authentifizierung Fehler.',
	'Add to favourite' => 'Zu Favoriten hinzufügen',
	'Current map' => 'Laufende Map',
	'Name' => 'Name',
	'Author' => 'Autor',
	'Environment' => 'Umgebung',
	'Map UId' => 'Map UId',
	'Game mode' => 'Spiel Modus',
	'No thumbnail' => 'Keine Vorschau',
	'Server name' => 'Server Name',
	'Status' => 'Status',
	'Server login' => 'Server Login',
	'Connected on' => 'Verbunden zu',
	'Dedicated version' => 'Server Version',
	'Statistics' => 'Statistiken',
	'Uptime' => 'Läuft seit',
	'Number of connections' => 'Anzahl der Verbindungen',
	'Average connection time' => 'Verbindungszeit Ø',
	'Average number of players' => 'Spieler Anzahl Ø',
	'Recv net rate' => 'Empfangsrate',
	'Send net rate' => 'Senderate',
	'Total receiving size' => 'Totaler Empfang',
	'Total sending size' => 'Totale Emission',
	'Players' => 'Spieler',
	'Detailed mode' => 'Detaillierte Modus',
	'Simple mode' => 'Einfacher Modus',
	'Nickname' => 'Nickname',
	'Login' => 'Login',
	'For the selection' => 'Für die Auswahl',
	'Ban' => 'Sperren',
	'Kick' => 'Kicken',
	'Spectator' => 'Zuschauer',
	'Player' => 'Spieler',
	'Team' => 'Team',
	'Guest' => 'Einladen',
	'Ignore' => 'Auslassen',
	'Red team' => 'Rote Team',
	'Blue team' => 'Blaue Team',
	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Ergebnisse wurden geändert : Les scores ont été modifiés : $00fblaue Team$fff hat !scoreTeamBlue und l\'$f00rote Team $fffhat !scoreTeamRed',
	'Server options' => 'Server Optionen',
	'General' => 'Allgemein',
	'Comment' => 'Kommentar',
	'Player password' => 'Spieler Passwort',
	'Spectator password' => 'Zuschauer Passwort',
	'Nb max of players' => 'Max Spieler Anzahl',
	'Next value' => 'Nächster Wert',
	'Nb max of spectators' => 'Max Zuschauer Anzahl',
	'Advanced' => 'Erweitert',
	'P2P Upload' => 'P2P Upload',
	'P2P Download' => 'P2P Download',
	'Ladder mode' => 'Ladder Modus',
	'Vehicles quality' => 'Fahrzeuge Qualität',
	'Vote expiration' => 'Wahl Ablaufzeit',
	'sec' => 'sek', // Second
	'Vote ratio' => 'Wahl Ratio',
	'Hidden server' => 'Versteckte Server',
	'Map download' => 'Maps Download',
	'Replays auto save' => 'Replays automatik speichern',
	'Buddy notification' => 'Buddy Benachrichtigung',
	'Save' => 'Speichern',
	'Inactive' => 'Inaktiv',
	'Forced' => 'Erzwungen',
	'Fast' => 'Schnell',
	'High' => 'Hoch',
	'Game infos' => 'Spiel-Info',
	'Game information' => 'Spiel-Info',
	'Color' => 'Farbe',
	'Black' => 'Schwarz',
	'Red' => 'Rot',
	'Green' => 'Grün',
	'Blue' => 'Blau',
	'Orange' => 'Orange',
	'Pink' => 'Rosa',
	'Purple' => 'Violett',
	'Grey' => 'Grau',
	'White' => 'Weiß',
	'Message destination' => 'Nachrichtenziel',
	'Chat' => 'Chat',
	'Show server lines' => 'Server-Linien zeigen',
	'Hide server lines' => 'Server-Linien ausblenden',
	'Default color: yellow' => 'Standard-Farbe : gelb',
	'Message' => 'Nachricht',
	'Destination' => 'Ziel',
	'Send' => 'Senden',
	'Unable to create the folder' => 'Das Verzeichnis konnte nicht erstellt werden',
	'Unable to rename the folder' => 'Das Verzeichnis konnte nicht umbenannt werden',
	'Unable to move the folder' => 'Das Verzeichnis konnte nicht verschoben werden',
	'Unable to delete the folder' => 'Das Verzeichnis konnte nicht gelöscht werden',
	'List' => 'Liste',
	'Go to the current map' => 'Zur aktuelle Map',
	'Map' => 'Map',
	'Delete' => 'Entfernen',
	'Move after the current map' => 'Hinter die aktuelle Map verschieben',
	'Unable to rename the map' => 'Die Map konnte nicht umbenannt werden',
	'Unable to move the map' => 'Die Map konnte nicht verschoben werden',
	'Unable to delete the map' => 'Die Map konnte nicht gelöscht werden',
	'Local' => 'Lokal',
	'Do you really want to remove this selection?' => 'Möchten Sie diese Auswahl wirklich entfernen?',
	'Move' => 'Verschieben',
	'Rename' => 'Umbennenen',
	'Download' => 'Herunterladen',
	'Insert' => 'Einfügen',
	'Add' => 'Hinzufügen',
	'Cancel' => 'Abbrechen',
	'Replace the special characters' => 'Sonderzeichen ersetzen',
	'in the folder:' => 'im Ordner:',
	'Root' => 'Root',
	'The map,is currently used by the server.' => 'Die Map wird momentan vom Server verwendet.',
	'MatchSettings' => 'MatchSettings',
	'Contains' => 'Enthält',
	'Modified' => 'Geändert',
	'Edit' => 'Editieren',
	'Load' => 'Laden',
	'Save ' => 'Speichern',
	'Create' => 'Erstellen',
	'Unable to save the MatchSettings' => 'Unmöglich, MatchSettings zu speichern',
	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'MatchSettings "!matchSettingName" wurde erfolgreich in Ordner erstellt',
	'a MatchSettings' => 'ein MatchSettings',
	'Create a MatchSettings' => 'Erstellen ein MatchSettings',
	'MatchSettings name' => 'MatchSettings Name',
	'Maps' => 'Maps',
	'Make selection' => 'Auswahl treffen',
	'Import all folder' => 'ganze Ordner importieren',
	'Select' => 'Wählen',
	'MatchSettings selected maps:' => 'MatchSettings ausgewählte Maps:',
	'View the MatchSettings selection' => 'MatchSettings Auswahl ansehen',
	'MatchSettings selection' => 'MatchSettings Auswahl',
	'Remove map from the selection' => 'Map von der Auswahl entfernen',
	'Close' => 'Schließen',
	'HotSeat' => 'HotSeat',
	'Time limit' => 'Zeitlimit',
	'Rounds count' => 'Runden Zahl',
	'Filter' => 'Filter',
	'Lan' => 'Lan',
	'Internet' => 'Internet',
	'Solo' => 'Solo',
	'Sort index' => 'Sortierungsindex',
	'Random map order' => 'Zufällige Maps Ordnung',
	'Default game mode' => 'Game Mode Standardeinstellung',
	'No map selected for the MatchSettings.' => 'Keine Map ist für MatchSettings ausgewählt.',
	'The MatchSettings name already exists! It will be overwritten.' => 'Diese MatchSettings Name ist schon verwendet! Die wird überschrieben.',
	'Order' => 'Ordnen',
	'Automatic sort' => 'Automatische Sortierung',
	'Random' => 'Zufällig',
	'Manual sort' => 'Manuelle Sortierung',
	'Save the current MatchSettings' => 'MatchSettings speichern',
	'Reset' => 'Neu stellen',
	'Transfer mode' => 'Transfer-Modus',
	'at the end of list' => 'zum Ende der Liste',
	'after current map' => 'hinter aktuelle Map',
	'only in the folder' => 'nur in den Ordner',
	'Options' => 'Optionen',
	'Go to the maps list when upload is complete' => 'Zur Maps-Liste gehen, wenn Upload fertig ist',
	'Upload' => 'Upload',
	'Failed' => 'Gescheitert',
	'Upload a file' => 'Datei hochladen',
	'Drop files here to upload' => 'Dateien hier ablegen zum Hochladen',
	'Upload not finished' => 'Upload nicht fertig',
	'from' => 'von',
	'Kb' => 'Kb',
	'Mb' => 'Mb',
	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} hat eine ungültige Dateierweiterung. Erlaubte Formate sind {extensions}.',
	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} ist zu groß. Maximale Dateigröße ist {sizeLimit}.',
	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} ist zu klein. Minimale Dateigröße ist {minSizeLimit}.',
	'{file} is empty, please select files again without it.' => '{file} ist leer. Wählen Sie noch einmal bitte.',
	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Die Dateien werden hochgeladen. Wenn Sie jetzt die Seite verlassen wird der Upload abgebrochen.',
	'No file was uploaded' => 'Keine Datei wurde hochgeladen',
	'The file is empty.' => 'Die Datei ist leer.',
	'The file size is too large.' => 'Die Dateigröße ist zu groß.',
	'The file has invalid extension (allowed extensions:' => 'Die Datei hat eine ungültige Dateierweiterung (erlaubte Dateierweiterungen:',
	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Die Datai wurde nicht hochgeladen. Der Upload wurde abgebrochen oder ein Server-Fehler ist aufgetreten.',
	'Server error. The upload destination folder isn\'t writable.' => 'Server Fehler. Der Upload Zielordner ist nicht beschreibbar.',
	'Plugins' => 'Plugins',
	'plugin installed' => 'Plugin installiert',
	'plugins installed' => 'Plugins installiert',
	'Cannot include another plugins config file.' => 'Keine weitere Plugins Konfiguration Datei kann addiert werden.',
	'Variable "$PLUGINS" not found.' => 'Variable "$PLUGINS" nicht gefunden.',
	'Plugins are extensions to add features to Adminserv.' => 'Plugins lassen Sie neue Funktionen zu AdminServ hinzufügen.',
	'Install a plugin' => 'Wie installiert man Plugins??',
	'See all plugins:' => 'Zeige alle Plugins:',
	'Click here' => 'Klicken Sie hier',
	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Entpacken sie das Plugin und verschieben Sie den Inhalt in den &laquo; plugins &raquo; Ordner von AdminServ.',
	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'Fügen Sie den Namen des Plugin Ordners in der Konfiguratiosdatei der Erweiterungen ein(extension.cfg.php).',
	'Create a new plugin' => 'Wie erstellt man sein eigenes Plugin?',
	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>Um ein Plugin zu erstellen, gehe in de Plugin Orner und kopiere den Ordner _newplugin. Ersetze die Werte in der config.ini Datei und bennene den Order um.<br />Dort befinden sich zwei PHP Dateien:</p><ul><li>script.php : Diese Datei wird vor dem Header der Seite ausgeführt. Hier werden alle Plugin Scripte plaziert.</li><li>view.php : Diese Datei ist für die Anzeige des Plugins verantworlich und wird nach dem Header der seite ausgeführt. Hier wird der ganze HTML Code plaziert.</li></ul><p>Die benötigten Recourcen (classes, js, css) können Sie in die Dateien einbinden.</p>',
	'Unable to delete the playlist' => 'Unmöglich, die Playlist zu löschen',
	'Player login' => 'Spieler Login',
	'Clean the list' => 'Liste reinigen',
	'The list is already empty.' => 'Die Liste ist schon Leer.',
	'No player' => 'Kein Spieler auf dem Server',
	'IP address' => 'IP Adresse',
	'Client' => 'Client',
	'Blacklist' => 'Blacklist',
	'Remove from the list' => 'Aus der Liste löschen',
	'Select a player' => 'Wählen Sie einen Spieler',
	'Enter another login' => 'Geben Sie einen anderen Login',
	'Add in the' => 'Addieren zu',
	'Playlists' => 'Playlists',
	'Playlist' => 'Playlist',
	'Type' => 'Art',
	'Playlist name' => 'Playlist Name',
	'New playlist' => 'Neue Playlist',
	'players' => 'Spieler',
	'player' => 'Spieler',
	'No playlist' => 'Kein Playlist wird gefunden',
	'You are not allowed to configure the servers' => 'Sie sind nicht erlaubt, Servers zu Konfigurieren.',
	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Kein Server ist verfügbar. Um einen Server zu addieren, Konfigurieren Sie die Datei "config/servers.cfg.php"',
	'The servers configuration file isn\'t recognized by AdminServ.' => 'Die Datei für die Servers Konfiguration wird nicht von AdminServ anerkannt.',
	'This server has been duplicated.' => 'Dieser Server wurde erfolgreich dupliziert.',
	'Unable to duplicate server.' => 'Unmöglich, den Server zu vervielfältigen.',
	'copy' => 'Kopie',
	'Servers list' => 'Servers Liste',
	'Address' => 'Adresse',
	'Port' => 'Port',
	'SuperAdmin level' => 'SuperAdmin Stufe',
	'User level' => 'User Stufe',
	'Manage' => 'Management',
	'None' => 'Keiner',
	'Local network' => 'Lokalen Netzwerk',
	'All' => 'Alle',
	'Removed' => 'Entfernt',
	'Missing' => 'Vermisst',
	'No server' => 'Kein Server',
	'servers' => 'Server',
	'server' => 'Server',
	'Duplicate' => 'Vervielfältigen',
	'Modify' => 'Ändern',
	'The "!serverName" server has been deleted.' => 'Der Server"!serverName" wurde gelöscht.',
	'This server has been modified.' => 'Dieser Server wurde modifiziert.',
	'Unable to modify the server.' => 'Unmöglich, der Server zu modifizieren.',
	'This server has been added.' => 'Der Server wurde erfolgreich addiert.',
	'Unable to add the server.' => 'Unmöglich, der Server zu addieren.',
	'Add server' => 'Server hinzufügen',
	'Edit server' => 'Server bearbeiten',
	'Back' => 'Zurück',
	'Connection information' => 'Verbindung Informationen',
	'Server name without color' => 'Server Name ohne Farbe',
	'IP address or domain name' => 'IP Adresse oder Domain-Name',
	'XMLRPC port' => 'XMLRPC Port',
	'Port for remote control' => 'Port für Fernsteuerung',
	'Optionnal information' => 'optionale Angaben',
	'Server MatchSettings' => 'Server MatchSettings',
	'Current server MatchSettings name' => 'Server\'s aktuelle MatchSettings Name',
	'Possible values for the admin level:' => 'Mögliche Werte für Admin Stufe :',
	'all => all access' => 'all => Zugriff zu alle',
	'local => local network access' => 'local => Lokalen Netzwerk Zugriff',
	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => Zugriff zu einer oder mehreren IP Adressen',
	'none => removed from the access list' => 'none => aus der Zugriffliste entfernt',
	'No server available' => 'Keiner Server ist verfügbar',
	'No game mode available' => 'Kein Spielmodus ist verfügbar',
	'Map end time' => 'Map Ende Zeit',
	'Round/lap end time' => 'Round/Lap Ende Zeit',
	'Respawn' => 'Respawn',
	'Default' => 'Standard',
	'Auto (based on map)' => 'Auto (hängt von der Map)',
	'Choose time' => 'Zeit Wählen',
	'Return to the default value' => 'Zurück auf den Standardwert',
	'All WarmUp duration' => 'Alle WarmUps Dauer',
	'Enable' => 'Aktivieren',
	'Disable' => 'Deaktivieren',
	'Force show of all opponents' => 'Force show alle Gegner',
	'Let player choose' => 'Lassen Spieler wählen',
	'All opponents' => 'Alle Gegner',
	'minimal opponents' => 'minimale Gegner',
	'Choose opponents number' => 'Gegner Nummer Wählen',
	'Script name' => 'Script Name',
	'Use new rules' => 'Neue Regeln verwenden',
	'Points limit' => 'Punkte Begrenzung',
	'Custom points limit' => 'Benutzerdefinierte Punkte Begrenzung',
	'Force laps' => 'Lap enden',
	'Start synchronization period' => 'Synchronisierungszeit am Start',
	'Maximal points' => 'Maximal Punkte',
	'Number of laps' => 'Laps Nummer',
	'Rounds per map' => 'Runden pro Map',
	'Number of winners' => 'Gewinner Nummer',
	'No player available' => 'Kein Spieler zur Verfügung',
	'New' => 'Neu',
	'Parent folder' => 'Vorgängerordner',
	'Folder options' => 'Ordner-Optionen',
	'Do you really want to remove this folder !currentDir?' => 'Möchten Sie den Ordner !currentDir wirklich entfernen ?',
	'Rename folder' => 'Ordner umbenennen',
	'Move folder' => 'Ordner verschieben',
	'Move folder <b>!currentDir</b> in:' => 'Ordner <b>!currentDir</b> verschieben nach :',
	'The server is not accessible.' => 'Der Server ist nicht verfügbar.',
	'You are not allowed at this admin level' => 'Sie besitzen nicht die benötigten Rechte.',
	'The password doesn\'t match to the server.' => 'Falsche Kennwort.',
	'Client not initialized' => 'client nicht initialisiert',
	'Unknown command' => 'Unbekannter Befehl',
	'$99FThis round is a draw.' => '$99FUnentschiedene Runde.',
	'$99FThe $<$00FBlue team$> wins this round.' => '$99FDas $00Fblaue Team gewinnt diese Runde.',
	'$99FThe $<$F00Red team$> wins this round.' => '$99FDas $F00rote Team gewinnt diese Runde.',
	'maps' => 'Maps',
	'map' => 'Map',
	'No map' => 'Kein Map wird gefunden',
	'matchsettings' => 'Matchsettings',
	'matchsetting' => 'Matchsetting',
	'No matchsetting' => 'Kein Matchsetting',
	'text->XML conversion error' => 'text->XML Konvertierungsfehler',
	'Saving XML file error' => 'XML Datei Speicherungsfehler',
	'The folder "logs" is not writable.' => 'Der Ordner "logs" kann nicht geschrieben werden.',
	'The folder "logs" does not exist.' => 'Der Ordner "logs" existiert nicht.',
	'Unable to create log file:' => 'Unmöglich, die Log Datei zu erstellen :',
	'Unable to add log in file:' => 'Unmöglich, Log zur Datei zu addieren :',
	'This server does not exist' => 'Dieser Server existiert nicht',
	'Change password' => 'Kennwort ändern',
	'Current' => 'Aktuell',
	'The current password doesn\'t match.' => 'Das aktuelle Passwort ist falsch.',
	'The password has been changed.' => 'Das Kennwort wurde geändert.',
	'Not rated' => 'Nicht bewertet',
	'Unable to delete server.' => 'Unmöglich, der Server zu löschen',
	'Guest-Ban' => 'Einladen-Sperren',
	'Access as player' => 'Als Spieler beitreten',
	'Access as spectator' => 'Als Zuschauer beitreten',
	'Disable horns' => 'Deaktivieren Hupen',
	'Current vote' => 'Aktuelle Bewertung',
	'Cancel vote' => 'Abbrechen stimmen',
	'Change order' => 'Ändern Sie die Reihenfolge',
	'Servers order' => 'Server um',
	'This path was not required rights:' => 'Dieser Weg war nicht Rechte erforderlich:',
	'needs' => 'Bedürfnisse',
	'Plugin error: script.php or view.php file is missing.' => 'Plugin-Fehler: script.php oder view.php Datei fehlt.',
	'No server admin levels configured.' => 'Nicht konfiguriert Server Admin Ebenen.',
	'Gold time' => 'Gold Zeit',
	'Cost' => 'Kosten',
	'Team infos' => 'Team Informationen',
	'Script settings' => 'Script-Einstellungen',
	'Script settings updated.' => 'Script-Einstellungen aktualisiert.',
	'Change authentication password' => 'Ändern Sie Passwort-Authentifizierung',
	'You changed the password "!authLevel", remember it at the next connection!' => 'Sie das Passwort geändert "!authLevel", erinnern sie bei der nächsten Verbindung!',
	'Automatic' => 'Automatisch',
	'Choose number' => 'Wählen Sie die Anzahl',
	'Client inputs max latency' => 'Client Eingaben max Latenzzeit',
	'Script info' => 'Informationen',
	'Compatible map types' => 'Kompatibel Maptypen',
	'Script parameters' => 'Skriptparameter',
	'Value' => 'Wert',
	'The server already exist! Change the name.' => 'Der Server existiert bereits! Ändern Sie den Namen.',
);
?>
﻿<?php
/**
* Danish translation
*
* @author   Steppie
* @version  1.0
*/
$translate = array(
	'Access server' => 'Tilslut server',
	'Access relay' => 'Tilslut reply',
	'Disconnect' => 'Afbryd forbindelse',
	'Servers' => 'Servere',
	'Server' => 'Server',
	'Password' => 'Adgangskode',
	'Admin level' => 'Admin niveau',
	'Connection' => 'Opret forbindelse',
	'Please put a password.' => 'Indtast venligst en adgangskode.',
	'Connection error' => 'Forbindelsen fejlede',
	'Connection error: invalid session.' => 'Forbindelsen fejlede: invalid Session.',
	'Servers configuration' => 'Servere Konfiguration',
	'Online configuration' => 'Online Konfiguration',
	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'Det er din første forbindelse. Vælg en adgangskode for at konfigurer dine servere.',
	'Unable to save password.' => 'Adgangskode kan ikke gemmes.',
	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Online Konfiguration er deaktiveret. Brug istedet: "./config/servers.cfg.php".',
	'Offline server.' => 'Offline Server.',
	'Authentication error.' => 'Godkendelse fejlede.',
	'Add to favourite' => 'Tilføj til farvorit',
	'Current map' => 'Nuværende bane',
	'Name' => 'Navn',
	'Author' => 'Forfatter',
	'Environment' => 'Miljø',
	'Map UId' => 'Bane UId',
	'Game mode' => 'Spil stil',
	'No thumbnail' => 'Ingen skitse',
	'Server name' => 'Server Navn',
	'Status' => 'Status',
	'Server login' => 'Server Login',
	'Connected on' => 'Forbind til',
	'Dedicated version' => 'Dedikeret Version',
	'Statistics' => 'Statistik',
	'Uptime' => 'Oppetid',
	'Number of connections' => 'Tilslutnings antal',
	'Average connection time' => 'Gennemsnitlig tilslutning tid',
	'Average number of players' => 'Gennemsnitlig spiller antal',
	'Recv net rate' => 'Upload rate',
	'Send net rate' => 'Download rate',
	'Total receiving size' => 'Total modtaget størrelse',
	'Total sending size' => 'Total sendt størrelse',
	'Players' => 'Spillere',
	'Detailed mode' => 'Detaljeret tilstand',
	'Simple mode' => 'Simpel tilstand',
	'Nickname' => 'Kælenavn',
	'Login' => 'Login',
	'For the selection' => 'For de valgte',
	'Ban' => 'Ban',
	'Kick' => 'Spark ud!',
	'Spectator' => 'Tilskuer',
	'Player' => 'Spiller',
	'Team' => 'Hold',
	'Guest' => 'Gæst',
	'Ignore' => 'Ignorer',
	'Red team' => 'Rød hold',
	'Blue team' => 'Blå hold',
	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Stillingen er blevet ændret : $00fBlå hold$fff har !scoreTeamBlue og $f00Rød hold $fffhar !scoreTeamRed',
	'Server options' => 'Server indstillinger',
	'General' => 'Generelt',
	'Comment' => 'Kommentar',
	'Player password' => 'Spiller adgangskode',
	'Spectator password' => 'Tilskure adgangskode',
	'Nb max of players' => 'Max spiller antal',
	'Next value' => 'Næste værdi',
	'Nb max of spectators' => 'Max tilskure antal',
	'Advanced' => 'Avanceret',
	'P2P Upload' => 'P2P Upload',
	'P2P Download' => 'P2P Download',
	'Ladder mode' => 'Ladder tilstand',
	'Vehicles quality' => 'Model kvalitet',
	'Vote expiration' => 'Afstemning udløb',
	'sec' => 'sek', // Second
	'Vote ratio' => 'Afstemning Ratio',
	'Hidden server' => 'Skjul Server',
	'Map download' => 'Bane Download',
	'Replays auto save' => 'Replays automatisk gem',
	'Buddy notification' => 'Ven notifikation',
	'Save' => 'Gem',
	'Inactive' => 'Inaktiv',
	'Forced' => 'Tvungen',
	'Fast' => 'Hurtig',
	'High' => 'Høj',
	'Game infos' => 'Spil info',
	'Game information' => 'Spil information',
	'Color' => 'Farve',
	'Black' => 'Sort',
	'Red' => 'Rød',
	'Green' => 'Grøn',
	'Blue' => 'Blå',
	'Orange' => 'Orange',
	'Pink' => 'Rosa',
	'Purple' => 'Violet',
	'Grey' => 'Grå',
	'White' => 'Hvid',
	'Message destination' => 'Besked destination',
	'Chat' => 'Chat',
	'Show server lines' => 'Vis server linier',
	'Hide server lines' => 'Skjul server linier',
	'Default color: yellow' => 'Standard farve: gul',
	'Message' => 'Besked',
	'Destination' => 'Destination',
	'Send' => 'Send',
	'Unable to create the folder' => 'Kunne ikke oprette mappe',
	'Unable to rename the folder' => 'Kunne ikke omdøbe mappe',
	'Unable to move the folder' => 'Kunne ikke flytte mappe',
	'Unable to delete the folder' => 'Kunne ikke slette mappe',
	'List' => 'Liste',
	'Go to the current map' => 'Gå til aktuel bane',
	'Map' => 'Bane',
	'Delete' => 'Slet',
	'Move after the current map' => 'Flyt efter aktuelle bane',
	'Unable to rename the map' => 'Kunne ikke omdøbe banen',
	'Unable to move the map' => 'Kunne ikke flytte banen',
	'Unable to delete the map' => 'Kunne ikke slette banen',
	'Local' => 'Lokal',
	'Do you really want to remove this selection?' => 'Ønsker du virkelig at slette disse valgte?',
	'Move' => 'Flyt',
	'Rename' => 'Omdøb',
	'Download' => 'Download',
	'Insert' => 'Indsæt',
	'Add' => 'Tilføj',
	'Cancel' => 'Annuller',
	'Replace the special characters' => 'Udskift specielle karakter',
	'in the folder:' => 'i mappen:',
	'Root' => 'Root',
	'The map,is currently used by the server.' => 'Banen bruges lige nu af serveren',
	'MatchSettings' => 'MatchSettings',
	'Contains' => 'Indholder',
	'Modified' => 'Ændre',
	'Edit' => 'Ændre',
	'Load' => 'Indlæs',
	'Save ' => 'Gem',
	'Create' => 'Opret',
	'Unable to save the MatchSettings' => 'Kunne ikke gemme MatchSettings',
	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'MatchSettings "!matchSettingName" blev med succes oprettet i mappen',
	'a MatchSettings' => 'en MatchSettings',
	'Create a MatchSettings' => 'Opret en MatchSettings',
	'MatchSettings name' => 'MatchSettings Navn',
	'Maps' => 'Baner',
	'Make selection' => 'Udvælg',
	'Import all folder' => 'Importer alle mapper',
	'Select' => 'Vælg',
	'MatchSettings selected maps:' => 'MatchSettings udvalgte baner:',
	'View the MatchSettings selection' => 'Vis MatchSettings udvalgte',
	'MatchSettings selection' => 'MatchSettings udvalgte',
	'Remove map from the selection' => 'Slet bane fra udvalgte',
	'Close' => 'Luk',
	'HotSeat' => 'HotSeat',
	'Time limit' => 'Tids begrænsning',
	'Rounds count' => 'Runde tæller',
	'Filter' => 'Filter',
	'Lan' => 'Lan',
	'Internet' => 'Internet',
	'Solo' => 'Solo',
	'Sort index' => 'Sorter index',
	'Random map order' => 'Tilfældig bane orden',
	'Default game mode' => 'Standard spil tilstand',
	'No map selected for the MatchSettings.' => 'Ingen bane valgt fra MatchSettings.',
	'The MatchSettings name already exists! It will be overwritten.' => 'MatchSettings findes allerede og bliver overskrevet.',
	'Order' => 'Rækkefølge',
	'Automatic sort' => 'Automatisk sorter',
	'Random' => 'Tilfældig',
	'Manual sort' => 'Manuel sortering',
	'Save the current MatchSettings' => 'Gem nuværende MatchSettings',
	'Reset' => 'Reset',
	'Transfer mode' => 'Transfer-Mode',
	'at the end of list' => 'til slutning af liste',
	'after current map' => 'efter aktuelle bane',
	'only in the folder' => 'kun i mappen',
	'Options' => 'Muligheder',
	'Go to the maps list when upload is complete' => 'Gå til bane, når overførslen er færdig',
	'Upload' => 'Upload',
	'Failed' => 'Fejlede',
	'Upload a file' => 'Upload en fil',
	'Drop files here to upload' => 'Drop filer til upload',
	'Upload not finished' => 'Upload er ikke færdig',
	'from' => 'fra',
	'Kb' => 'Kb',
	'Mb' => 'Mb',
	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} er ikke en gyldig filtype. Kun filtyper {extensions} er gyldige.',
	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} er for stor. Maksimal filstørrelse er {sizeLimit}.',
	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} er for lille. Minimal filstørrelse er {minSizeLimit}.',
	'{file} is empty, please select files again without it.' => '{file} er tom, vælg venligst filer igen, uden denne.',
	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Filerne bliver uploadet, hvis du forlader siden nu, vil upload blive annulleret.',
	'No file was uploaded' => 'Ingen filer blev uploadet',
	'The file is empty.' => 'Filen er tom.',
	'The file size is too large.' => 'Filen er for stor.',
	'The file has invalid extension (allowed extensions:' => 'Filen er ikke gyldig (godkendte filtyper:',
	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Filen blev ikke uploadet. Upload blev annulleret eller en server fejl er opstået.',
	'Server error. The upload destination folder isn\'t writable.' => 'Server fejl. Upload folder er skrivebeskyttet.',
	'Plugins' => 'Tilføjelser',
	'plugin installed' => 'Tilføjelse blev installeret',
	'plugins installed' => 'Tilføjelser blev installeret',
	'Cannot include another plugins config file.' => 'Kan ikke inkluder en anden tilføjelses konfig fil.',
	'Variable "$PLUGINS" not found.' => 'Variabel "$PLUGINS" blev ikke fundet.',
	'Plugins are extensions to add features to Adminserv.' => 'Tilføjelser er udvidelser der tilføje funktioner til AdminServ .',
	'Install a plugin' => 'Installer en tilføjelse?',
	'See all plugins:' => 'Se alle tilføjelser :',
	'Click here' => 'Klik her',
	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Udpak tilføjelsen til &laquo; plugins &raquo; mappen i AdminServ.',
	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'I Configuration Extension, tilføjes navnet på den tilføjelsesmappe du lige at tilføjet.',
	'Create a new plugin' => 'Opret en ny tilføjelse ?',
	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values ​​in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>For at oprette en tilføjelse, gå til plugins mappen og kopiere filen _newplugin. Udskift værdierne i config.ini filen og mappe navn <br /> Så er der to PHP-filer:</p><ul><li>script.php: Denne fil indlæses inden header af hjemmesiden. Dette er her hvor alle plugin script vil blive placeret.</li><li>view.php: Denne fil er visningen af pluginet, indlæses efter header. Dette er her hvor html-koden skal placeres.</li></ul><p>Du skal oprette ressourcer (classes, js, css) derefter inkluder disse filer.</p>',
	'Unable to delete the playlist' => 'Kunne ikke slette playlisten',
	'Player login' => 'Spiller login',
	'Clean the list' => 'Rengør listen',
	'The list is already empty.' => 'Listen er allerede tom.',
	'No player' => 'Ingen spiller',
	'IP address' => 'IP Adresse',
	'Client' => 'Client',
	'Blacklist' => 'Blacklist',
	'Remove from the list' => 'Fjern fra listen',
	'Select a player' => 'Vølg en spiller',
	'Enter another login' => 'Indtast et andet login',
	'Add in the' => 'Tilføj til',
	'Playlists' => 'Playlists',
	'Playlist' => 'Playlist',
	'Type' => 'Art',
	'Playlist name' => 'Playlist navn',
	'New playlist' => 'Ny playlist',
	'players' => 'Spillere',
	'player' => 'Spiller',
	'No playlist' => 'Ingen playlist',
	'You are not allowed to configure the servers' => 'Du har rettighed til at konfigurer serverne.',
	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Ingen server tilgænglig, For at tilføje, ret "config/servers.cfg.php" filen',
	'The servers configuration file isn\'t recognized by AdminServ.' => 'Server konfigurations filen er ikke gyldig til AdminServ.',
	'This server has been duplicated.' => 'Denne server er blevet buplikeret.',
	'Unable to duplicate server.' => 'Kunne ikke dupliker.',
	'copy' => 'Kopier',
	'Servers list' => 'Servers Liste',
	'Address' => 'Adresse',
	'Port' => 'Port',
	'SuperAdmin level' => 'SuperAdmin niveau',
	'User level' => 'User niveau',
	'Manage' => 'Administrer',
	'None' => 'Ingen',
	'Local network' => 'Lokal netværk',
	'All' => 'Alle',
	'Removed' => 'Fjern',
	'Missing' => 'Mangler',
	'No server' => 'Ingen Server',
	'servers' => 'Servere',
	'server' => 'Server',
	'Duplicate' => 'Dupliker',
	'Modify' => 'Ændre',
	'The "!serverName" server has been deleted.' => 'Serveren "!serverName" blev slettet.',
	'This server has been modified.' => 'Serveren blev ændret.',
	'Unable to modify the server.' => 'Kunne ikke ændre server.',
	'This server has been added.' => 'Serveren blev tilføjet.',
	'Unable to add the server.' => 'Kunne ikke tilføje serveren.',
	'Add server' => 'Tilføj Server',
	'Edit server' => 'Ændre server',
	'Back' => 'Tilbage',
	'Connection information' => 'Forbindelses information',
	'Server name without color' => 'Servernavn uden farve',
	'IP address or domain name' => 'IP Adresse eller domænenavn',
	'XMLRPC port' => 'XMLRPC Port',
	'Port for remote control' => 'Port til fjernstyring',
	'Optional information' => 'Valgfri Information',
	'Server MatchSettings' => 'Server MatchSettings',
	'Current server MatchSettings name' => 'Serveren\' aktuelle MatchSettings Navn',
	'Possible values for the admin level:' => 'Mulige størrelse for Admin niveau :',
	'all => all access' => 'all => Adgang til alle',
	'local => local network access' => 'local => Lokal netværk adgang',
	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => Adgang for én eller flere IP adresser',
	'none => removed from the access list' => 'none => fjern fra adgangsliste',
	'No server available' => 'Ingen server tilgængelig',
	'No game mode available' => 'Ingen spil tilstand tilgængelig',
	'Map end time' => 'Bane slut tid',
	'Round/lap end time' => 'Rounde/Omgang slut tid',
	'Respawn' => 'Respawn',
	'Default' => 'Standard',
	'Auto (based on map)' => 'Auto (Baseret på banen)',
	'Choose time' => 'Vælg tid',
	'Return to the default value' => 'Tilbage til standard værdi',
	'All WarmUp duration' => 'Alle WarmUps varighed',
	'Enable' => 'Aktiver',
	'Disable' => 'Deaktiver',
	'Force show of all opponents' => 'Tving vis af alle modstandere',
	'Let player choose' => 'Lad spillere vælge',
	'All opponents' => 'Alle modtandere',
	'minimal opponents' => 'minimal modtandere',
	'Choose opponents number' => 'Vælg modstander nummer',
	'Script name' => 'Script Navn',
	'Use new rules' => 'Brug nye regler',
	'Points limit' => 'Points grænse',
	'Custom points limit' => 'Brugerdefineret points grænse',
	'Force laps' => 'Tving omgang',
	'Start synchronization period' => 'Start synkroniserings period',
	'Maximal points' => 'Maksimal Points',
	'Number of laps' => 'Antal omgange',
	'Rounds per map' => 'Runder pr. bane',
	'Number of winners' => 'Antal vindere',
	'No player available' => 'Ingen spiller tilgængelig',
	'New' => 'Ny',
	'Parent folder' => 'Hoved mappe',
	'Folder options' => 'Mappe indstilling',
	'Do you really want to remove this folder !currentDir?' => 'Ønsker du virkelig at slette denne mappe !currentDir?',
	'Rename folder' => 'Omdøb mappe',
	'Move folder' => 'Flyt mappe',
	'Move folder <b>!currentDir</b> in:' => 'Flyt mappen <b>!currentDir</b> i:',
	'The server is not accessible.' => 'Serveren er ikke tilgængelig.',
	'You are not allowed at this admin level' => 'Du har tilladelse med denne admin niveau.',
	'The password doesn\'t match to the server.' => 'Forkert kodeord til server.',
	'Client not initialized' => 'Klienten ikke initialiseret',
	'Unknown command' => 'Ukendt kommando',
	'$99FThis round is a draw.' => '$99FRunden er uafgjort.',
	'$99FThe $<$00FBlue team$> wins this round.' => '$99FDet $<$00FBlue team$> vinner denne runde.',
	'$99FThe $<$F00Red team$> wins this round.' => '$99FDet $<$F00Red team$> vinner denne runde.',
	'maps' => 'Baner',
	'map' => 'Bane',
	'No map' => 'Ingen baner',
	'matchsettings' => 'Matchsettings',
	'matchsetting' => 'Matchsetting',
	'No matchsetting' => 'Ingen Matchsetting',
	'text->XML conversion error' => 'text->XML Konverteringsfejl',
	'Saving XML file error' => 'Kunne ikke gemme XML fil',
	'The folder "logs" is not writable.' => 'Mappen "logs" er skrivebeskyttet.',
	'The folder "logs" does not exist.' => 'Mappen "logs" findes ikke.',
	'Unable to create log file:' => 'Kunne ikke oprette log fil:',
	'Unable to add log in file:' => 'Kunne ikke tilføje log i filen:',
	'This server does not exist' => 'Denne server findes ikke',
	'Change password' => 'Ændre adgangskode',
	'Current' => 'Aktuel',
	'The current password doesn\'t match.' => 'Det aktuelle kodeord passer ikke.',
	'The password has been changed.' => 'Adgangskoden er blevet ændret.',
	'Not rated' => 'Ikke bedømt',
	'Unable to delete server.' => 'Kunne ikke slette server',
	'Guest-Ban' => 'Gæst-Ban',
	'Access as player' => 'Tilslut som spiller',
	'Access as spectator' => 'Tilslut som tilskure',
	'Disable horns' => 'Deaktiver horn',
	'Current vote' => 'Aktuel afstemning',
	'Cancel vote' => 'Annuller afstemning',
	'Change order' => 'Ændre rækkefølge',
	'Servers order' => 'Server rækkefølge',
	'This path was not required rights:' => 'Denne sti var ikke påkrævet rettigheder:',
	'needs' => 'behov',
	'Plugin error: script.php or view.php file is missing.' => 'Tilføjelse-fejl: script.php eller view.php fil mangler.',
	'No server admin levels configured.' => 'Ingen server admin niveau konfigureret.',
	'Gold time' => 'Guld tid',
	'Cost' => 'Værdi',
	'Team infos' => 'Hold Information',
	'Script settings' => 'Script-indstillinger',
	'Script settings updated.' => 'Script-indstillinger opdateret.',
	'Change authentication password' => 'Skift autentificerings adgangskode',
	'You changed the password "!authLevel", remember it at the next connection!' => 'Du har ændret adgangskode "!authLevel", husk det til næste login!',
	'Automatic' => 'Automatisk',
	'Choose number' => 'Vælg nummer',
	'Client inputs max latency' => 'Client inputs max latency',
	'Script info' => 'Script Information',
	'Compatible map types' => 'Kompatible bane typer',
	'Script parameters' => 'Script parametre',
	'Value' => 'Værdi',
	'The server already exist! Change the name.' => 'Serveren findes allerede! Ændre navnet.',
	'Version' => 'Version',
	'Disable vote ratio' => 'Deaktiver stemme forholdet',
	'Manage server options' => 'Administrer server indstillinger',
	'Import' => 'Importer',
	'Export' => 'Eksporter',
	'No export available' => 'Ingen eksport tilgængelig',
	'No such file or file is not readable' => 'Filen findes ikke eller filen kan ikke læses',
	'Server options are exported in' => 'Server indstillinger overføres til',
	'Unable to export server options' => 'Kunne ikke overføre server indstillinger',
	'Maps base folder' => 'Hoved bane mappe',
	'Default path from maps folder for listing maps' => 'Standard sti fra "bane" mappen til visning af baner',
	'No folder' => 'Ingen mappe',
	'Server selection' => 'Vælg server',
);
?>
<?php
/**
* Español translation
*
* @author   Revo
* @author   Kev717
* @version  1.1
*/
$translate = array(
	'Access server' => 'Acceder al servidor',
	'Access relay' => 'Acceder al repetidor',
	'Disconnect' => 'Desconexión',
	'Servers' => 'Servidores',
	'Server' => 'Servidor',
	'Password' => 'Contraseña',
	'Admin level' => 'Nivel admin',
	'Connection' => 'Conexión',
	'Please put a password.' => 'Por favor, ponga una contraseña.',
	'Connection error' => 'Error de conexión',
	'Connection error: invalid session.' => 'Error de conexión : sesión no válido.',
	'Servers configuration' => 'Configuración dos servidores',
	'Online configuration' => 'Configuration en línea',
	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'Esta es su primera conexión y no hay un servidor configurado. Elija una contraseña para configurar los servidores.',
	'Unable to save password.' => 'Imposible guardar el contraseña',
	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Configuración en línea está desactivado. Utilice el fichero "./config/servers.cfg.php".',
	'Offline server.' => 'Servidor offline.',
	'Authentication error.' => 'Error de autenticación.',
	'Add to favourite' => 'Añadir a favoritos',
	'Current map' => 'Mapa actual',
	'Name' => 'Nombre',
	'Author' => 'Autor',
	'Environment' => 'Ambiente',
	'Map UId' => 'Mapa UId',
	'Game mode' => 'Modo de juego',
	'No thumbnail' => 'No hay miniatura',
	'Server name' => 'Nombre del servidor',
	'Status' => 'Estado',
	'Server login' => 'Login servidor',
	'Connected on' => 'Conectado a',
	'Dedicated version' => 'Versión dedicada',
	'Statistics' => 'Estadísticas',
	'Uptime' => 'Empezado desde',
	'Number of connections' => 'Número de conexiones',
	'Average connection time' => 'Tiempo de conexión promedio',
	'Average number of players' => 'Número de jugadores promedio',
	'Recv net rate' => 'Tasa de recepción',
	'Send net rate' => 'Tasa de envío',
	'Total receiving size' => 'Recepción total',
	'Total sending size' => 'Emisión total',
	'Players' => 'Jugadores',
	'Detailed mode' => 'Modo detalle',
	'Simple mode' => 'Modo sencillo',
	'Nickname' => 'Seudónimo',
	'Login' => 'Login',
	'For the selection' => 'Para la selección',
	'Ban' => 'Banear',
	'Kick' => 'Kicker',
	'Spectator' => 'Espectador',
	'Player' => 'Jugador',
	'Team' => 'Equipo',
	'Guest' => 'Invitar',
	'Ignore' => 'Ignorar',
	'Red team' => 'Equipo rojo',
	'Blue team' => 'Equipo azul',
	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Los resultados han sido modificados : el $00fequipo azul$fff con !scoreTeamBlue y el $f00equipo rojo $fffcon !scoreTeamRed',
	'Server options' => 'Opciones servidor',
	'General' => 'General',
	'Comment' => 'Comentarios',
	'Player password' => 'Contraseña jugador',
	'Spectator password' => 'Contraseña espectador',
	'Nb max of players' => 'N° máximo de jugadores',
	'Next value' => 'Próximo valor',
	'Nb max of spectators' => 'N° máximo de espectadores',
	'Advanced' => 'Avanzado',
	'P2P Upload' => 'Carga P2P',
	'P2P Download' => 'Descarga P2P',
	'Ladder mode' => 'Modo ladder',
	'Vehicles quality' => 'Calidad de los vehículos',
	'Vote expiration' => 'Expiración del voto',
	'sec' => 'seg', // Second
	'Vote ratio' => 'Voto ratio',
	'Hidden server' => 'Servidor oculto',
	'Map download' => 'Descarga de los mapas',
	'Replays auto save' => 'Guardar automáticamente los replays',
	'Buddy notification' => 'Notificaciones amigos',
	'Save' => 'Guardar',
	'Inactive' => 'Inactivo',
	'Forced' => 'Forzado',
	'Fast' => 'Rápida',
	'High' => 'Alta',
	'Game infos' => 'Infos de jeu',
	'Game information' => 'Información juego',
	'Color' => 'Color',
	'Black' => 'Negro',
	'Red' => 'Rojo',
	'Green' => 'Verde',
	'Blue' => 'Azul',
	'Orange' => 'Naranja',
	'Pink' => 'Rosa',
	'Purple' => 'Púrpura',
	'Grey' => 'Gris',
	'White' => 'Blanco',
	'Message destination' => 'Destinación del mensaje',
	'Chat' => 'Chat',
	'Show server lines' => 'Visualizar las líneas servidor',
	'Hide server lines' => 'Ocultar las líneas servidor',
	'Default color: yellow' => 'Color por defecto : amarillo',
	'Message' => 'Mensaje',
	'Destination' => 'Destinación',
	'Send' => 'Enviar',
	'Unable to create the folder' => 'Imposible crear el carpeta',
	'Unable to rename the folder' => 'Imposible renombrar el carpeta',
	'Unable to move the folder' => 'Imposible desplazar el carpeta',
	'Unable to delete the folder' => 'Imposible borrar el carpeta',
	'List' => 'Lista',
	'Go to the current map' => 'Vaya a mapa actual',
	'Map' => 'Mapa',
	'Delete' => 'Borrar',
	'Move after the current map' => 'Desplazar después el mapa actual',
	'Unable to rename the map' => 'Imposible renombrar el mapa',
	'Unable to move the map' => 'Imposible desplazar el mapa',
	'Unable to delete the map' => 'Imposible borrar el mapa',
	'Local' => 'Local',
	'Do you really want to remove this selection?' => '¿Desea realmente borrar este selección?',
	'Move' => 'Desplazar',
	'Rename' => 'Renombrar',
	'Download' => 'Descargar',
	'Insert' => 'Insertar',
	'Add' => 'Añadir',
	'Cancel' => 'Cancelar',
	'Replace the special characters' => 'Reemplazar caracteres especiales',
	'in the folder:' => 'en el carpeta :',
	'Root' => 'Raíz',
	'The map,is currently used by the server.' => 'El mapa,está siendo utilizado actualmente por el servidor.',
	'MatchSettings' => 'MatchSettings',
	'Contains' => 'Contiene',
	'Modified' => 'Modificado el',
	'Edit' => 'Editar',
	'Load' => 'Cargar',
	'Save ' => 'Guardar',
	'Create' => 'Crear',
	'Unable to save the MatchSettings' => 'Imposible guardar el MatchSettings',
	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'El MatchSettings "!matchSettingName" a sido creada en la carpeta',
	'a MatchSettings' => 'un MatchSettings',
	'Create a MatchSettings' => 'Crear un MatchSettings',
	'MatchSettings name' => 'Nombre del MatchSettings',
	'Maps' => 'Mapas',
	'Make selection' => 'Haga una selección',
	'Import all folder' => 'Importar la carpeta completa',
	'Select' => 'Seleccionar',
	'MatchSettings selected maps:' => 'Los mapas seleccionados para MatchSettings:',
	'View the MatchSettings selection' => 'Ver MatchSettings selección',
	'MatchSettings selection' => 'Selección del MatchSettings',
	'Remove map from the selection' => 'Quitar esta mapa de la selección',
	'Close' => 'Cerrar',
	'HotSeat' => 'HotSeat',
	'Time limit' => 'Límite de tiempo',
	'Rounds count' => 'Nombre de rounds',
	'Filter' => 'Filtros',
	'Lan' => 'Lan',
	'Internet' => 'Internet',
	'Solo' => 'Solo',
	'Sort index' => 'Índice de clasificación',
	'Random map order' => 'Orden de los mapas aleatorio',
	'Default game mode' => 'Modo de juego por defecto',
	'No map selected for the MatchSettings.' => 'Ningún mapa seleccionado para MatchSettings.',
	'The MatchSettings name already exist! It will be overwritten.' => 'MatchSettings nombre ya existe! Va a ser sobreescrito.',
	'Order' => 'Orden',
	'Automatic sort' => 'Clasificación automática',
	'Random' => 'Aleatorio',
	'Manual sort' => 'Clasificación manual',
	'Save the current MatchSettings' => 'Guardar el MatchSettings actual',
	'Reset' => 'Reinicializar',
	'Transfer mode' => 'Modo del transferencia',
	'at the end of list' => 'al final de la lista',
	'after current map' => 'después mapa actual',
	'only in the folder' => 'en el carpeta sólo',
	'Options' => 'Opciones',
	'Go to the maps list when upload is complete' => 'Vaya a la lista de mapas después de la carga completa',
	'Upload' => 'Carga',
	'Failed' => 'Fracasado',
	'Upload a file' => 'Examinar...',
	'Drop files here to upload' => 'Arrastrar ficheros aquí para enviar',
	'Upload not finished' => 'La carga no está terminado',
	'from' => 'de',
	'Kb' => 'Ko',
	'Mb' => 'Mo',
	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} tiene una extensión no válida. Sólo {extensions} de formatos están permitidos.',
	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} es demasiado pesado. El tamaño máximo es {sizeLimit}.',
	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} es demasiado pequeño. El tamaño mínimo es de {minSizeLimit}.',
	'{file} is empty, please select files again without it.' => '{file} está vacía. Por favor, seleccione un fichero que no está vacío.',
	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Los ficheros se están transfiriendo. Si sale de la página, se cancelará el envío.',
	'No file was uploaded' => 'No existe el fichero fue subido',
	'The file is empty.' => 'El fichero está vacío.',
	'The file size is too large.' => 'El tamaño del fichero es mayor que el límite permitido.',
	'The file has invalid extension (allowed extensions:' => 'La extensión de fichero no es válido (extensiones permitidas:',
	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'El fichero no se ha enviado. El envío ha sido cancelada o se produjo un error en el servidor.',
	'Server error. The upload destination folder isn\'t writable.' => 'Error del servidor. La carpeta de destino no es escribible archivos.',
	'Plugins' => 'Plugins',
	'plugin installed' => 'plugin instalado',
	'plugins installed' => 'plugins instalados',
	'Cannot include another plugins config file.' => 'Imposible incluir otro fichero de configuración de plugins.',
	'Variable "$PLUGINS" not found.' => 'Variable "$PLUGINS" no se encuentra.',
	'Install a plugin' => '¿Cómo instalar un plugin?',
	'Click here' => 'Haga clic aquí',
	'Create a new plugin' => '¿Cómo crear un plugin?',
	'Unable to delete the playlist' => 'Imposible borrar el lista',
	'Player login' => 'Login jugador',
	'Clean the list' => 'Vaciar la lista',
	'The list is already empty.' => 'La lista ya está vacía.',
	'No player' => 'Ningún jugador',
	'IP address' => 'Dirección IP',
	'Client' => 'Cliente',
	'Blacklist' => 'Poner en la lista negra',
	'Remove from the list' => 'Quitar de la lista',
	'Select a player' => 'Seleccionar un jugador',
	'Enter another login' => 'Introduzca otro inicio login',
	'Add in the' => 'Añadir al',
	'Playlists' => 'Listas',
	'Playlist' => 'Lista',
	'Type' => 'Tipo',
	'Playlist name' => 'Nombre de la lista',
	'New playlist' => 'Nueva lista',
	'players' => 'jugadores',
	'player' => 'jugador',
	'No playlist' => 'Ninguna lista',
	'You are not allowed to configure the servers' => 'Usted no está autorizado a configurar los servidores.',
	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Ningún servidor está diponible. Para añadir uno, ha de configurar el fichero "config/servers.cfg.php"',
	'The servers configuration file isn\'t recognized by AdminServ.' => 'El servidor de fichero de configuración no es reconocido por Adminserv.',
	'This server has been duplicated.' => 'El servidor se ha duplicado.',
	'Unable to duplicate server.' => 'Imposible duplicado el servidor.',
	'copy' => 'copia',
	'Servers list' => 'Lista de servidores',
	'Address' => 'Dirección',
	'Port' => 'Puerto',
	'SuperAdmin level' => 'Nivel SuperAdmin',
	'User level' => 'Nivel User',
	'Manage' => 'Gestión',
	'None' => 'Ningún',
	'Local network' => 'Red local',
	'All' => 'Todos',
	'Removed' => 'Quitar',
	'Missing' => 'Desaparecido',
	'No server' => 'Ningún servidor',
	'servers' => 'servidores',
	'server' => 'servidor',
	'Duplicate' => 'Duplicar',
	'Modify' => 'Modificar',
	'The "!serverName" server has been deleted.' => 'El servidor "!serverName" se ha borrar.',
	'This server has been modified.' => 'El servidor ha sido modificado.',
	'Unable to modify the server.' => 'Imposible modificado el servidor.',
	'This server has been added.' => 'El servidor ha sido añadido.',
	'Unable to add the server.' => 'Imposible añadido el servidor.',
	'Add server' => 'Añadir un servidor',
	'Edit server' => 'Editar un servidor',
	'Back' => 'Atrás',
	'Connection information' => 'Informacióon del conexión',
	'Server name without color' => 'Nombre del servidor sin color',
	'IP address or domain name' => 'Dirección IP o nombre de dominio',
	'XMLRPC port' => 'Puerto XMLRPC',
	'Port for remote control' => 'Puerto para control remoto',
	'Optionnal information' => 'Informacióon opcionales',
	'Server MatchSettings' => 'MatchSettings del servidor',
	'Current server MatchSettings name' => 'Nombre del MatchSettings actual del servidor',
	'Possible values for the admin level:' => 'Los valores posibles para los administradores de niveles:',
	'all => all access' => 'all => accesos lost todos',
	'local => local network access' => 'local => acceso a la red local',
	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => acceso a una o más direcciones IP',
	'none => removed from the access list' => 'none => acceso quitar de la lista',
	'No server available' => 'Ningún servidor está diponible',
	'No game mode available' => 'Ningún modo de juego está diponible',
	'Map end time' => 'Tiempo de fin de mapa',
	'Round/lap end time' => 'Tiempo de fin de round/lap',
	'Respawn' => 'Respawn',
	'Default' => 'Por defecto',
	'Auto (based on map)' => 'Auto (de acuerdo con el mapa)',
	'Choose time' => 'Elija el tiempo',
	'Return to the default value' => 'Revertir y la valor por defecto',
	'All WarmUp duration' => 'Número de vueltas de calentamiento',
	'Enable' => 'Activado',
	'Disable' => 'Desactivado',
	'Force show of all opponents' => 'Obligar visualización de los adversarios',
	'Let player choose' => 'Deje la elección al jugador',
	'All opponents' => 'Todos los adversarios',
	'minimal opponents' => 'adversarios mínimo',
	'Choose opponents number' => 'Elija el número de adversarios',
	'Script name' => 'Nombre del escritura',
	'Use new rules' => 'El uso de las nuevas normas',
	'Points limit' => 'Límite de puntos',
	'Custom points limit' => 'Límite de puntos personalizado',
	'Force laps' => 'Obligar el vuelta',
	'Start synchronization period' => 'Tiempo de sincronización de la partida',
	'Maximal points' => 'Puntos máximos',
	'Number of laps' => 'Número de vueltas',
	'Rounds per map' => 'Número de round por mapa',
	'Number of winners' => 'Número de ganadores',
	'No player available' => 'Ningún jugador disponible',
	'New' => 'Nuevo',
	'Parent folder' => 'Carpeta de origen',
	'Folder options' => 'Opciones de carpeta',
	'Do you really want to remove this folder !currentDir?' => '¿Desea realmente borrar este carpeta !currentDir?',
	'Rename folder' => 'Renombrar un carpeta',
	'Move folder' => 'Desplazar un carpeta',
	'Move folder <b>!currentDir</b> in:' => 'Desplazar el carpeta <b>!currentDir</b> en :',
	'The server is not accessible.' => 'No se puede acceder al servidor.',
	'You are not allowed at this admin level' => 'No está autorizado en ese nivel de administración.',
	'The password doesn\'t match to the server.' => 'La contraseña no coincide con el servidor.',
	'Client not initialized' => 'El cliente no está inicializado',
	'Unknown command' => 'El comando no es reconocido',
	'$99FThis round is a draw.' => '$99FSin partida.',
	'$99FThe $<$00FBlue team$> wins this round.' => '$99FEl $00Fequipo azur gana esta ronda.',
	'$99FThe $<$F00Red team$> wins this round.' => '$99FEl $F00equipo rojo gana esta ronda.',
	'maps' => 'mapas',
	'map' => 'mapa',
	'No map' => 'Nunguna mapa',
	'matchsettings' => 'matchsettings',
	'matchsetting' => 'matchsetting',
	'No matchsetting' => 'Ningún matchsetting',
	'text->XML conversion error' => 'Error al convertir el texto->XML',
	'Saving XML file error' => 'Error guardar el fichero XML',
	'The folder "logs" is not writable.' => 'La carpeta "logs" no se puede escribir registro.',
	'The folder "logs" does not exist.' => 'La carpeta "logs" no existe.',
	'Unable to create log file:' => 'Imposible crear el fichero de registro:',
	'Unable to add log in file:' => 'Imposible añadir un fichero al registro:',
	'This server does not exist' => 'Este servidor no existe',
	'Change password' => 'Cambiar la contraseña',
	'Current' => 'Actual',
	'The current password doesn\'t match.' => 'La contraseña actual no coincide.',
	'The password has been changed.' => 'La contraseña ha sido cambiada.',
	'Not rated' => 'No clasificado',
	'Unable to delete server.' => 'Imposible borrar esta servidor.',
	'Guest-Ban' => 'Invitados-Baneados',
	'Access as player' => 'Acceder en jugador',
	'Access as spectator' => 'Acceder en espectador',
	'Disable horns' => 'Claxones desactivados',
	'Current vote' => 'Actual voto',
	'Cancel vote' => 'Cancelar el voto',
	'Change order' => 'Cambiar el orden',
	'Servers order' => 'Orden dos servidores',
	'This path was not required rights:' => 'La ruta de acceso no está obligado derechos:',
	'needs' => 'necesidades',
	'Plugin error: script.php or view.php file is missing.' => 'Plugin error: el fichero script.php o view.php esta desaparecido.',
	'No server admin levels configured.' => 'Ningún nivel de administración configurado para esta servidor.',
	'Gold time' => 'Tiempo oro',
	'Cost' => 'Costo',
	'Team infos' => 'Noticias del equipo',
	'Script settings' => 'Los parámetros de script',
	'Script settings updated.' => 'Parámetros actualizados script.',
	'Change authentication password' => 'Cambiar la contraseña de una cuenta',
	'You changed the password "!authLevel", remember it at the next connection!' => 'Usted acaba de cambiar la contraseña "!authLevel", piensa en ello en el siguiente inicio de sesión!',
	'Automatic' => 'Automático',
	'Choose number' => 'Elija un número',
	'Client inputs max latency' => 'Max latencia clientes',
);
?>
<?php
/**
* French translation
*
* @author   Kev717
* @version  1.4
*/
$translate = array(
	'Access server' => 'Accéder au serveur',
	'Access relay' => 'Accéder au relai',
	'Disconnect' => 'Déconnexion',
	'Servers' => 'Serveurs',
	'Server' => 'Serveur',
	'Password' => 'Mot de passe',
	'Admin level' => 'Niveau admin',
	'Connection' => 'Connexion',
	'Please put a password.' => 'Veuillez mettre un mot de passe.',
	'Connection error' => 'Erreur de connexion',
	'Connection error: invalid session.' => 'Erreur de connexion : session invalide.',
	'Servers configuration' => 'Configuration des serveurs',
	'Online configuration' => 'Configuration en ligne',
	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'C\'est votre 1ère connexion et aucun serveur n\'est configuré. Choisissez un mot de passe pour configurer vos serveurs.',
	'Unable to save password.' => 'Impossible d\'enregistrer le mot de passe',
	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'La configuration en ligne est désactivée. Utilisez le fichier "./config/servers.cfg.php".',
	'Offline server.' => 'Serveur hors ligne.',
	'Authentication error.' => 'Erreur d\'authentification.',
	'Add to favourite' => 'Ajouter aux favoris',
	'Current map' => 'Map en cours',
	'Name' => 'Nom',
	'Author' => 'Auteur',
	'Environment' => 'Environnement',
	'Map UId' => 'Map UId',
	'Game mode' => 'Mode de jeu',
	'No thumbnail' => 'Pas de miniature',
	'Server name' => 'Nom du serveur',
	'Status' => 'Statut',
	'Server login' => 'Login serveur',
	'Connected on' => 'Connecté sur',
	'Dedicated version' => 'Version dédié',
	'Statistics' => 'Statistiques',
	'Uptime' => 'Démarré depuis',
	'Number of connections' => 'Nombre de connexions',
	'Average connection time' => 'Temps de connexion moyen',
	'Average number of players' => 'Nombre de joueurs moyen',
	'Recv net rate' => 'Taux de récéption',
	'Send net rate' => 'Taux d\'envoi',
	'Total receiving size' => 'Réception totale',
	'Total sending size' => 'Emission totale',
	'Players' => 'Joueurs',
	'Detailed mode' => 'Mode détail',
	'Simple mode' => 'Mode simple',
	'Nickname' => 'Pseudo',
	'Login' => 'Login',
	'For the selection' => 'Pour la sélection',
	'Ban' => 'Bannir',
	'Kick' => 'Kicker',
	'Spectator' => 'Spectateur',
	'Player' => 'Joueur',
	'Team' => 'Équipe',
	'Guest' => 'Inviter',
	'Ignore' => 'Ignorer',
	'Red team' => 'Équipe rouge',
	'Blue team' => 'Équipe bleue',
	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Les scores ont été modifiés : l\'$00féquipe bleue$fff à !scoreTeamBlue et l\'$f00équipe rouge $fffà !scoreTeamRed',
	'Server options' => 'Options du serveur',
	'General' => 'Général',
	'Comment' => 'Commentaire',
	'Player password' => 'Mot de passe joueur',
	'Spectator password' => 'Mot de passe spectateur',
	'Nb max of players' => 'Nb max de joueurs',
	'Next value' => 'Prochaine valeur',
	'Nb max of spectators' => 'Nb max de spectateurs',
	'Advanced' => 'Avancé',
	'P2P Upload' => 'P2P Upload',
	'P2P Download' => 'P2P Download',
	'Ladder mode' => 'Mode ladder',
	'Vehicles quality' => 'Qualité des véhicules',
	'Vote expiration' => 'Expiration du vote',
	'sec' => 'sec', // Second
	'Vote ratio' => 'Ratio vote',
	'Hidden server' => 'Serveur caché',
	'Map download' => 'Téléchargement des maps',
	'Replays auto save' => 'Sauvegarde auto des replays',
	'Buddy notification' => 'Notifications des amis',
	'Save' => 'Enregistrer',
	'Inactive' => 'Inactif',
	'Forced' => 'Forcé',
	'Fast' => 'Rapide',
	'High' => 'Haute',
	'Game infos' => 'Infos de jeu',
	'Game information' => 'Informations de jeu',
	'Color' => 'Couleur',
	'Black' => 'Noir',
	'Red' => 'Rouge',
	'Green' => 'Vert',
	'Blue' => 'Bleu',
	'Orange' => 'Orange',
	'Pink' => 'Rose',
	'Purple' => 'Violet',
	'Grey' => 'Gris',
	'White' => 'Blanc',
	'Message destination' => 'Destination du message',
	'Chat' => 'Chat',
	'Show server lines' => 'Afficher les lignes du serveur',
	'Hide server lines' => 'Masquer les lignes du serveur',
	'Default color: yellow' => 'Couleur par défaut : jaune',
	'Message' => 'Message',
	'Destination' => 'Destination',
	'Send' => 'Envoyer',
	'Unable to create the folder' => 'Impossible de créer le dossier',
	'Unable to rename the folder' => 'Impossible de renommer le dossier',
	'Unable to move the folder' => 'Impossible de déplacer le dossier',
	'Unable to delete the folder' => 'Impossible de supprimer le dossier',
	'List' => 'Liste',
	'Go to the current map' => 'Aller à la map en cours',
	'Map' => 'Map',
	'Delete' => 'Supprimer',
	'Move after the current map' => 'Déplacer après la map en cours',
	'Unable to rename the map' => 'Impossible de renommer la map',
	'Unable to move the map' => 'Impossible de déplacer la map',
	'Unable to delete the map' => 'Impossible de supprimer la map',
	'Local' => 'Local',
	'Do you really want to remove this selection?' => 'Voulez-vous vraiment supprimer cette sélection ?',
	'Move' => 'Déplacer',
	'Rename' => 'Renommer',
	'Download' => 'Télécharger',
	'Insert' => 'Insérer',
	'Add' => 'Ajouter',
	'Cancel' => 'Annuler',
	'Replace the special characters' => 'Remplacer les caractères spéciaux',
	'in the folder:' => 'dans le dossier :',
	'Root' => 'Racine',
	'The map,is currently used by the server.' => 'La map,est actuellement utilisée par le serveur.',
	'MatchSettings' => 'MatchSettings',
	'Contains' => 'Contient',
	'Modified' => 'Modifié le',
	'Edit' => 'Éditer',
	'Load' => 'Charger',
	'Save ' => 'Sauvegarder',
	'Create' => 'Créer',
	'Unable to save the MatchSettings' => 'Impossible d\'enregistrer le MatchSettings',
	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'Le MatchSettings "!matchSettingName" a bien été créé dans le dossier',
	'a MatchSettings' => 'un MatchSettings',
	'Create a MatchSettings' => 'Créer un MatchSettings',
	'MatchSettings name' => 'Nom du MatchSettings',
	'Maps' => 'Maps',
	'Make selection' => 'Faire une sélection',
	'Import all folder' => 'Importer tout le dossier',
	'Select' => 'Sélectionner',
	'MatchSettings selected maps:' => 'Maps sélectionnées pour le MatchSettings :',
	'View the MatchSettings selection' => 'Voir la sélection du MatchSettings',
	'MatchSettings selection' => 'Sélection du MatchSettings',
	'Remove map from the selection' => 'Enlever cette map de la sélection',
	'Close' => 'Fermer',
	'HotSeat' => 'HotSeat',
	'Time limit' => 'Limite de temps',
	'Rounds count' => 'Nombre de rounds',
	'Filter' => 'Filtres',
	'Lan' => 'Lan',
	'Internet' => 'Internet',
	'Solo' => 'Solo',
	'Sort index' => 'Index de tri',
	'Random map order' => 'Ordre des maps aléatoire',
	'Default game mode' => 'Mode de jeu par défaut',
	'No map selected for the MatchSettings.' => 'Aucune map sélectionnée pour le MatchSettings.',
	'The MatchSettings name already exist! It will be overwritten.' => 'Le nom du MatchSettings existe déjà ! Il sera écrasé.',
	'Order' => 'Ordonner',
	'Automatic sort' => 'Tri automatique',
	'Random' => 'Aléatoire',
	'Manual sort' => 'Tri manuel',
	'Save the current MatchSettings' => 'Sauvegarder le MatchSettings courant',
	'Reset' => 'Réinitialiser',
	'Transfer mode' => 'Mode de transfert',
	'at the end of list' => 'à la fin de la liste',
	'after current map' => 'après la map en cours',
	'only in the folder' => 'dans le dossier seulement',
	'Options' => 'Options',
	'Go to the maps list when upload is complete' => 'Aller à la liste des maps une fois l\'upload terminé',
	'Upload' => 'Upload',
	'Failed' => 'Échoué',
	'Upload a file' => 'Parcourir...',
	'Drop files here to upload' => 'Glissez les fichiers ici pour envoyer',
	'Upload not finished' => 'L\'upload n\'est pas terminé',
	'from' => 'de',
	'Kb' => 'Ko',
	'Mb' => 'Mo',
	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} a une extension invalide. Seulement les formats {extensions} sont autorisés.',
	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} est trop lourd. La taille maximale est de {sizeLimit}.',
	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} est trop petit. La taille minimale est de {minSizeLimit}.',
	'{file} is empty, please select files again without it.' => '{file} est vide. Veuillez sélectionner un fichier qui n\'est pas vide.',
	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Les fichiers sont en cours de transfert. Si vous quittez la page, l\'envoi sera annulé.',
	'No file was uploaded' => 'Aucun fichier n\'a été uploadé',
	'The file is empty.' => 'Le fichier est vide.',
	'The file size is too large.' => 'La taille du fichier est supérieure à la limite autorisé.',
	'The file has invalid extension (allowed extensions:' => 'L\'extension du fichier est invalide (extensions autorisées :',
	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Le fichier n\'a pas été envoyé. L\'envoi a été annulé ou une erreur du serveur est survenue.',
	'Server error. The upload destination folder isn\'t writable.' => 'Erreur du serveur. Le dossier de destination des uploads n\'est pas écrivable.',
	'Plugins' => 'Plugins',
	'plugin installed' => 'plugin installé',
	'plugins installed' => 'plugins installés',
	'Cannot include another plugins config file.' => 'Impossible d\'inclure un autre fichier de config pour les plugins.',
	'Variable "$PLUGINS" not found.' => 'Variable "$PLUGINS" non trouvée.',
	'Plugins are extensions to add features to Adminserv.' => 'Les plugins sont des extensions permettant d\'ajouter des fonctionnalités pour AdminServ.',
	'Install a plugin' => 'Comment installer un plugin ?',
	'See all plugins:' => 'Voir tous les plugins :',
	'Click here' => 'Cliquez-ici',
	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Dézippez le plugin et placez son contenu dans le dossier &laquo; plugins &raquo; d\'AdminServ.',
	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'Dans la configuration Extension, ajoutez le nom du dossier du plugin précédement ajouté.',
	'Create a new plugin' => 'Comment créer son plugin ?',
	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values ​​in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>Pour créer son plugin, allez dans le dossier plugins et dupliquez le dossier _newplugin. Remplacez les valeurs dans le fichier config.ini ainsi que le nom du dossier.<br />Il y a ensuite 2 fichiers PHP :</p><ul><li>script.php : ce fichier est exécuté avant le header du site. C\'est là que tout le script du plugin sera placé.</li><li>view.php : ce fichier est l\'affichage du plugin exécuté après le header. C\'est là que sera placé tout le code html.</li></ul><p>A vous de créer les ressources (classes, js, css) puis de les inclure dans ces fichiers.</p>',
	'Unable to delete the playlist' => 'Impossible de supprimer la playlist',
	'Player login' => 'Login joueur',
	'Clean the list' => 'Vider la liste',
	'The list is already empty.' => 'La liste est déjà vide.',
	'No player' => 'Aucun joueur',
	'IP address' => 'Adresse IP',
	'Client' => 'Client',
	'Blacklist' => 'Blacklister',
	'Remove from the list' => 'Retirer de la liste',
	'Select a player' => 'Sélectionnez un joueur',
	'Enter another login' => 'Entrez un autre login',
	'Add in the' => 'Ajouter à la',
	'Playlists' => 'Playlists',
	'Playlist' => 'Playlist',
	'Type' => 'Type',
	'Playlist name' => 'Nom de la playlist',
	'New playlist' => 'Nouvelle playlist',
	'players' => 'joueurs',
	'player' => 'joueur',
	'No playlist' => 'Aucune playlist',
	'You are not allowed to configure the servers' => 'Vous n\'êtes pas autorisé à configurer les serveurs.',
	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Aucun serveur n\'est disponible. Pour en ajouter un, il faut configurer le fichier "config/servers.cfg.php"',
	'The servers configuration file isn\'t recognized by AdminServ.' => 'Le fichier de configuration des serveurs n\'est pas reconnu par AdminServ.',
	'This server has been duplicated.' => 'Le serveur a bien été dupliqué.',
	'Unable to duplicate server.' => 'Impossible de dupliquer le serveur.',
	'copy' => 'copie',
	'Servers list' => 'Liste des serveurs',
	'Address' => 'Adresse',
	'Port' => 'Port',
	'SuperAdmin level' => 'Niveau SuperAdmin',
	'User level' => 'Niveau User',
	'Manage' => 'Gestion',
	'None' => 'Aucun',
	'Local network' => 'Réseau local',
	'All' => 'Tous',
	'Removed' => 'Enlevé',
	'Missing' => 'Manquant',
	'No server' => 'Aucun serveur',
	'servers' => 'serveurs',
	'server' => 'serveur',
	'Duplicate' => 'Dupliquer',
	'Modify' => 'Modifier',
	'The "!serverName" server has been deleted.' => 'Le serveur "!serverName" a été supprimé.',
	'This server has been modified.' => 'Le serveur a bien été modifié.',
	'Unable to modify the server.' => 'Impossible de modifier le serveur.',
	'This server has been added.' => 'Le serveur a bien été ajouté.',
	'Unable to add the server.' => 'Impossible d\'ajouter le serveur.',
	'Add server' => 'Ajouter un serveur',
	'Edit server' => 'Éditer un serveur',
	'Back' => 'Retour',
	'Connection information' => 'Informations de connexion',
	'Server name without color' => 'Nom du serveur sans couleur',
	'IP address or domain name' => 'Adresse IP ou nom de domaine',
	'XMLRPC port' => 'Port XMLRPC',
	'Port for remote control' => 'Port permettant le contrôle à distance',
	'Optionnal information' => 'Informations optionnelles',
	'Server MatchSettings' => 'MatchSettings du serveur',
	'Current server MatchSettings name' => 'Nom du MatchSettings courant du serveur',
	'Possible values for the admin level:' => 'Valeurs possibles pour les niveaux admins :',
	'all => all access' => 'all => accès à tous',
	'local => local network access' => 'local => accès au réseau local',
	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => accès à une ou plusieurs adresses IP',
	'none => removed from the access list' => 'none => accès enlevé de la liste',
	'No server available' => 'Aucun serveur disponible',
	'No game mode available' => 'Aucun mode de jeu disponible',
	'Map end time' => 'Temps de fin de map',
	'Round/lap end time' => 'Temps de fin de round/lap',
	'Respawn' => 'Respawn',
	'Default' => 'Par défaut',
	'Auto (based on map)' => 'Auto (en fonction de la map)',
	'Choose time' => 'Choisir le temps',
	'Return to the default value' => 'Revenir à la valeur par défaut',
	'All WarmUp duration' => 'Nombre de WarmUp',
	'Enable' => 'Activé',
	'Disable' => 'Désactivé',
	'Force show of all opponents' => 'Forcer l\'affichage des adversaires',
	'Let player choose' => 'Laisser le choix au joueur',
	'All opponents' => 'Tous les adversaires',
	'minimal opponents' => 'adversaires minimum',
	'Choose opponents number' => 'Choisir le nombre d\'adversaires',
	'Script name' => 'Nom du script',
	'Use new rules' => 'Utiliser les nouvelles règles',
	'Points limit' => 'Limite de points',
	'Custom points limit' => 'Limite de points personnalisée',
	'Force laps' => 'Forcer le tour',
	'Start synchronization period' => 'Temps de synchronisation du départ',
	'Maximal points' => 'Points maximum',
	'Number of laps' => 'Nombre de tours',
	'Rounds per map' => 'Nombre de round par map',
	'Number of winners' => 'Nombre de vainqueurs',
	'No player available' => 'Aucun joueur disponible',
	'New' => 'Nouveau',
	'Parent folder' => 'Dossier parent',
	'Folder options' => 'Options du dossier',
	'Do you really want to remove this folder !currentDir?' => 'Voulez-vous vraiment supprimer le dossier !currentDir ?',
	'Rename folder' => 'Renommer un dossier',
	'Move folder' => 'Déplacer un dossier',
	'Move folder <b>!currentDir</b> in:' => 'Déplacer le dossier <b>!currentDir</b> dans :',
	'The server is not accessible.' => 'Le serveur n\'est pas accessible.',
	'You are not allowed at this admin level' => 'Vous n\'êtes pas autorisé dans ce niveau admin.',
	'The password doesn\'t match to the server.' => 'Le mot de passe ne correspond pas au serveur.',
	'Client not initialized' => 'Le client n\'est pas initialisé',
	'Unknown command' => 'La commande n\'est pas reconnue',
	'$99FThis round is a draw.' => '$99FMatch nul.',
	'$99FThe $<$00FBlue team$> wins this round.' => '$99FL\'$00Féquipe bleue remporte ce tour.',
	'$99FThe $<$F00Red team$> wins this round.' => '$99FL\'$F00équipe rouge remporte ce tour.',
	'maps' => 'maps',
	'map' => 'map',
	'No map' => 'Aucune map',
	'matchsettings' => 'matchsettings',
	'matchsetting' => 'matchsetting',
	'No matchsetting' => 'Aucun matchsetting',
	'text->XML conversion error' => 'Erreur de conversion texte->XML',
	'Saving XML file error' => 'Erreur d\'entregistrement du fichier XML',
	'The folder "logs" is not writable.' => 'Le dossier "logs" ne permet pas l\'écriture de log.',
	'The folder "logs" does not exist.' => 'Le dossier "logs" n\'existe pas.',
	'Unable to create log file:' => 'Impossible de créer le fichier de log :',
	'Unable to add log in file:' => 'Impossible d\'ajouter un log au fichier :',
	'This server does not exist' => 'Ce serveur n\'existe pas',
	'Change password' => 'Changer le mot de passe',
	'Current' => 'Actuel',
	'The current password doesn\'t match.' => 'Le mot de passe actuel ne correspond pas.',
	'The password has been changed.' => 'Le mot de passe a bien été changé.',
	'Not rated' => 'Non classé',
	'Unable to delete server.' => 'Impossible de supprimer ce serveur',
	'Guest-Ban' => 'Invités-Bannis',
	'Access as player' => 'Accéder en joueur',
	'Access as spectator' => 'Accéder en spectateur',
	'Disable horns' => 'Désactiver les klaxons',
	'Current vote' => 'Vote en cours',
	'Cancel vote' => 'Annuler le vote',
	'Change order' => 'Changer l\'ordre',
	'Servers order' => 'Ordre des serveurs',
	'This path was not required rights:' => 'Le chemin suivant n\'a pas les droits requis :',
	'needs' => 'a besoin de',
	'Plugin error: script.php or view.php file is missing.' => 'Erreur de plugin : le fichier script.php ou view.php est manquant.',
	'No server admin levels configured.' => 'Aucun niveau admin configuré pour ce serveur.',
	'Gold time' => 'Temps or',
	'Cost' => 'Coût',
	'Team infos' => 'Infos sur les équipes',
	'Script settings' => 'Paramètres de script',
	'Script settings updated.' => 'Paramètres de script mis à jour.',
	'Change authentication password' => 'Changer le mot de passe d\'un compte',
	'You changed the password "!authLevel", remember it at the next connection!' => 'Vous venez de changer le mot de passe "!authLevel", pensez-y à la prochaine connexion !',
	'Automatic' => 'Automatique',
	'Choose number' => 'Choisir un nombre',
	'Client inputs max latency' => 'Latence max des clients',
	'Script info' => 'Informations',
	'Compatible map types' => 'Types de map compatibles',
	'Script parameters' => 'Paramètres',
	'Value' => 'Valeur',
	'The server already exist! Change the name.' => 'Le serveur existe déjà ! Changez le nom.',
	'Version' => 'Version',
	'Disable vote ratio' => 'Désactiver le ratio vote',
	'Manage server options' => 'Gérer les options du serveur',
	'Import' => 'Importer',
	'Export' => 'Exporter',
	'No export available' => 'Pas d\'export disponible',
	'No such file or file is not readable' => 'Le fichier n\'existe pas ou n\'est pas lisible',
	'Server options are exported in' => 'Les options du serveur sont exportées dans',
	'Unable to export server options' => 'Impossible d\'exporter les options du serveur',
	'Maps base folder' => 'Dossier de base pour les maps',
	'Default path from maps folder for listing maps' => 'Chemin par défaut à partir du dossier "Maps" pour lister les maps',
	'No folder' => 'Aucun dossier',
	'Server selection' => 'Sélection du serveur',
	'Configuration' => 'Configuration',
	'Force the scores' => 'Forcer les scores',
	'Folders' => 'Dossiers',
	'Admin levels' => 'Niveaux d\'admin',
	'admin levels' => 'niveaux d\'admin',
	'Admin levels list' => 'Liste des niveaux d\'admin',
	'Access' => 'Accès',
	'Permissions' => 'Permissions',
	'authorized access' => 'accès autorisés',
	'authorized permissions' => 'permissions autorisées',
	'Add level' => 'Ajouter un niveau',
	'Edit level' => 'Éditer un niveau',
	'Level name' => 'Nom du niveau',
	'Level type' => 'Type de niveau',
	'Add access' => 'Ajouter un accès',
	'All access' => 'Tous les accès',
	'Selected access' => 'Accès sélectionnés',
	'Add permission' => 'Ajouter une permission',
	'All permissions' => 'Toutes les permissions',
	'Selected permissions' => 'Permissions sélectionnées',
	'Levels order' => 'Ordre des niveaux',
	'This admin level has been duplicated.' => 'Le niveau admin a bien été dupliqué.',
	'Unable to duplicate admin level.' => 'Impossible de dupliquer le niveau admin.',
	'The "!levelName" admin level has been deleted.' => 'Le niveau admin "!levelName" a été supprimé.',
	'Unable to delete admin level.' => 'Impossible de supprimer le niveau admin.',
	'This admin level has been modified.' => 'Le niveau admin a bien été modifié.',
	'Unable to modify the admin level.' => 'Impossible de modifier le niveau admin.',
	'This admin level has been added.' => 'Le niveau admin a bien été ajouté.',
	'Unable to add the admin level.' => 'Impossible d\'ajouter le niveau admin.',
);
?>
<?php
/**
* Dutch translation
*
* @author   Weerwolf
* @version  1.0
*/
$translate = array(
	'Access server' => 'Toegang Server',
	'Access relay' => 'Toegang Relay',
	'Disconnect' => 'Verbinding Verbreken',
	'Servers' => 'Servers',
	'Server' => 'Server',
	'Password' => 'Wachtwoord',
	'Admin level' => 'Admin Level',
	'Connection' => 'Verbinding',
	'Please put a password.' => 'Wachtwoord Invoeren',
	'Connection error' => 'Verbindingsfout',
	'Connection error: invalid session.' => 'Verbindingsfout: Ongeldige Sessie',
	'Servers configuration' => 'Server Configuratie',
	'Online configuration' => 'Online Configuratie',
	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'Dit is je 1e verbinding en er zijn geen servers geconfigureerd. Kies een wachtwoord om server te gaan configureren',
	'Unable to save password.' => 'Wachtwoord kan niet opgeslagen worden.',
	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Online configuratie is uitgeschakeld. Gebruik "./config/servers.cfg.php" om servers te configureren.',
	'Offline server.' => 'Server Offline.',
	'Authentication error.' => 'Aanmeldingsfout.',
	'Add to favourite' => 'Aan favorieten Toevoegen',
	'Current map' => 'Huidige Map',
	'Name' => 'Naam',
	'Author' => 'Auteur',
	'Environment' => 'Omgeving',
	'Map UId' => 'Map UId',
	'Game mode' => 'Spel Mode',
	'No thumbnail' => 'Geen Voorbeeld',
	'Server name' => 'Server Naam',
	'Status' => 'Status',
	'Server login' => 'Server Login',
	'Connected on' => 'Verbonden met',
	'Dedicated version' => 'Server Versie',
	'Statistics' => 'Statestieken',
	'Uptime' => 'Tijd Online',
	'Number of connections' => 'Aantal verbindingen',
	'Average connection time' => 'Gemiddelde Tijd Verbinding',
	'Average number of players' => 'Gemiddeld aantal Spelers',
	'Recv net rate' => 'Downloadsnelheid',
	'Send net rate' => 'Uploadsnelheid',
	'Total receiving size' => 'Totaal Ontvangen',
	'Total sending size' => 'Totaal Verzonden',
	'Players' => 'Spelers',
	'Detailed mode' => 'Detail Weergave',
	'Simple mode' => 'Eenvoudige Weergave',
	'Nickname' => 'Schuilnaam',
	'Login' => 'Login',
	'For the selection' => 'Voor De Selectie',
	'Ban' => 'Uitsluiten',
	'Kick' => 'Verwijderen',
	'Spectator' => 'Toeschouwer',
	'Player' => 'Speler',
	'Team' => 'Team',
	'Guest' => 'Gast',
	'Ignore' => 'Negeren',
	'Red team' => 'Rode Team',
	'Blue team' => 'Blauwe Team',
	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Ergebnisse wurden geändert : Les scores ont été modifiés : $00fblaue Team$fff hat !scoreTeamBlue und l\'$f00rote Team $fffhat !scoreTeamRed',
	'Server options' => 'Server Opties',
	'General' => 'Algemeen',
	'Comment' => 'Commentaar',
	'Player password' => 'Speler Wachtwoord',
	'Spectator password' => 'Toeschouwer Wachtwoord',
	'Nb max of players' => 'Max Aantal Spelers',
	'Next value' => 'Volgende Waarde',
	'Nb max of spectators' => 'Max Aantal Toeschouwers',
	'Advanced' => 'Geavanceerd',
	'P2P Upload' => 'P2P Upload',
	'P2P Download' => 'P2P Download',
	'Ladder mode' => 'Ladder Mode',
	'Vehicles quality' => 'Voertuig Kwaliteit',
	'Vote expiration' => 'Stemtijd',
	'sec' => 'seconden', // Second
	'Vote ratio' => 'Stem Percentage',
	'Hidden server' => 'Verborgen Server',
	'Map download' => 'Maps Downloaden',
	'Replays auto save' => 'Automatisch herhalingen opslaan',
	'Buddy notification' => 'Notificatie Vrienden',
	'Save' => 'Opslaan',
	'Inactive' => 'Inactief',
	'Forced' => 'Geforceerd',
	'Fast' => 'Snel',
	'High' => 'Hoog',
	'Game infos' => 'Spelinformatie',
	'Game information' => 'Spelnformatie',
	'Color' => 'Kleur',
	'Black' => 'Zwart',
	'Red' => 'Rood',
	'Green' => 'Groen',
	'Blue' => 'Blauw',
	'Orange' => 'Oranje',
	'Pink' => 'Roze',
	'Purple' => 'Paars',
	'Grey' => 'Grijs',
	'White' => 'Wit',
	'Message destination' => 'Bestemming bericht',
	'Chat' => 'Chat',
	'Show server lines' => 'Regels Server Tonen',
	'Hide server lines' => 'Regels Server Verbergen',
	'Default color: yellow' => 'Standaard Kleur: Geel',
	'Message' => 'Bericht',
	'Destination' => 'Bestemming',
	'Send' => 'Versturen',
	'Unable to create the folder' => 'Aanmaken Directory Mislukt',
	'Unable to rename the folder' => 'Hernoemen Directory Mislukt',
	'Unable to move the folder' => 'Verplaatsen Directory Mislukt',
	'Unable to delete the folder' => 'Verwijderen Directory Mislukt',
	'List' => 'Lijst',
	'Go to the current map' => 'Ga Naar De Huidige Map',
	'Map' => 'Map',
	'Delete' => 'Verwijderen',
	'Move after the current map' => 'Plaats Achter De Huidige Map',
	'Unable to rename the map' => 'De Map Kon Niet Worden Hernoemd',
	'Unable to move the map' => 'De Map Kon Niet Worden Verplaatst',
	'Unable to delete the map' => 'De Map Kon Niet Worden Verwijderd',
	'Local' => 'Lokaal',
	'Do you really want to remove this selection?' => 'Wil Je Echt De Huidige Selectie Verwijderen',
	'Move' => 'Verplaatsen',
	'Rename' => 'Hernoemen',
	'Download' => 'Downloaden',
	'Insert' => 'Invoegen',
	'Add' => 'Toevoegen',
	'Cancel' => 'Afbreken',
	'Replace the special characters' => 'Vervang de speciale tekens',
	'in the folder:' => 'In De Directory:',
	'Root' => 'Root',
	'The map,is currently used by the server.' => 'Deze map wordt op dit moment door de server gebruikt.',
	'MatchSettings' => 'MatchSettings',
	'Contains' => 'Bevat',
	'Modified' => 'Aangepast',
	'Edit' => 'Aanpassen',
	'Load' => 'Laden',
	'Save ' => 'Opslaan',
	'Create' => 'Aanmaken',
	'Unable to save the MatchSettings' => 'Oplsaan MatchSettings Mislukt',
	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'MatchSettings "!matchSettingName" Aanmaken In De Directory Geslaagd',
	'a MatchSettings' => 'MatchSettings',
	'Create a MatchSettings' => 'MatchSettings Aanmaken',
	'MatchSettings name' => 'Naam MatchSettings',
	'Maps' => 'Maps',
	'Make selection' => 'Maak Een Selectie',
	'Import all folder' => 'Importeer Hele Dirtectory',
	'Select' => 'Selecteren',
	'MatchSettings selected maps:' => 'MatchSettings Geslecteerde Maps:',
	'View the MatchSettings selection' => 'MatchSettings Gekozen Selectie Bekijken',
	'MatchSettings selection' => 'MatchSettings Selectie',
	'Remove map from the selection' => 'Map Uit De Selectie Verwijderen',
	'Close' => 'Sluiten',
	'HotSeat' => 'HotSeat',
	'Time limit' => 'Tijdlimiet',
	'Rounds count' => 'Aantal Ronden',
	'Filter' => 'Filter',
	'Lan' => 'Lan',
	'Internet' => 'Internet',
	'Solo' => 'Solo',
	'Sort index' => 'Sortering Index',
	'Random map order' => 'Willekeurig Map Volgorde',
	'Default game mode' => 'Standaard Spel Mode',
	'No map selected for the MatchSettings.' => 'Geen Map voor de MatchSettings Geselecteerd.',
	'The MatchSettings name already exists! It will be overwritten.' => 'De Naam Voor Deze MatchSettings Bestaat Al, En Zal Worden Overschreven.',
	'Order' => 'Rangschikken',
	'Automatic sort' => 'Automatisch Sorteren',
	'Random' => 'Willekeurig',
	'Manual sort' => 'Handmatig Sorteren',
	'Save the current MatchSettings' => 'De Huidige MatchSettings Opslaan',
	'Reset' => 'Resetten',
	'Transfer mode' => 'Overdrachtsmode',
	'at the end of list' => 'Aan Het Einde Van de Lijst',
	'after current map' => 'Achter De Huidige Map',
	'only in the folder' => 'Alleen In De Directory',
	'Options' => 'Opties',
	'Go to the maps list when upload is complete' => 'Ga Naar De Maplijst Als De Upload Klaar Is',
	'Upload' => 'Upload',
	'Failed' => 'Mislukt',
	'Upload a file' => 'Bestand Uploaden',
	'Drop files here to upload' => 'Sleep Bestanden Hier Om Te Uploaden',
	'Upload not finished' => 'Uploaden Nog Niet Klaar',
	'from' => 'Van',
	'Kb' => 'Kb',
	'Mb' => 'Mb',
	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} Heeft Een Ongeldig Bestandsformaat. Toegestane Formaten Zijn: {extensions}.',
	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} Is te Groot. De Maximale Groote is: {sizeLimit}.',
	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} Is Te Klein. De Minimale Grootte is: {minSizeLimit}.',
	'{file} is empty, please select files again without it.' => '{file} Is Leeg. Selecteer Nogmaals.',
	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'De Bestanden Worden Geupload. Als Je Nu Het Scherm Sluit, Wordt De Upload Afgebroken.',
	'No file was uploaded' => 'Er Zijn Geen Bestanden Geupload',
	'The file is empty.' => 'Het Bestand Is Leeg.',
	'The file size is too large.' => 'Het Bestand Is Te Groot.',
	'The file has invalid extension (allowed extensions:' => 'Het Bestand Heeft Een Ongeldig Formaat (Toegestane Formaten zijn:',
	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Het Bestand Is Niet Geupload. De upload Is AfgebrokenOf Er Is Een Serverfout Opgetreden.',
	'Server error. The upload destination folder isn\'t writable.' => 'Serverfout. De Doeldirectory Is Niet Schrijfbaar.',
	'Plugins' => 'Invoegtoepassingen',
	'plugin installed' => 'Invoegtoepassing Geinstalleerd',
	'plugins installed' => 'Invoegtoepassingen Geinstalleerd',
	'Cannot include another plugins config file.' => 'Er kunnen geen Invoegtoepassing Configuratiebestanden Ingesloten Worden.',
	'Variable "$PLUGINS" not found.' => 'Variabele "$PLUGINS" Niet Gevonden.',
	'Plugins are extensions to add features to Adminserv.' => 'Invoegtoepassingen zijn Extenties die Functionaliteit aan AdminServ Toevoegen.',
	'Install a plugin' => 'Invoegtoepassing Installeren',
	'See all plugins:' => 'Bekijk Alle Invoegtoepassingen:',
	'Click here' => 'Klik Hier',
	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Entpacken sie das Plugin und verschieben Sie den Inhalt in den &laquo; plugins &raquo; Ordner von AdminServ.',
	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'Fügen Sie den Namen des Plugin Ordners in der Konfiguratiosdatei der Erweiterungen ein(extension.cfg.php).',
	'Create a new plugin' => 'Nieuwe Invoegtoepassing Aanmaken',
	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>Um ein Plugin zu erstellen, gehe in de Plugin Orner und kopiere den Ordner _newplugin. Ersetze die Werte in der config.ini Datei und bennene den Order um.<br />Dort befinden sich zwei PHP Dateien:</p><ul><li>script.php : Diese Datei wird vor dem Header der Seite ausgeführt. Hier werden alle Plugin Scripte plaziert.</li><li>view.php : Diese Datei ist für die Anzeige des Plugins verantworlich und wird nach dem Header der seite ausgeführt. Hier wird der ganze HTML Code plaziert.</li></ul><p>Die benötigten Recourcen (classes, js, css) können Sie in die Dateien einbinden.</p>',
	'Unable to delete the playlist' => 'Kan De Speellijst Niet Wissen',
	'Player login' => 'Speler Login',
	'Clean the list' => 'Lijst Legen',
	'The list is already empty.' => 'De Lijst Is Al Leeg.',
	'No player' => 'Geen Speler(s) Op De Server',
	'IP address' => 'IP Adres',
	'Client' => 'Client',
	'Blacklist' => 'Zwarte Lijst',
	'Remove from the list' => 'Verwijder Van De Lijst',
	'Select a player' => 'Selecteer Een Speler',
	'Enter another login' => 'Voer Een Andere Login In',
	'Add in the' => 'Voeg Toe Aan',
	'Playlists' => 'Speellijsten',
	'Playlist' => 'Speellijst',
	'Type' => 'Type',
	'Playlist name' => 'Naam Speellijst',
	'New playlist' => 'Nieuwe Speellijst',
	'players' => 'Spelers',
	'player' => 'Speler',
	'No playlist' => 'Geen Speellijst',
	'You are not allowed to configure the servers' => 'Je Bent Niet Bevoegd Om Servers Te Configureren.',
	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Geen Server Beschikbaar. Om Servers Toe Te Voegen, Configureer "config/servers.cfg.php"',
	'The servers configuration file isn\'t recognized by AdminServ.' => 'Het Server Configuratiebestand Wordt Niet Door AdminServ Herkend.',
	'This server has been duplicated.' => 'Deze Server Is Met Succes Gedupliceerd.',
	'Unable to duplicate server.' => 'Kan De Server Niet Dupliceren.',
	'copy' => 'Kopie',
	'Servers list' => 'Serverlijst',
	'Address' => 'Adres',
	'Port' => 'Poort',
	'SuperAdmin level' => 'SuperAdmin Rang',
	'User level' => 'Gebruiker Rang',
	'Manage' => 'Beheren',
	'None' => 'Geen',
	'Local network' => 'Lokaal Netwerk',
	'All' => 'Alle',
	'Removed' => 'Verwijderd',
	'Missing' => 'Ontbreekt',
	'No server' => 'Geen Server',
	'servers' => 'Servers',
	'server' => 'Server',
	'Duplicate' => 'Dupliceer',
	'Modify' => 'Wijzig',
	'The "!serverName" server has been deleted.' => 'De server "!serverName" Werd Verwijderd.',
	'This server has been modified.' => 'Deze Server werd Aangepast.',
	'Unable to modify the server.' => 'Kan De Server Niet Aanpassen.',
	'This server has been added.' => 'Deze Server Is Met Succes Toegevoegd.',
	'Unable to add the server.' => 'Kan De Server Niet Toevoegen.',
	'Add server' => 'Server Toevoegen',
	'Edit server' => 'Server Aanpassen',
	'Back' => 'Terug',
	'Connection information' => 'Informatie Verbinding',
	'Server name without color' => 'Servernaam Zonder Kleur',
	'IP address or domain name' => 'IP Adres of Domeinnaam',
	'XMLRPC port' => 'XMLRPC Poort',
	'Port for remote control' => 'Poort voor Externe Toegang',
	'Optionnal information' => 'Optionele Informatie',
	'Server MatchSettings' => 'Server MatchSettings',
	'Current server MatchSettings name' => 'Server\'s huidige MatchSettings Naam',
	'Possible values for the admin level:' => 'Mogelijke Waarden voor de Admin rang:',
	'all => all access' => 'all => Alle toegang',
	'local => local network access' => 'local => Lokaal Netwerk Toegang',
	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => Toegang Vanaf 1 of meerdere IP Adressen',
	'none => removed from the access list' => 'none => Uit de Toegangslijst Verwijderd',
	'No server available' => 'Geen Server(s) Beschikbaar',
	'No game mode available' => 'Geen Speelmode Beschikbaar',
	'Map end time' => 'Map Einde Tijd',
	'Round/lap end time' => 'Ronde Einde Tijd',
	'Respawn' => 'Respawn',
	'Default' => 'Standaard',
	'Auto (based on map)' => 'Automatisch (Afhankelijk Van De Map)',
	'Choose time' => 'Tijd Selecteren',
	'Return to the default value' => 'Terug Naar De Standaard Waarde',
	'All WarmUp duration' => 'Tijd Voor Opwarming',
	'Enable' => 'Activieren',
	'Disable' => 'Deactivieren',
	'Force show of all opponents' => 'Forceer Alle Spelers Zichtbaar',
	'Let player choose' => 'Laat De Speler Kiezen',
	'All opponents' => 'Alle Tegenstanders',
	'minimal opponents' => 'Minimale Tegenstanders',
	'Choose opponents number' => 'Kies Aantal Tegenstanders',
	'Script name' => 'Script Naam',
	'Use new rules' => 'Nieuwe Regels Gebruiken',
	'Points limit' => 'Puntenlimiet',
	'Custom points limit' => 'Aangepaste Puntenlimiet',
	'Force laps' => 'Forceer Ronden',
	'Start synchronization period' => 'Synchronisatietijd Bij Start',
	'Maximal points' => 'Maximaal Aantal Punten',
	'Number of laps' => 'Aantal Ronden',
	'Rounds per map' => 'Ronden Per Map',
	'Number of winners' => 'Gewinner Nummer',
	'No player available' => 'Geen Speler Beschikbaar',
	'New' => 'Nieuw',
	'Parent folder' => 'Huidige Directory',
	'Folder options' => 'Directory Opties',
	'Do you really want to remove this folder !currentDir?' => 'Wil Je Echt Deze Directory Verwijderen: !currentDir?',
	'Rename folder' => 'Directory Hernoemen',
	'Move folder' => 'Directory Verplaatsen',
	'Move folder <b>!currentDir</b> in:' => 'Verplaats Directory <b>!currentDir</b> naar:',
	'The server is not accessible.' => 'De Server Is Niet Bereikbaar.',
	'You are not allowed at this admin level' => 'Je bent Niet Bevoegd met je Rang.',
	'The password doesn\'t match to the server.' => 'Het Opgegegven WachtWoord Komt Niet Overeen Met Die Van De Server.',
	'Client not initialized' => 'client nicht initialisiert',
	'Unknown command' => 'Onbekende Opdracht',
	'$99FThis round is a draw.' => '$99FDeze Ronde Is Gelijk Spel.',
	'$99FThe $<$00FBlue team$> wins this round.' => '$99FHet $00Fblauwe Team Wint Deze Ronde.',
	'$99FThe $<$F00Red team$> wins this round.' => '$99FHet $F00Rode Team Wint Deze Ronde.',
	'maps' => 'Maps',
	'map' => 'Map',
	'No map' => 'Geen Map',
	'matchsettings' => 'Matchsettings',
	'matchsetting' => 'Matchsetting',
	'No matchsetting' => 'Geen Matchsetting',
	'text->XML conversion error' => 'text->XML conversiefout',
	'Saving XML file error' => 'Fout Bij Opslaan XML File',
	'The folder "logs" is not writable.' => 'De Directory "logs" Kan Niet Beschreven Worden.',
	'The folder "logs" does not exist.' => 'De Directory "logs" Bestaat Niet.',
	'Unable to create log file:' => 'Kan het Logbestand Niet Aanmaken:',
	'Unable to add log in file:' => 'Kan Niets Toevoegen Aan Het Logbestand:',
	'This server does not exist' => 'Deze Server Bestaat Niet',
	'Change password' => 'Verander Wachtwoord',
	'Current' => 'Huidig',
	'The current password doesn\'t match.' => 'Het Huidige Wachtwoord Komt Niet Overeen.',
	'The password has been changed.' => 'Het Wachtwoor is Aangepast.',
	'Not rated' => 'Niet Beoordeeld',
	'Unable to delete server.' => 'Kan De Server Niet Verwijderen',
	'Guest-Ban' => 'Gasten-Bannen',
	'Access as player' => 'Verbinden Als Speler',
	'Access as spectator' => 'verbinden als Toeschouwer',
	'Disable horns' => 'Toeters Deactiveren',
	'Current vote' => 'Huidige Beoordeling',
	'Cancel vote' => 'Beoordeling Afbre3ken',
	'Change order' => 'Verander Rangschikking',
	'Servers order' => 'Rangschikking Servers',
	'This path was not required rights:' => 'Dir Pad Had Geen Vereiste Rechten:',
	'needs' => 'Afhankelijkheden',
	'Plugin error: script.php or view.php file is missing.' => 'Fout Invoegtoepassing: script.php of view.php Ontbreekt.',
	'No server admin levels configured.' => 'Geen Server Rangen Geconfigureerd.',
	'Gold time' => 'Gouden Tijd',
	'Cost' => 'Kosten',
	'Team infos' => 'Team Informatie',
	'Script settings' => 'Script Instellingen',
	'Script settings updated.' => 'Script Instellingen Bijgewerkt.',
	'Change authentication password' => 'Verander authenticatie wachtwoord',
	'You changed the password "!authLevel", remember it at the next connection!' => 'Het Wachtwoor Is Aangepast "!authLevel", Onthoud Dit Voor De Volgende Keer!',
	'Automatic' => 'Automatisch',
	'Choose number' => 'Kies Aantal',
	'Client inputs max latency' => 'Maximale vertraging Client (Ping)',
	'Script info' => 'Script Informatie',
	'Compatible map types' => 'Overeenkomende Map Typen',
	'Script parameters' => 'Script Waarden',
	'Value' => 'Waarde',
	'The server already exist! Change the name.' => 'De Server Bestaat Al! Verander De Naam.',
);
?>
﻿<?php
/**
* Norsk translation
*
* @author   W00p 
* @version  1.0
*/
$translate = array(
	'Access server' => 'Tilgang server',
	'Access relay' => 'Tilgang relay',
	'Disconnect' => 'Koble fra',
	'Servers' => 'Servere',
	'Server' => 'Server',
	'Password' => 'Passord',
	'Admin level' => 'Administrasjonsnivå',
	'Connection' => 'Koble til',
	'Please put a password.' => 'Vennligst skriv inn et passord.',
	'Connection error' => 'Tilkoblings feil',
	'Connection error: invalid session.' => 'Tilkoblings feil: ugyldig økt.',
	'Servers configuration' => 'Server konfigurasjon',
	'Online configuration' => 'Online konfigurasjon',
	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'Dette er din første tilkobling og ingen servere er konfigurert. Velg et passord for å konfigere dine servere.',
	'Unable to save password.' => 'Feil ved lagring av passord.',
	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Online konfigurering er deaktivert. Bruk "./config/servers.cfg.php".',
	'Offline server.' => 'Frakoblet server.',
	'Authentication error.' => 'Autentiseringsfeil.',
	'Add to favourite' => 'Legg til som favoritt',
	'Current map' => 'Gjeldende bane',
	'Name' => 'Navn',
	'Author' => 'Laget av',
	'Environment' => 'Miljø',
	'Map UId' => 'Bane UId',
	'Game mode' => 'Spillmodus',
	'No thumbnail' => 'Ingen miniatyrbilde',
	'Server name' => 'Server navn',
	'Status' => 'Status',
	'Server login' => 'Server logginn',
	'Connected on' => 'Tilkoblet på',
	'Dedicated version' => 'Dedicated versjon',
	'Statistics' => 'Statistikk',
	'Uptime' => 'Oppetid',
	'Number of connections' => 'Antall tilkoblinger',
	'Average connection time' => 'Gjennomsnittlig tilkoblingstiden',
	'Average number of players' => 'Gjennomsnittlig antall spillere',
	'Recv net rate' => 'Recv net rate',
	'Send net rate' => 'Send net rate',
	'Total receiving size' => 'Totalt størrelse mottat',
	'Total sending size' => 'Totalt størrelse sendt',
	'Players' => 'Spillere',
	'Detailed mode' => 'Detaljert modus',
	'Simple mode' => 'Enkel modus',
	'Nickname' => 'Kallenavn',
	'Login' => 'Logginn',
	'For the selection' => 'Valg',
	'Ban' => 'Utesteng',
	'Kick' => 'Sparke',
	'Spectator' => 'Tilskuer',
	'Player' => 'Spiller',
	'Team' => 'Lag',
	'Guest' => 'Gjest',
	'Ignore' => 'Ignorer',
	'Red team' => 'Rødt lag',
	'Blue team' => 'Blått lag',
	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Resultatet har blitt endret: $00fblått lag $fffhar !scoreTeamBlue og $f00rødt lag $fffhar !scoreTeamRed',
	'Server options' => 'Serverinnstillinger',
	'General' => 'Generelt',
	'Comment' => 'Kommentar',
	'Player password' => 'Spiller passord',
	'Spectator password' => 'Tilskuer passord',
	'Nb max of players' => 'Maks antall spillere',
	'Next value' => 'Neste valg',
	'Nb max of spectators' => 'Maks antall tilskuere',
	'Advanced' => 'Avansert',
	'P2P Upload' => 'P2P Opplasting',
	'P2P Download' => 'P2P Nedlasting',
	'Ladder mode' => 'Ladder modus',
	'Vehicles quality' => 'Kvalitet på kjøretøy',
	'Vote expiration' => 'Stemme utløpsdato',
	'sec' => 'sek', // Second
	'Vote ratio' => 'Stemme forhold',
	'Hidden server' => 'Skjul server',
	'Map download' => 'Bane nedlasting',
	'Replays auto save' => 'autolagring av repriser',
	'Buddy notification' => 'Kompis varsling',
	'Save' => 'Lagre',
	'Inactive' => 'Inaktiv',
	'Forced' => 'Tvunget',
	'Fast' => 'Rask',
	'High' => 'Høy',
	'Game infos' => 'Spillinnstillinger',
	'Game information' => 'Spillinnstillinger',
	'Color' => 'Farge',
	'Black' => 'Sort',
	'Red' => 'Rødt',
	'Green' => 'Grønt',
	'Blue' => 'Blå',
	'Orange' => 'Orange',
	'Pink' => 'Rosa',
	'Purple' => 'Violett',
	'Grey' => 'Grå',
	'White' => 'Hvit',
	'Message destination' => 'Meldings destinasjon',
	'Chat' => 'Prate',
	'Show server lines' => 'Se server linjer',
	'Hide server lines' => 'Skjul server linjer',
	'Default color: yellow' => 'Standard farge: gul',
	'Message' => 'Melding',
	'Destination' => 'Destinasjon',
	'Send' => 'Last opp',
	'Unable to create the folder' => 'Kan ikke opprettet mappen',
	'Unable to rename the folder' => 'Kan ikke endre navn på mappen',
	'Unable to move the folder' => 'Kan ikke flytte mappen',
	'Unable to delete the folder' => 'Kan ikke slettet mappen',
	'List' => 'Liste',
	'Go to the current map' => 'Gå til gjeldende bane',
	'Map' => 'Bane',
	'Delete' => 'Slett',
	'Move after the current map' => 'Flytt etter gjeldende bane',
	'Unable to rename the map' => 'Kan ikke endre navnet på banen',
	'Unable to move the map' => 'Kan ikke flytte banen',
	'Unable to delete the map' => 'Kan ikke slette banen',
	'Local' => 'Lokal',
	'Do you really want to remove this selection?' => 'Vil du virkelig fjerne dette valget?',
	'Move' => 'Flytt',
	'Rename' => 'Endre navn',
	'Download' => 'Last ned',
	'Insert' => 'Sett inn',
	'Add' => 'Legg til',
	'Cancel' => 'Avbryt',
	'Replace the special characters' => 'Erstatte spesialtegn',
	'in the folder:' => 'i mappen:',
	'Root' => 'Roten',
	'The map,is currently used by the server.' => 'Banen er i bruk av serveren.',
	'MatchSettings' => 'MatchSettings',
	'Contains' => 'Inneholder',
	'Modified' => 'Endret',
	'Edit' => 'Rediger',
	'Load' => 'Last',
	'Save ' => 'Lagre',
	'Create' => 'Opprett',
	'Unable to save the MatchSettings' => 'Kan ikke lagre MatchSettings',
	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'MatchSettings "!matchSettingName" var vellykket opprettet i mappen',
	'a MatchSettings' => 'en MatchSettings',
	'Create a MatchSettings' => 'Opprett en MatchSettings',
	'MatchSettings name' => 'MatchSettings navn',
	'Maps' => 'Baner',
	'Make selection' => 'Opprett valgene',
	'Import all folder' => 'Importer alle mappene',
	'Select' => 'Velg',
	'MatchSettings selected maps:' => 'MatchSettings valgte baner:',
	'View the MatchSettings selection' => 'Se MatchSettings valgene',
	'MatchSettings selection' => 'MatchSettings valg',
	'Remove map from the selection' => 'Fjern baner fra valget',
	'Close' => 'Lukk',
	'HotSeat' => 'HotSeat',
	'Time limit' => 'Tidsfrit',
	'Rounds count' => 'Runde teller',
	'Filter' => 'Filter',
	'Lan' => 'Lan',
	'Internet' => 'Internet',
	'Solo' => 'Solo',
	'Sort index' => 'Indeks sortering',
	'Random map order' => 'Tilfeldig bane rekkefølge',
	'Default game mode' => 'Standard spillmodus',
	'No map selected for the MatchSettings.' => 'Ingen baner valgt for MatchSettings.',
	'The MatchSettings name already exists! It will be overwritten.' => 'MatchSettings navnet finnes allerede! Det vil bli overskrevet.',
	'Order' => 'Rekkefølge',
	'Automatic sort' => 'Automatisk sortering',
	'Random' => 'Tilfeldig',
	'Manual sort' => 'Manuell sortering',
	'Save the current MatchSettings' => 'Lagre gjeldende MatchSettings',
	'Reset' => 'Tilbakestill',
	'Transfer mode' => 'Transfer modus',
	'at the end of list' => 'til slutten av listen',
	'after current map' => 'etter gjeldende bane',
	'only in the folder' => 'kun i mappen',
	'Options' => 'Alternativer',
	'Go to the maps list when upload is complete' => 'Gå til banelisten når opplastingen er ferdig',
	'Upload' => 'Last opp',
	'Failed' => 'Mislyktes',
	'Upload a file' => 'Last opp en fil',
	'Drop files here to upload' => 'Slipp filer her for å laste opp',
	'Upload not finished' => 'Opplasting ikke ferdig',
	'from' => 'fra',
	'Kb' => 'Kb',
	'Mb' => 'Mb',
	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} har ugyldig utvidelse. Bare {extensions} er tillatt.',
	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} er for stor, maks tillatt størrelse er {sizeLimit}.',
	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} er for liten, minste filstørrelse er {minSizeLimit}.',
	'{file} is empty, please select files again without it.' => '{file} er tom, vennligst velg filen igjen.',
	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Filer blir nå lastet opp, forlater du siden nå vil opplasting bli kasellert.',
	'No file was uploaded' => 'Ingen filer ble lastet opp',
	'The file is empty.' => 'Filer er tom.',
	'The file size is too large.' => 'Størrelsen på filen er for stor.',
	'The file has invalid extension (allowed extensions:' => 'Filen har ugyldig utvidelse (tillatt utvidelser:',
	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Filen ble ikke lastet opp. Opplasting har blitt kansellert, eller en server feil har oppstått.',
	'Server error. The upload destination folder isn\'t writable.' => 'Server feil. Opplastings mappe er ikke skrivbar.',
	'Plugins' => 'Programtillegg',
	'plugin installed' => 'programtillegg installert',
	'plugins installed' => 'Programtillegg installert',
	'Cannot include another plugins config file.' => 'Kan ikke inkludere en annen konfigurasjons fil til programtillegg.',
	'Variable "$PLUGINS" not found.' => 'Variabel "$PLUGINS" ikke funnet.',
	'Plugins are extensions to add features to Adminserv.' => 'Programtillegg er utvidelser for ekstra funksjoner til Adminserv.',
	'Install a plugin' => 'Installer er programtillegg',
	'See all plugins:' => 'Zeige alle Plugins:',
	'Click here' => 'Klikk her',
	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Pakk ut filene til programtillegget og legg det i &laquo; plugins &raquo; mappen til Adminserv.',
	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'I konfigurasjons utvidelsen, legg til navnet på programtillegg mappen du nylagt pakket ut.',
	'Create a new plugin' => 'Opprett et nytt programtillegg',
	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>Um ein Plugin zu erstellen, gehe in de Plugin Orner und kopiere den Ordner _newplugin. Ersetze die Werte in der config.ini Datei und bennene den Order um.<br />Dort befinden sich zwei PHP Dateien:</p><ul><li>script.php : Diese Datei wird vor dem Header der Seite ausgeführt. Hier werden alle Plugin Scripte plaziert.</li><li>view.php : Diese Datei ist für die Anzeige des Plugins verantworlich und wird nach dem Header der seite ausgeführt. Hier wird der ganze HTML Code plaziert.</li></ul><p>Die benötigten Recourcen (classes, js, css) können Sie in die Dateien einbinden.</p>',
	'Unable to delete the playlist' => 'Kan ikke slette spillelisten',
	'Player login' => 'Spiller logginn',
	'Clean the list' => 'Tøm listen',
	'The list is already empty.' => 'Listen er allerede tom.',
	'No player' => 'Ingen spillere',
	'IP address' => 'IP adresse',
	'Client' => 'Klient',
	'Blacklist' => 'Svartelistet',
	'Remove from the list' => 'Fjern fra listen',
	'Select a player' => 'Velg en spiller',
	'Enter another login' => 'Skriv et annet logginn',
	'Add in the' => 'Legg til i',
	'Playlists' => 'Spillelister',
	'Playlist' => 'Spilleliste',
	'Type' => 'Type',
	'Playlist name' => 'Spillelistens navn',
	'New playlist' => 'Ny spilleliste',
	'players' => 'Spillere',
	'player' => 'Spiller',
	'No playlist' => 'Ingen spilleliste',
	'You are not allowed to configure the servers' => 'Du har ikke rettigheter til konfigurering av serverene.',
	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Ingen servere tilgjengelig. For å legge til ny, konfigurer "config/servers.cfg.php"',
	'The servers configuration file isn\'t recognized by AdminServ.' => 'Server konfigurasjonsfilen kan ikke gjenkjennes av Adminserv.',
	'This server has been duplicated.' => 'Denne servere har blitt duplisert.',
	'Unable to duplicate server.' => 'Kan ikke duplisere serveren.',
	'copy' => 'Kopier',
	'Servers list' => 'Serverliste',
	'Address' => 'Adresse',
	'Port' => 'Port',
	'SuperAdmin level' => 'SuperAdmin level',
	'User level' => 'User level',
	'Manage' => 'Administrere',
	'None' => 'Ingen',
	'Local network' => 'Lokalt nettverk',
	'All' => 'Alle',
	'Removed' => 'Fjernet',
	'Missing' => 'Mangler',
	'No server' => 'Ingen server',
	'servers' => 'Servere',
	'server' => 'Server',
	'Duplicate' => 'Duplisere',
	'Modify' => 'Endre',
	'The "!serverName" server has been deleted.' => 'Serveren "!serverName" har blitt slettet.',
	'This server has been modified.' => 'Denne serveren har blitt endret.',
	'Unable to modify the server.' => 'Kan ikke endre serveren.',
	'This server has been added.' => 'Denne serveren har blitt lagt til.',
	'Unable to add the server.' => 'Kan ikke legge til serveren.',
	'Add server' => 'Legg til server',
	'Edit server' => 'Rediger server',
	'Back' => 'Tilbake',
	'Connection information' => 'Tilkoblings informasjon',
	'Server name without color' => 'Server navn uten farger',
	'IP address or domain name' => 'IP adresse eller domene navn',
	'XMLRPC port' => 'XMLRPC Port',
	'Port for remote control' => 'Port for fjernstyring',
	'Optionnal information' => 'Valgfri informasjon',
	'Server MatchSettings' => 'Server MatchSettings',
	'Current server MatchSettings name' => 'Gjeldende server MatchSettings navn',
	'Possible values for the admin level:' => 'Mulige verdier for admin nivå:',
	'all => all access' => 'alle => alle rettigheter',
	'local => local network access' => 'lokale => lokale nettverks rettigheter',
	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => Tilgang til en eller flere IP adresser',
	'none => removed from the access list' => 'ingen => fjernet fra rettighets listen',
	'No server available' => 'Ingen server tilgjengelig',
	'No game mode available' => 'Ingen spillmodus tilgjengelig',
	'Map end time' => 'Bane slutt tid',
	'Round/lap end time' => 'Round/Bane slutt tid',
	'Respawn' => 'Respawn',
	'Default' => 'Standard',
	'Auto (based on map)' => 'Auto (Basert på banen)',
	'Choose time' => 'Velg tid',
	'Return to the default value' => 'Returner til standardverdien',
	'All WarmUp duration' => 'Varighet på oppvarmingstid',
	'Enable' => 'Aktiver',
	'Disable' => 'Deaktiver',
	'Force show of all opponents' => 'Tving visning av alle motstandere',
	'Let player choose' => 'La spillere velge',
	'All opponents' => 'Alle motstandere',
	'minimal opponents' => 'minimalt med motstandere',
	'Choose opponents number' => 'Velg motstander nummer',
	'Script name' => 'Skript navn',
	'Use new rules' => 'Bruk nye regler',
	'Points limit' => 'Poeng grense',
	'Custom points limit' => 'Egendefinert poeng grense',
	'Force laps' => 'Tving runder',
	'Start synchronization period' => 'Starte synkronisering periode',
	'Maximal points' => 'Maksimalt med poeng',
	'Number of laps' => 'Antall runder',
	'Rounds per map' => 'Runder per bane',
	'Number of winners' => 'Antall vinnere',
	'No player available' => 'Ingen spillere tilgjengelig',
	'New' => 'Ny',
	'Parent folder' => 'Forrige mappe',
	'Folder options' => 'Mappe innstillinger',
	'Do you really want to remove this folder !currentDir?' => 'Vil du virkelig slette mappen !currentDir?',
	'Rename folder' => 'Endre mappe navn',
	'Move folder' => 'Flytt mappe',
	'Move folder <b>!currentDir</b> in:' => 'Flytt mappen <b>!currentDir</b> til:',
	'The server is not accessible.' => 'Denne server er ikke tilgjengelig.',
	'You are not allowed at this admin level' => 'Du er ikke tillatt på dette admin nivå.',
	'The password doesn\'t match to the server.' => 'Feil passord, vennligst skriv inn rett passord.',
	'Client not initialized' => 'Klienten er ikke initialisert',
	'Unknown command' => 'Ugyldig kommando',
	'$99FThis round is a draw.' => '$99FDenne runder ble uavgjort.',
	'$99FThe $<$00FBlue team$> wins this round.' => '$00Fblått lag vant denne runden.',
	'$99FThe $<$F00Red team$> wins this round.' => '$F00rødt lag vant denne runden.',
	'maps' => 'Baner',
	'map' => 'Bane',
	'No map' => 'Ingen bane',
	'matchsettings' => 'Matchsettings',
	'matchsetting' => 'Matchsetting',
	'No matchsetting' => 'Ingen Matchsetting',
	'text->XML conversion error' => 'text->XML konverterings feil',
	'Saving XML file error' => 'XML lagringsfeil',
	'The folder "logs" is not writable.' => 'Mappen "logs" er ikke skrivbar.',
	'The folder "logs" does not exist.' => 'Mappen "logs" eksisterer ikke.',
	'Unable to create log file:' => 'Kan ikke opprette log fil:',
	'Unable to add log in file:' => 'Kan ikke legge til log fil:',
	'This server does not exist' => 'Denne serveren eksisterer ikke',
	'Change password' => 'Endre passord',
	'Current' => 'Gjeldende',
	'The current password doesn\'t match.' => 'Gjeldende passord samvarer ikke.',
	'The password has been changed.' => 'Passordet har blitt endret.',
	'Not rated' => 'Ikke vurdert',
	'Unable to delete server.' => 'Kan ikke slette server',
	'Guest-Ban' => 'Gjeste banning',
	'Access as player' => 'Koble til som spiller',
	'Access as spectator' => 'Koble til som tilskuer',
	'Disable horns' => 'Deaktiver horn',
	'Current vote' => 'Gjeldende stemme',
	'Cancel vote' => 'Kanseller stemme',
	'Change order' => 'Endre rekkefølge',
	'Servers order' => 'Server rekkefølge',
	'This path was not required rights:' => 'Denne banen var ikke påkrevd rettigheter:',
	'needs' => 'behov',
	'Plugin error: script.php or view.php file is missing.' => 'Feil med programtillegg: script.php eller view.php mangler.',
	'No server admin levels configured.' => 'Ingen admin nivå konfigurert.',
	'Gold time' => 'Gold tid',
	'Cost' => 'Kost',
	'Team infos' => 'Lag informasjon',
	'Script settings' => 'Skript innstillinger',
	'Script settings updated.' => 'Skript innstillinger oppdatert.',
	'Change authentication password' => 'Endre autentiserings passord',
	'You changed the password "!authLevel", remember it at the next connection!' => 'Du endre passord "!authLevel", husk dette neste gang til kobler til!',
	'Automatic' => 'Automatisk',
	'Choose number' => 'Velg nummer',
	'Client inputs max latency' => 'Maks ventetid klient innganger',
	'Script info' => 'Skript info',
	'Compatible map types' => 'Kompatible banetyper',
	'Script parameters' => 'Skript parametre',
	'Value' => 'Verdi',
	'The server already exist! Change the name.' => 'Serveren eksisterer allerede! Skift navn.',
);
?>
<?php
/**
* Polish translation
*
* @author   Djhubertus 
* @version  1.0
*/
$translate = array(
	'Access server' => 'Dostęp do serwera',
	'Access relay' => 'Dostęp do transmisji',
	'Disconnect' => 'Rozłącz',
	'Servers' => 'Serwery',
	'Server' => 'Serwer',
	'Password' => 'Hasło',
	'Admin level' => 'Poziom zarządzania',
	'Connection' => 'Połączenie',
	'Please put a password.' => 'Proszę wpisać hasło.',
	'Connection error' => 'Błąd połączenia',
	'Connection error: invalid session.' => 'Błąd połączenia: nieprawidłowa sesja',
	'Servers configuration' => 'Konfiguracja serwera',
	'Online configuration' => 'Konfiguracja Online',
	'It\'s your first connection and no server configured. Choose a password to configure your servers.' => 'To twoje pierwsze połączenie i nie posiadasz żadnych skonfigurowanych serwerów. Wpisz hasło którym zabezpieczysz dostęp do konfiguracji AdminServ',
	'Unable to save password.' => 'Problem z zapisem hasła, spróbuj ponownie.',
	'The online configuration is disabled. Use "./config/servers.cfg.php" file.' => 'Konfiguracja Online jest zablokowana. Użyj pliku ".config/servers.cfg.php"',
	'Offline server.' => 'Serwer niedostępny.',
	'Authentication error.' => 'Błąd uwierzytelnienia.',
	'Add to favourite' => 'Dodaj do ulubionych',
	'Current map' => 'Aktualna mapa na serwerze',
	'Name' => 'Nazwa',
	'Author' => 'Autor',
	'Environment' => 'Środowisko',
	'Map UId' => 'UId mapy',
	'Game mode' => 'Tryb gry',
	'No thumbnail' => 'Brak miniatury',
	'Server name' => 'Nazwa serwera',
	'Status' => 'Status',
	'Server login' => 'Login serwera',
	'Connected on' => 'Połączony na',
	'Dedicated version' => 'Wersja serwera',
	'Statistics' => 'Statystyki',
	'Uptime' => 'Załadowanie',
	'Number of connections' => 'Liczba połączeń',
	'Average connection time' => 'Średni czas graczy',
	'Average number of players' => 'Średnia liczba graczy',
	'Recv net rate' => 'Tempo otrzymanych pakietów danych',
	'Send net rate' => 'Tempo wysłanych pakietów danych',
	'Total receiving size' => 'Wielkość otrzymanych',
	'Total sending size' => 'Wielkość wysłanych',
	'Players' => 'Graczy',
	'Detailed mode' => 'Tryb szczegółowy',
	'Simple mode' => 'Tryb prosty',
	'Nickname' => 'Nick',
	'Login' => 'Login',
	'For the selection' => 'Z zaznaczonych',
	'Ban' => 'Ban',
	'Kick' => 'Kick',
	'Spectator' => 'Widz',
	'Player' => 'Gracz',
	'Team' => 'Zespół',
	'Guest' => 'Gość',
	'Ignore' => 'Ignoruj',
	'Red team' => 'Czerwoni',
	'Blue team' => 'Niebiescy',
	'The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed' => 'Wyniki uległy zmianie: $00fNiebiescy $fff!scoreTeamBlue - !scoreTeamRed $f00Czerwoni',
	'Server options' => 'Opcje serwera',
	'General' => 'Główne',
	'Comment' => 'Komentarz',
	'Player password' => 'Hasło do gry',
	'Spectator password' => 'Hasło dla widzów',
	'Nb max of players' => 'Max. liczba graczy',
	'Next value' => 'Nowa wartość',
	'Nb max of spectators' => 'Max. liczba widzów',
	'Advanced' => 'Zaawansowane',
	'P2P Upload' => 'P2P - Wysyłanie',
	'P2P Download' => 'P2P - Pobieranie',
	'Ladder mode' => 'Tryb rankingowy',
	'Vehicles quality' => 'Jakość pojazdów',
	'Vote expiration' => 'Długość głosowań',
	'sec' => 'sek', // Second
	'Vote ratio' => 'Współczynnik udanego głosowania',
	'Hidden server' => 'Serwer prywatny',
	'Map download' => 'Pobieranie map',
	'Replays auto save' => 'Auto zapis powtórek',
	'Buddy notification' => 'Powiadomienia o znajomych',
	'Save' => 'Zapisz',
	'Inactive' => 'Nieaktywny',
	'Forced' => 'Wymuszony',
	'Fast' => 'Szybko',
	'High' => 'Ładny',
	'Game infos' => 'Info o grze',
	'Game information' => 'Informacje o grze',
	'Color' => 'Kolor',
	'Black' => 'Czarny',
	'Red' => 'Czerwony',
	'Green' => 'Zielony',
	'Blue' => 'Niebieski',
	'Orange' => 'Pomarańczowy',
	'Pink' => 'Różowy',
	'Purple' => 'Fioletowy',
	'Grey' => 'Szary',
	'White' => 'Biały',
	'Message destination' => 'Przeznaczenie wiadomości',
	'Chat' => 'Chat',
	'Show server lines' => 'Pokaż wiadomości serwera',
	'Hide server lines' => 'Ukryj wiadomości serwera',
	'Default color: yellow' => 'Domyślny kolor: żółty',
	'Message' => 'Wiadomość',
	'Destination' => 'Przeznaczenie',
	'Send' => 'Wyślij',
	'Unable to create the folder' => 'Niemożliwe stworzenie folderu',
	'Unable to rename the folder' => 'Niemożliwa zmiana nazwy folderu',
	'Unable to move the folder' => 'Niemożliwe przeniesienie folderu',
	'Unable to delete the folder' => 'Niemożliwe usunięcie folderu',
	'List' => 'Lista',
	'Go to the current map' => 'Idź do aktualnej mapy',
	'Map' => 'Mapa',
	'Delete' => 'Usuń',
	'Move after the current map' => 'Umieść pod aktualną mapą',
	'Unable to rename the map' => 'Niemożliwe zmiana nazwy mapy',
	'Unable to move the map' => 'Niemożliwe przeniesienie mapy',
	'Unable to delete the map' => 'Niemożliwe usunięcie mapy',
	'Local' => 'Lokalnie',
	'Do you really want to remove this selection?' => 'Jesteś pewny że chcesz usunąć zaznaczenie ?',
	'Move' => 'Przesuń',
	'Rename' => 'Zmień nazwę',
	'Download' => 'Pobierz',
	'Insert' => 'Włóż',
	'Add' => 'Dodaj',
	'Cancel' => 'Anuluj',
	'Replace the special characters' => 'Zamień znaki specjalne',
	'in the folder:' => 'w folderze:',
	'Root' => 'Root',
	'The map,is currently used by the server.' => 'Mapa jest aktualnie używana przez serwer.',
	'MatchSettings' => 'Ustawienia skryptu',
	'Contains' => 'Zawiera',
	'Modified' => 'Modyfikowana',
	'Edit' => 'Edytuj',
	'Load' => 'Wczytaj',
	'Save ' => 'Zapisz',
	'Create' => 'Stwórz',
	'Unable to save the MatchSettings' => 'Niemożliwy zapis ustawień skryptu',
	'The MatchSettings "!matchSettingName" was successfully created in the folder' => 'Ustawienia "!matchSettingName" zostały pomyślnie stworzone w folderze',
	'a MatchSettings' => 'Ustawienia skryptu',
	'Create a MatchSettings' => 'Stwórz plik z ustawieniami skryptu',
	'MatchSettings name' => 'Nazwa',
	'Maps' => 'Mapy',
	'Make selection' => 'Zrób zaznaczenie',
	'Import all folder' => 'Importuj wszystkie foldery',
	'Select' => 'Wybierz',
	'MatchSettings selected maps:' => 'Wybrane mapy:',
	'View the MatchSettings selection' => 'Zobacz zaznaczenie',
	'MatchSettings selection' => 'Zaznaczenie',
	'Remove map from the selection' => 'Wyrzuć mapę z zaznaczenia',
	'Close' => 'Zamknij',
	'HotSeat' => 'Gorące krzesło',
	'Time limit' => 'Limit Czasowy',
	'Rounds count' => 'Liczba rund',
	'Filter' => 'Filtr',
	'Lan' => 'Lokalna',
	'Internet' => 'Sieciowa',
	'Solo' => 'Solo',
	'Sort index' => 'Index sortowania',
	'Random map order' => 'Losowa kolejność map',
	'Default game mode' => 'Domyślny tryb gry',
	'No map selected for the MatchSettings.' => 'Brak wybranych map dla skryptu.',
	'The MatchSettings name already exists! It will be overwritten.' => 'Taka nazwa jest już używana! Zostanie ona nadpisana.',
	'Order' => 'Kolejność',
	'Automatic sort' => 'Automatyczne sortowanie',
	'Random' => 'Losowo',
	'Manual sort' => 'Ręczne sortowanie',
	'Save the current MatchSettings' => 'Zapisz aktualne ustawienia skryptu',
	'Reset' => 'Reset',
	'Transfer mode' => 'Tryb Transferu',
	'at the end of list' => 'Na końcu listy',
	'after current map' => 'Po aktualnej mapie',
	'only in the folder' => 'Tylko w folderze',
	'Options' => 'Opcje',
	'Go to the maps list when upload is complete' => 'Idź do listy map kiedy wysyłanie dobiegnie końca',
	'Upload' => 'Wysyłanie',
	'Failed' => 'Niepowodzenie',
	'Upload a file' => 'Wyślij plik',
	'Drop files here to upload' => 'Umieść pliki tutaj by wysłać',
	'Upload not finished' => 'Wysyłanie nie dobiegło końca',
	'from' => 'z',
	'Kb' => 'Kb',
	'Mb' => 'Mb',
	'{file} has invalid extension. Only {extensions} are allowed.' => '{file} ma nieznane rozszerzenie. Tylko {extensions} są dopuszczalne',
	'{file} is too large, maximum file size is {sizeLimit}.' => '{file} jest zbyt duży. Max. rozmiar to {sizeLimit}',
	'{file} is too small, minimum file size is {minSizeLimit}.' => '{file} jest zbyt mały. Min. rozmiar to {minSizeLimit}.',
	'{file} is empty, please select files again without it.' => '{file} jest pusty. Wybierz pliki pomijając ten.',
	'The files are being uploaded, if you leave now the upload will be cancelled.' => 'Pliki są wysyłane. jeżeli opuścisz stronę, wysyłanie zostanie anulowane.',
	'No file was uploaded' => 'Żaden plik nie jest wysyłany',
	'The file is empty.' => 'Plik jest pusty.',
	'The file size is too large.' => 'Wielkość piku jest zbyt duża.',
	'The file has invalid extension (allowed extensions:' => 'Plik ma nieznane rozszerzenie (Dozwolone:',
	'The file was not uploaded. Upload has been cancelled or a server error occurred.' => 'Plik nie został wysłany. Wysyłanie zostało anulowane lub wystąpił błąd',
	'Server error. The upload destination folder isn\'t writable.' => 'Błąd serwera. Przeznaczenie wysyłanego pliku jest nienadpisywalne, sprawdź CHMOD\'y ',
	'Plugins' => 'Pluginy',
	'plugin installed' => 'Zainstalowany',
	'plugins installed' => 'Zainstalowane',
	'Cannot include another plugins config file.' => 'Nie można dołączyć plików konfiguracyjnych innych pluginów.',
	'Variable "$PLUGINS" not found.' => 'Zmienna "$PLUGINS" nie znaleziona.',
	'Plugins are extensions to add features to Adminserv.' => 'Pluginy to rozszerzenie umożliwiające zwiększenie zawartości AdminServ.',
	'Install a plugin' => 'Zainstaluj plugin',
	'See all plugins:' => 'Zobacz wszystkie pluginy:',
	'Click here' => 'Kliknij tutaj',
	'Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.' => 'Rozpakuj plugin i umieść jego zawartość w folderze &laquo; plugins &raquo; AdminServ\'a.',
	'In the Configuration Extension, add the name of the plugin folder previously added.' => 'W pliku extension.cfg.php dodaj nazwę folderu pluginu dodanego wcześniej.',
	'Create a new plugin' => 'Stwórz nowy plugin',
	'<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>' => '<p>By stworzyć plugin, idź do folderu plugins i zduplikuj plik _newplugin. Podmień wartości w config.ini i nazwę folderu.<br />Potem sprawdź 2 pliki PHP:</p><ul><li>script.php : Ten plik jest używany przed headerem strony. To miejsce gdzie wszystkie pluginy są umieszczane.</li><li>view.php : Ten plik jest wywoływane po headerze. To miejsce gdzie umieszczany jest kod HTML.</li></ul><p>Potrzebujesz stworzyć zawartość (klasy, js, css), potem załącz te pliki.</p>',
	'Unable to delete the playlist' => 'Niemożliwe by usunąć playlistę',
	'Player login' => 'Login gracza',
	'Clean the list' => 'Wyczyść listę',
	'The list is already empty.' => 'Lista jest pusta.',
	'No player' => 'Brak graczy',
	'IP address' => 'Adres IP',
	'Client' => 'Klient',
	'Blacklist' => 'Czarna lista',
	'Remove from the list' => 'Usuń z listy',
	'Select a player' => 'Wybierz gracza',
	'Enter another login' => 'Wpisz inny login',
	'Add in the' => 'Dodaj do',
	'Playlists' => 'Playlisty',
	'Playlist' => 'Playlista',
	'Type' => 'Rodzaj',
	'Playlist name' => 'Nazwa playlisty',
	'New playlist' => 'Nowa playlista',
	'players' => 'graczy',
	'player' => 'gracz',
	'No playlist' => 'Brak playlisty',
	'You are not allowed to configure the servers' => 'Nie jesteś upoważniony do konfiguracji serwerów.',
	'No server available. To add one, configure "config/servers.cfg.php" file.' => 'Brak dostępnych serwerów. By dodać, skonfiguruj plik "config/servers.cfg.php"',
	'The servers configuration file isn\'t recognized by AdminServ.' => 'Konfiguracja serwerów nie jest rozpoznawalna przez AdminServ.',
	'This server has been duplicated.' => 'Ten serwer jest zduplikowany.',
	'Unable to duplicate server.' => 'Niemożliwa duplikacja serwera.',
	'copy' => 'kopiuj',
	'Servers list' => 'Lista serwerów',
	'Address' => 'Adres',
	'Port' => 'Port',
	'SuperAdmin level' => 'Poziom SuperAdmina',
	'User level' => 'Poziom Gracza',
	'Manage' => 'Zarządzaj',
	'None' => 'Żaden',
	'Local network' => 'Sieć lokalna',
	'All' => 'Wszystkie',
	'Removed' => 'Usunięty',
	'Missing' => 'Pominięty',
	'No server' => 'Brak serwera',
	'servers' => 'serwery',
	'server' => 'serwer',
	'Duplicate' => 'Duplikuj',
	'Modify' => 'Modyfikuj',
	'The "!serverName" server has been deleted.' => 'Serwer "!serverName" został usunięty.',
	'This server has been modified.' => 'Serwer został zmodyfikowany.',
	'Unable to modify the server.' => 'Niemożliwa modyfikacja serwera.',
	'This server has been added.' => 'Serwer został dodany.',
	'Unable to add the server.' => 'Niemożliwe dodanie serwera.',
	'Add server' => 'Dodaj serwer',
	'Edit server' => 'Edytuj serwer',
	'Back' => 'Wróć',
	'Connection information' => 'Informacje o połączeniu',
	'Server name without color' => 'Nazwa serwera bez formatowania',
	'IP address or domain name' => 'Adres IP lub domena',
	'XMLRPC port' => 'Port XMLRPC',
	'Port for remote control' => 'Port dostępu',
	'Optionnal information' => 'Informacje opcjonalne',
	'Server MatchSettings' => 'Ustawienia skryptu',
	'Current server MatchSettings name' => 'Aktualna nazwa ustawień skryptu',
	'Possible values for the admin level:' => 'Możliwe wartości dla poziomu Admina :',
	'all => all access' => 'all => Dostęp dla wszystkich',
	'local => local network access' => 'local => Dostęp tylko przez sieć lokalną',
	'192.168.0.1, 192.168.0.2 => access to one or more IP address' => '192.168.0.1, 192.168.0.2 => Dostęp tylko przez adres IP',
	'none => removed from the access list' => 'none => Usunięty z listy dostępu',
	'No server available' => 'Brak dostępnych serwerów',
	'No game mode available' => 'Brak dostępnych trybów gry',
	'Map end time' => 'Czas po końcu trasy (tylko TM)',
	'Round/lap end time' => 'Czas na zakończenie Rundy/Okrążenia',
	'Respawn' => 'Respawn',
	'Default' => 'Domyślny',
	'Auto (based on map)' => 'Auto (Bazując na mapie)',
	'Choose time' => 'Wybierz czas',
	'Return to the default value' => 'Wróć do domyślnej wartości',
	'All WarmUp duration' => 'Długość rozgrzewki (tylko TM)',
	'Enable' => 'Włączone',
	'Disable' => 'Wyłączone',
	'Force show of all opponents' => 'Wymuś oglądanie wszystkich przeciwników',
	'Let player choose' => 'Daj wybrać graczowi',
	'All opponents' => 'Wszyscy przeciwnicy',
	'minimal opponents' => 'minimum przeciwników',
	'Choose opponents number' => 'Wybierz liczbę przeciwników',
	'Script name' => 'Nazwa skryptu',
	'Use new rules' => 'Użyj nowych reguł',
	'Points limit' => 'Limit punktów',
	'Custom points limit' => 'Własny limit punktów',
	'Force laps' => 'Wymuś okrążenia',
	'Start synchronization period' => 'Uruchom okres synchronizacji',
	'Maximal points' => 'Max. punktów',
	'Number of laps' => 'Liczba okrążeń',
	'Rounds per map' => 'Liczba rund na mapę',
	'Number of winners' => 'Liczba zwycięzców',
	'No player available' => 'Brak dostępnych graczy',
	'New' => 'Nowy',
	'Parent folder' => 'Folder nadrzędny',
	'Folder options' => 'Opcje folderu',
	'Do you really want to remove this folder !currentDir?' => 'Jesteś pewny że chcesz usunąć !currentDir ?',
	'Rename folder' => 'Zmień nazwę folderu',
	'Move folder' => 'Przesuń folder',
	'Move folder <b>!currentDir</b> in:' => 'Przesuń <b>!currentDir</b> w:',
	'The server is not accessible.' => 'Serwer zabronił dostępu.',
	'You are not allowed at this admin level' => 'Nie masz dostępu do poziomu Admina.',
	'The password doesn\'t match to the server.' => 'Nieprawidłowe hasło.',
	'Client not initialized' => 'Klient nie zainicjowany',
	'Unknown command' => 'Nieznana komenda',
	'$99FThis round is a draw.' => '$99FTa runda to remis.',
	'$99FThe $<$00FBlue team$> wins this round.' => '$00FNiebiescy $99fwygrali rundę.',
	'$99FThe $<$F00Red team$> wins this round.' => '$F00Czerwoni $99fwygrali rundę.',
	'maps' => 'mapy',
	'map' => 'mapa',
	'No map' => 'brak mapy',
	'matchsettings' => 'Ustawienia skryptu',
	'matchsetting' => 'Ustawienia skryptu',
	'No matchsetting' => 'Brak ustawień skryptu',
	'text->XML conversion error' => 'Błąd przy konwersji text->XML',
	'Saving XML file error' => 'Błąd w zapisie pliku XML',
	'The folder "logs" is not writable.' => 'Folder "logs" jest nie zapisywalny, sprawdź CHMOD\'y.',
	'The folder "logs" does not exist.' => 'Folder "logs" nie istnieje.',
	'Unable to create log file:' => 'Niemożliwe stworzenie logu:',
	'Unable to add log in file:' => 'Niemożliwe dodanie logu do pliku:',
	'This server does not exist' => 'Serwer nie istnieje',
	'Change password' => 'Zmień hasło',
	'Current' => 'Aktualne',
	'The current password doesn\'t match.' => 'Aktualne hasło nie pasuje.',
	'The password has been changed.' => 'Hasło zostało zmienione.',
	'Not rated' => 'Nie oceniane',
	'Unable to delete server.' => 'Niemożliwe usunięcie serwera',
	'Guest-Ban' => 'Ban dla gości',
	'Access as player' => 'Wejdź jako gracz',
	'Access as spectator' => 'Wejdź jako widz',
	'Disable horns' => 'Zablokuj klaksony',
	'Current vote' => 'Aktualne głosowanie',
	'Cancel vote' => 'Anuluj głosowanie',
	'Change order' => 'Zmień kolejność',
	'Servers order' => 'Kolejność serwerów',
	'This path was not required rights:' => 'Ta ścieżka nie zyskała wymaganych praw:',
	'needs' => 'potrzebuje',
	'Plugin error: script.php or view.php file is missing.' => 'Błąd pluginu: script.php lub view.php jest nieprawidłowy.',
	'No server admin levels configured.' => 'Brak skonfigurowanych poziomów Admina.',
	'Gold time' => 'Złoty czas',
	'Cost' => 'Koszt',
	'Team infos' => 'Informacje o drużynach',
	'Script settings' => 'Ustawienia skryptu',
	'Script settings updated.' => 'Ustawienia skryptu zaktualizowane.',
	'Change authentication password' => 'Zmień hasło uwierzytelniające',
	'You changed the password "!authLevel", remember it at the next connection!' => 'Zmieniłeś hasło na "!authLevel", zapamiętaj je!',
	'Automatic' => 'Automatycznie',
	'Choose number' => 'Wybierz liczbę',
	'Client inputs max latency' => 'Max. opóźnienie klienta',
	'Script info' => 'Informacje',
	'Compatible map types' => 'Rodzaj map',
	'Script parameters' => 'Parametry skryptu',
	'Value' => 'Wartość',
	'The server already exist! Change the name.' => 'Taki serwer już jest ! Zmień nazwę.',
);
?>
<?php
	// LECTURE
	$data['serverLines'] = AdminServ::getChatServerLines();
	
	$lastNicknameUsed = Utils::readCookieData('adminserv_user', 2);
	$data['nickname'] = ($lastNicknameUsed != null) ? $lastNicknameUsed : Utils::t('Nickname');
	
	$colorList = array(
		'$ff0' => Utils::t('Color'),
		'$000' => Utils::t('Black'),
		'$f00' => Utils::t('Red'),
		'$0f0' => Utils::t('Green'),
		'$00f' => Utils::t('Blue'),
		'$f80' => Utils::t('Orange'),
		'$f0f' => Utils::t('Pink'),
		'$888' => Utils::t('Grey'),
		'$fff' => Utils::t('White')
	);
	$data['colorOptions'] = null;
	$lastColorUsed = Utils::readCookieData('adminserv_user', 3);
	foreach($colorList as $colorCode => $colorName){
		$selected = ($colorCode == $lastColorUsed) ? ' selected="selected"' : null;
		$data['colorOptions'] .= '<option value="'.$colorCode.'"'.$selected.'>'.$colorName.'</option>';
	}
	
	$lastDestination = null;
	$lastDestinationTitle = Utils::t('server');
	if( isset($_SESSION['adminserv']['chat_dst']) ){
		$lastDestination = $lastDestinationTitle = $_SESSION['adminserv']['chat_dst'];
	}
	$data['destination']['list'] = AdminServUI::getPlayerList($lastDestination);
	$data['destination']['title'] = Utils::t('Message destination').' : '.$lastDestinationTitle;
?>
<?php
	// ENREGISTREMENT
	if (isset($_POST['savelevel'])) {
		// Variables
		$levelName = Str::replaceSpecialChars( htmlspecialchars(addslashes($_POST['addLevelName'])), false);
		$levelType = $_POST['addLevelType'];
		$levelAccess = array();
		if ($_POST['selectedAccessSortList']) {
			$levelAccess = explode(',', $_POST['selectedAccessSortList']);
		}
		$levelPermission = array();
		if ($_POST['selectedPermissionSortList']) {
			$levelPermission = explode(',', $_POST['selectedPermissionSortList']);
		}
		$levelData = array(
			'name' => $levelName,
			'adminlevel' => array(
				'type' => $levelType
			),
			'access' => $levelAccess,
			'permission' => $levelPermission,
		);
		
		// Édition
		if($args['id'] !== -1){
			if( ($result = AdminServAdminLevel::saveConfig($levelData, $args['id'])) !== true ){
				AdminServ::error( Utils::t('Unable to modify the admin level.').' ('.$result.')');
			}
			else{
				$action = Utils::t('This admin level has been modified.');
				AdminServ::info($action);
				AdminServLogs::add('action', $action);
				Utils::redirection(false, '?p=config-adminlevel');
			}
		}
		// Ajout
		else{
			if( ($result = AdminServAdminLevel::saveConfig($levelData)) !== true ){
				AdminServ::error( Utils::t('Unable to add the admin level.').' ('.$result.')');
			}
			else{
				$action = Utils::t('This admin level has been added.');
				AdminServ::info($action);
				AdminServLogs::add('action', $action);
				Utils::redirection(false, '?p='.USER_PAGE);
			}
		}
	}
	
	
	// LECTURE
	$defaultAccess = AdminServAdminLevel::getDefaultAccess();
	$defaultPermission = AdminServAdminLevel::getDefaultPermission();
	$data = array(
		'name' => null,
		'types' => AdminServAdminLevel::getDefaultType(),
		'adminlevel' => array(
			'type' => null,
		),
		'access' => array(
			'default' => array(),
			'selected' => $defaultAccess,
		),
		'permission' => array(
			'default' => array(),
			'selected' => $defaultPermission,
		)
	);
	if($args['id'] !== -1){
		define('IS_LEVEL_EDITION', true);
		$data['name'] = AdminServAdminLevel::getName($args['id']);
		if($data['name']){
			$levelData = AdminServAdminLevel::getData($data['name']);
			
			$data['adminlevel'] = array(
				'type' => $levelData['adminlevel']['type'],
			);
			$data['access'] = array(
				'default' => array_diff($defaultAccess, $levelData['access']),
				'selected' => $levelData['access'],
			);
			$data['permission'] = array(
				'default' => array_diff($defaultPermission, $levelData['permission']),
				'selected' => $levelData['permission'],
			);
		}
	}
?>
<?php
	// ENREGISTREMENT
	if( isset($_POST['saveserver']) ){
		// Variables
        $displayServPassword = trim($_POST['addDisplayServPassword']);
		$serverName = Str::replaceSpecialChars( htmlspecialchars(addslashes($_POST['addServerName'])), false);
		$serverAddress = trim($_POST['addServerAddress']);
		$serverPort = intval($_POST['addServerPort']);
		$serverMapsBasePath = trim($_POST['addServerMapsBasePath']);
		$serverMatchSet = trim($_POST['addServerMatchSet']);
		$serverAdmLvl = array(
			'SuperAdmin' => $_POST['addServerAdmLvlSA'],
			'Admin' => $_POST['addServerAdmLvlADM'],
			'User' => $_POST['addServerAdmLvlUSR']
		);
		$isNotAnArray = array('all', 'local', 'none');
		foreach($serverAdmLvl as $admLvlId => $admLvlValue){
			if( !in_array($admLvlValue, $isNotAnArray) ){
				$serverAdmLvl[$admLvlId] = explode(',', $admLvlValue);
			}
			else{
				$serverAdmLvl[$admLvlId] = trim($admLvlValue);
			}
		}
		$serverData = array(
			'name' => $serverName,
			'address' => $serverAddress,
			'port' => $serverPort,
			'mapsbasepath' => $serverMapsBasePath,
			'matchsettings' => $serverMatchSet,
			'adminlevel' => array(),
            'ds_pw' => $displayServPassword
		);
		foreach($serverAdmLvl as $admLvlId => $admLvlValue){
			$serverData['adminlevel'][$admLvlId] = $admLvlValue;
		}
		
		// Édition
		if($args['id'] !== -1){
			if( ($result = AdminServServerConfig::saveServerConfig($serverData, $args['id'])) !== true ){
				AdminServ::error( Utils::t('Unable to modify the server.').' ('.$result.')');
			}
			else{
				$action = Utils::t('This server has been modified.');
				AdminServ::info($action);
				AdminServLogs::add('action', $action);
				Utils::redirection(false, '?p=config-servers');
			}
		}
		// Ajout
		else{
			if( ($result = AdminServServerConfig::saveServerConfig($serverData)) !== true ){
				AdminServ::error( Utils::t('Unable to add the server.').' ('.$result.')');
			}
			else{
				$action = Utils::t('This server has been added.');
				AdminServ::info($action);
				AdminServLogs::add('action', $action);
				Utils::redirection(false, '?p='.USER_PAGE);
			}
		}
	}
	
	
	// LECTURE
	$data = array(
		'name' => null,
		'address' => 'localhost',
		'port' => 5000,
		'mapsbasepath' => null,
		'matchsettings' => 'MatchSettings/',
		'adminlevel' => array(
			'SuperAdmin' => 'all',
			'Admin' => 'all',
			'User' => 'all'
		),
        'ds_pw' => 'User'
	);
	if($args['id'] !== -1){
		define('IS_SERVER_EDITION', true);
		$data['name'] = AdminServServerConfig::getServerName($args['id']);
		if($data['name']){
			$serverData = AdminServServerConfig::getServer($data['name']);
			$data['address'] = $serverData['address'];
			$data['port'] = $serverData['port'];
            $data['ds_pw'] = $serverData['ds_pw'];
			$data['mapsbasepath'] = (isset($serverData['mapsbasepath'])) ? $serverData['mapsbasepath'] : '';
			$data['matchsettings'] = $serverData['matchsettings'];
			foreach($serverData['adminlevel'] as $admLvlId => $admLvlValue){
				if( is_array($admLvlValue) ){
					$data['adminlevel'][$admLvlId] = implode(', ', $admLvlValue);
				}
				else{
					$data['adminlevel'][$admLvlId] = $admLvlValue;
				}
			}
		}
	}
?>
<?php
	// EDITION
	if (isset($_POST['editlevel'])) {
		$levelId = AdminServAdminLevel::getId($_POST['level'][0]);
		Utils::redirection(false, '?p=config-addlevel&id='.$levelId);
	}
	
	// DUPLIQUER
	if (isset($_POST['duplicatelevel'])) {
		// GET
		$getLevelData = AdminServAdminLevel::getData($_POST['level'][0]);
		
		// SET
		$setLevelData = array(
			'name' => trim( htmlspecialchars( addslashes($_POST['level'][0] . ' - '.Utils::t('copy') ) ) ),
			'adminlevel' => $getLevelData['adminlevel'],
			'access' => $getLevelData['access'],
			'permission' => $getLevelData['permission'],
		);
		if (AdminServAdminLevel::saveConfig($setLevelData)) {
			$action = Utils::t('This admin level has been duplicated.');
			AdminServ::info($action);
			AdminServLogs::add('action', $action);
			Utils::redirection(false, '?p='.USER_PAGE);
		}
		else {
			AdminServ::error( Utils::t('Unable to duplicate admin level.') );
		}
	}
	
	// SUPPRESSION
	if (isset($_POST['deletelevel'])) {
		$levels = AdminLevelConfig::$ADMINLEVELS;
		unset($levels[$_POST['level'][0]]);
		if (($result = AdminServAdminLevel::saveConfig(array(), -1, $levels)) !== true) {
			AdminServ::error( Utils::t('Unable to delete admin level.').' ('.$result.')');
		}
		else {
			$action = Utils::t('The "!levelName" admin level has been deleted.', array('!levelName' => $_POST['level'][0]));
			AdminServ::info($action);
			AdminServLogs::add('action', $action);
			Utils::redirection(false, '?p='.USER_PAGE);
		}
	}
	
	// LEVELLIST
	$data['levels'] = array();
	if (AdminServAdminLevel::hasLevel()) {
		foreach (AdminLevelConfig::$ADMINLEVELS as $levelName => $levelData) {
			$data['levels'][] = array(
				'name' => $levelName,
				'type' => $levelData['adminlevel']['type'],
				'allowed_access' =>  count($levelData['access']).' '.Utils::t('authorized access'),
				'allowed_permissions' => count($levelData['permission']).' '.Utils::t('authorized permissions'),
			);
		}
	}
	$data['count'] = count($data['levels']);
?>
<?php
	// ACTIONS
	if( isset($_POST['save']) && isset($_POST['list']) && $_POST['list'] != null ){
		$adminLevelList = AdminLevelConfig::$ADMINLEVELS;
		$list = explode(',', $_POST['list']);
		
		$newAdminLevelList = array();
		foreach($list as $listLevelName){
			$newAdminLevelList[$listLevelName] = array(
				'adminlevel' => $adminLevelList[$listLevelName]['adminlevel'],
				'access' => $adminLevelList[$listLevelName]['access'],
				'permission' => $adminLevelList[$listLevelName]['permission'],
			);
		}
		
		AdminServAdminLevel::saveConfig(array(), -1, $newAdminLevelList);
		AdminServLogs::add('action', 'Order admin level list');
		Utils::redirection(false, '?p='.USER_PAGE);
	}
	
	
	// LEVELLIST
	$data['levels'] = array();
	if (AdminServAdminLevel::hasLevel()) {
		$data['levels'] = AdminLevelConfig::$ADMINLEVELS;
	}
?>
<?php
	// ENREGISTREMENT
	if( isset($_POST['savepassword']) ){
		$current = md5($_POST['changePasswordCurrent']);
		$new = md5($_POST['changePasswordNew']);
		if( isset($_SESSION['adminserv']['path']) ){ $adminservPath = $_SESSION['adminserv']['path']; }else{ $adminservPath = null; }
		$pathConfig = $adminservPath.'config/';
		
		if(OnlineConfig::PASSWORD !== $current){
			AdminServ::error( Utils::t('The current password doesn\'t match.') );
		}
		else{
			if( ($result = AdminServServerConfig::savePasswordConfig($pathConfig.'adminserv.cfg.php', $new)) !== true ){
				AdminServ::error( Utils::t('Unable to save password.').' ('.$result.')');
			}
			else{
				$info = Utils::t('The password has been changed.');
				AdminServ::info($info);
				AdminServLogs::add('action', $info);
			}
		}
		
		Utils::redirection(false, '?p='.USER_PAGE);
	}
?>
<?php
	// EDITION
	if( isset($_POST['editserver']) ){
		$serverId = AdminServServerConfig::getServerId($_POST['server'][0]);
		Utils::redirection(false, '?p=config-addserver&id='.$serverId);
	}
	
	// DUPLIQUER
	if( isset($_POST['duplicateserver']) ){
		// GET
		$getServerData = AdminServServerConfig::getServer($_POST['server'][0]);
		
		// SET
		$setServerData = array(
			'name' => trim( htmlspecialchars( addslashes($_POST['server'][0] . ' - '.Utils::t('copy') ) ) ),
			'address' => trim($getServerData['address']),
			'port' => intval($getServerData['port']),
			'matchsettings' => trim($getServerData['matchsettings']),
			'adminlevel' => array(
				'SuperAdmin' => $getServerData['adminlevel']['SuperAdmin'],
				'Admin' => $getServerData['adminlevel']['Admin'],
				'User' => $getServerData['adminlevel']['User'],
			),
			'ds_pw' => trim($getServerData['ds_pw'])
		);
		if( AdminServServerConfig::saveServerConfig($setServerData) ){
			$action = Utils::t('This server has been duplicated.');
			AdminServ::info($action);
			AdminServLogs::add('action', $action);
			Utils::redirection(false, '?p='.USER_PAGE);
		}
		else{
			AdminServ::error( Utils::t('Unable to duplicate server.') );
		}
	}
	
	// SUPPRESSION
	if( isset($_POST['deleteserver']) ){
		$servers = ServerConfig::$SERVERS;
		unset($servers[$_POST['server'][0]]);
		if( ($result = AdminServServerConfig::saveServerConfig(array(), -1, $servers)) !== true ){
			AdminServ::error( Utils::t('Unable to delete server.').' ('.$result.')');
		}
		else{
			$action = Utils::t('The "!serverName" server has been deleted.', array('!serverName' => $_POST['server'][0]));
			AdminServ::info($action);
			AdminServLogs::add('action', $action);
			Utils::redirection(false, '?p='.USER_PAGE);
		}
	}
	
	// SERVERLIST
	$data['servers'] = array();
	if (is_array(ServerConfig::$SERVERS) && !empty(ServerConfig::$SERVERS)) {
		$data['servers'] = ServerConfig::$SERVERS;
	}
	$data['count'] = count($data['servers']);
	$data['adminLevelsType'] = AdminServAdminLevel::getDefaultType();
?>
<?php
	// ACTIONS
	if( isset($_POST['save']) && isset($_POST['list']) && $_POST['list'] != null ){
		$serverList = ServerConfig::$SERVERS;
		$list = explode(',', $_POST['list']);
		
		$newServerList = array();
		foreach($list as $listServerName){
			$newServerList[$listServerName] = array(
				'address' => $serverList[$listServerName]['address'],
				'port' => $serverList[$listServerName]['port'],
				'mapsbasepath' => (isset($serverList[$listServerName]['mapsbasepath'])) ? $serverList[$listServerName]['mapsbasepath'] : '',
				'matchsettings' => $serverList[$listServerName]['matchsettings'],
				'adminlevel' => $serverList[$listServerName]['adminlevel']
			);
		}
		
		AdminServServerConfig::saveServerConfig(array(), -1, $newServerList);
		AdminServLogs::add('action', 'Order server list');
		Utils::redirection(false, '?p='.USER_PAGE);
	}
	
	
	// SERVERLIST
	$data['servers'] = array();
	if (is_array(ServerConfig::$SERVERS) && !empty(ServerConfig::$SERVERS)) {
		$data['servers'] = ServerConfig::$SERVERS;
	}
?>
<?php
	// SESSION
	if( !isset($_SESSION['adminserv']['allow_config_servers']) ){
		AdminServ::error( Utils::t('You are not allowed to configure the servers') );
		Utils::redirection();
	}
	
	// VERIFICATION
	if( class_exists('ServerConfig') ){
		// Si on n'autorise pas la configuration en ligne
		if( OnlineConfig::ACTIVATE !== true ){
			AdminServ::info( Utils::t('No server available. To add one, configure "config/servers.cfg.php" file.') );
			Utils::redirection();
		}
		elseif (USER_PAGE != 'config-addserver') {
			if( OnlineConfig::ADD_ONLY === true ){
				Utils::redirection(false, './?p=addserver');
			}
		}
	}
	else{
		AdminServ::error( Utils::t('The servers configuration file isn\'t recognized by AdminServ.') );
		Utils::redirection();
	}
?>
<?php
	// Si on demande le mot de passe pour la config en ligne
	if( !isset($_SESSION['adminserv']['check_password']) && !isset($_SESSION['adminserv']['get_password']) ){
		// On vérifie qu'une configuration existe, sinon on la créer
		if( class_exists('ServerConfig') ){
			// Si la configuration contient au moins 1 serveur et qu'il n'est pas l'exemple
			if( AdminServServerConfig::hasServer() ){
				// Connexion
				if( isset($_POST['as_server']) && isset($_POST['as_password']) && isset($_POST['as_adminlevel']) ){
					// Récupération des valeurs
					$serverName = $_POST['as_server'];
					$password = addslashes( htmlspecialchars( trim($_POST['as_password']) ) );
					if(AdminServConfig::MD5_PASSWORD){
						$password = md5($password);
					}
					$adminLevel = addslashes( htmlspecialchars($_POST['as_adminlevel']) );
					
					// Vérification des valeurs
					if($password == null){
						AdminServ::error( Utils::t('Please put a password.') );
					}
					else{
						// Sessions & Cookies
						$_SESSION['adminserv']['sid'] = AdminServServerConfig::getServerId($serverName);
						$_SESSION['adminserv']['name'] = $serverName;
						$_SESSION['adminserv']['password'] = $password;
						$_SESSION['adminserv']['adminlevel'] = $adminLevel;
						Utils::addCookieData('adminserv', array($_SESSION['adminserv']['sid'], $adminLevel), AdminServConfig::COOKIE_EXPIRE);
						
						// Redirection
						if($_SESSION['adminserv']['sid'] != -1 && $_SESSION['adminserv']['name'] != null && $_SESSION['adminserv']['password'] != null && $_SESSION['adminserv']['adminlevel'] != null){
							Utils::redirection();
						}
						else{
							AdminServ::error( Utils::t('Connection error: invalid session.') );
						}
					}
				}
			}
			else{
				if(OnlineConfig::ACTIVATE === true){
					Utils::redirection(false, './config/');
				}
				else{
					AdminServ::info( Utils::t('No server available. To add one, configure "config/servers.cfg.php" file.') );
				}
			}
		}
		else{
			if(OnlineConfig::ACTIVATE === true && !isset($_GET['error']) ){
				Utils::redirection(false, './config/');
			}
			else{
				AdminServ::error( Utils::t('The servers configuration file isn\'t recognized by AdminServ.') );
			}
		}
	}
	else if( isset($_SESSION['adminserv']['get_password']) ){
		AdminServ::info( Utils::t('It\'s your first connection and no server configured. Choose a password to configure your servers.') );
	}
	
	// HTML
	if( isset($_GET['error']) ){
		AdminServ::error($_GET['error']);
	}
	else if( isset($_GET['info']) ){
		AdminServ::info($_GET['info']);
	}
?>
<?php
	// ENREGISTREMENT
	if( isset($_POST['savegameinfos']) ){
		// Variables
		$struct = AdminServ::getGameInfosStructFromPOST();
		
		// Requêtes
		if(!$client->query('SetGameInfos', $struct) && $client->getErrorMessage() != 'Script not allowed for this title.'){
			AdminServ::error();
		}
		else{
			// Team info
			if(SERVER_VERSION_NAME == 'ManiaPlanet' && isset($_POST['teamInfo1Name']) ){
				$team1 = array(
					'name' => $_POST['teamInfo1Name'],
					'color' => $_POST['teamInfo1Color'],
					'colorhex' => $_POST['teamInfo1ColorHex'],
					'country' => $_POST['teamInfo1Country']
				);
				$team2 =  array(
					'name' => $_POST['teamInfo2Name'],
					'color' => $_POST['teamInfo2Color'],
					'colorhex' => $_POST['teamInfo2ColorHex'],
					'country' => $_POST['teamInfo2Country']
				);
				
				AdminServ::setTeamInfo($team1, $team2);
			}
			
			// RoundCustomPoints
			if( isset($_POST['NextRoundCustomPoints']) && $_POST['NextRoundCustomPoints'] != null){
				$NextRoundCustomPoints = explode(',', $_POST['NextRoundCustomPoints']);
				$NextRoundCustomPointsArray = array();
				if( count($NextRoundCustomPoints) > 0 ){
					foreach($NextRoundCustomPoints as $point){
						$NextRoundCustomPointsArray[] = intval( trim($point) );
					}
				}
				if( !$client->query('SetRoundCustomPoints', $NextRoundCustomPointsArray) ){
					AdminServ::error();
				}
			}
			
			// MatchSettings
			if(SERVER_MATCHSET){
				$mapsDirectory = AdminServ::getMapsDirectoryPath();
				if( array_key_exists('SaveCurrentMatchSettings', $_POST) ){
					if( !$client->query('SaveMatchSettings', $mapsDirectory . SERVER_MATCHSET) ){
						AdminServ::error();
					}
				}
			}
			
			AdminServLogs::add('action', 'Save game infos');
			Utils::redirection(false, '?p='.USER_PAGE);
		}
	}
	
	
	// LECTURE
	$gameInfos = AdminServ::getGameInfos();
	$data['gameInfos'] = array(
		'curr' => $gameInfos['curr'],
		'next' => $gameInfos['next']
	);
	$data['teamInfo'] = array(
		'team1' => array(
			'name' => Utils::t('Blue'),
			'color' => '0.667',
			'colorhex' => '#0000ff',
			'country' => 'World|France'
		),
		'team2' => array(
			'name' => Utils::t('Red'),
			'color' => '0',
			'colorhex' => '#ff0000',
			'country' => 'World|France'
		)
	);
	if( isset($_SESSION['adminserv']['teaminfo']) && count($_SESSION['adminserv']['teaminfo']) > 0 ){
		$data['teamInfo'] = array(
			'team1' => $_SESSION['adminserv']['teaminfo']['team1'],
			'team2' => $_SESSION['adminserv']['teaminfo']['team2']
		);
	}
	
	unset($gameInfos);
?>
<?php
	// ACTIONS
	if( isset($_GET['stop']) ){
		if( !$client->query('StopServer') ){
			AdminServ::error();
		}
		else{
			$client->Terminate();
			Utils::redirection(false, '?logout');
		}
	}
	else if( isset($_POST['BanLoginList']) && count($_POST['player']) > 0 ){
		foreach($_POST['player'] as $player){
			if( !$client->query('Ban', $player) ){
				AdminServ::error();
				break;
			}
			else{
				AdminServLogs::add('action', 'Ban player: '.$player);
			}
		}
	}
	else if( isset($_POST['KickLoginList']) && count($_POST['player']) > 0 ){
		foreach($_POST['player'] as $player){
			if( !$client->query('Kick', $player) ){
				AdminServ::error();
				break;
			}
			else{
				AdminServLogs::add('action', 'Kick player: '.$player);
			}
		}
	}
	else if( isset($_POST['IgnoreLoginList']) && count($_POST['player']) > 0 ){
		foreach($_POST['player'] as $player){
			if( !$client->query('Ignore', $player) ){
				AdminServ::error();
				break;
			}
			else{
				AdminServLogs::add('action', 'Ignore player: '.$player);
			}
		}
	}
	else if( isset($_POST['GuestLoginList']) && count($_POST['player']) > 0 ){
		foreach($_POST['player'] as $player){
			if( !$client->query('AddGuest', $player) ){
				AdminServ::error();
				break;
			}
			else{
				AdminServLogs::add('action', 'Add Guest player: '.$player);
			}
		}
	}
	else if( isset($_POST['ForcePlayerList']) && count($_POST['player']) > 0 ){
		foreach($_POST['player'] as $player){
			if( !$client->query('ForceSpectator', $player, 2) ){
				AdminServ::error();
				break;
			}
			else{
				if( !$client->query('ForceSpectator', $player, 0) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Force player mode: '.$player);
				}
			}
		}
	}
	else if( isset($_POST['ForceSpectatorList']) && count($_POST['player']) > 0 ){
		foreach($_POST['player'] as $player){
			if( !$client->query('ForceSpectator', $player, 1) ){
				AdminServ::error();
				break;
			}
			else{
				if(!$client->query('ForceSpectator', $player, 0) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Force spectator mode: '.$player);
				}
			}
		}
	}
	else if( (isset($_POST['ForceBlueTeam']) || isset($_POST['ForceRedTeam'])) && count($_POST['player']) > 0 ){
		if( isset($_POST['ForceBlueTeam']) ){
			$teamId = 0;
		}else{
			$teamId = 1;
		}
		
		foreach($_POST['player'] as $player){
			if( !$client->query('ForcePlayerTeam', $player, $teamId) ){
				AdminServ::error();
				break;
			}
			else{
				if($teamId == 0){ $color = 'blue'; }else{ $color = 'red'; }
				AdminServLogs::add('action', 'Force player in '.$color.' team: '.$player);
			}
		}
	}
	else if( isset($_POST['ForceScores']) && isset($_POST['ScoreTeamBlue']) && isset($_POST['ScoreTeamRed']) ){
		$scoreTeamBlue = intval($_POST['ScoreTeamBlue']);
		$scoreTeamRed = intval($_POST['ScoreTeamRed']);
		$scores = array(
			array(
				'PlayerId' => 0,
				'Score' => $scoreTeamBlue
			),
			array(
				'PlayerId' => 1,
				'Score' => $scoreTeamRed
			)
		);
		if( !$client->query('ForceScores', $scores, true) ){
			AdminServ::error();
		}else{
			$action = '[Admin] '.Utils::t('The scores have been modified : $00fblue team $fffhas !scoreTeamBlue and $f00red team $fffhas !scoreTeamRed', array('!scoreTeamBlue' => $scoreTeamBlue, '!scoreTeamRed' => $scoreTeamRed));
			if( !$client->query('ChatSendServerMessage', $action) ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', $action);
			}
		}
	}
	else if( isset($_POST['CancelVote']) ){
		if( !$client->query('CancelVote') ){
			AdminServ::error();
		}
		else{
			Utils::redirection();
		}
	}
	
	
	// Info serveur
	$data['serverInfo'] = AdminServ::getCurrentServerInfo();
	$data['isTeamGameMode'] = AdminServ::checkDisplayTeamMode($data['serverInfo']['srv']['gameModeId'], $data['serverInfo']['srv']['gameModeScriptName']);
	// Si on est en mode équipe, on force l'affichage en mode détail
	if($data['isTeamGameMode']){
		$_SESSION['adminserv']['mode']['general'] = 'detail';
	}
	if( defined('IS_RELAY') && IS_RELAY ){
		// @deprecated $mainServerLogin = AdminServ::getMainServerLoginFromRelay();
		$data['mainServerLogin'] = null;
	}
?>
<?php
	// GAMEDATA
	if( AdminServAdminLevel::isType('Admin') ){
		if( !$client->query('GameDataDirectory') ){
			AdminServ::error();
		}
		else{
			$data['gameDataDirectory'] = $client->getResponse();
			$data['playlistDirectory'] = Folder::read($data['gameDataDirectory'].'Config', array(), array(), intval(AdminServConfig::RECENT_STATUS_PERIOD * 3600) );
		}
	}
	
	// ACTIONS
	// Vider la liste
	if( isset($_GET['clean']) ){
		$clean = strtolower($_GET['clean']);
		if($clean == 'banlist'){
			if( !$client->query('CleanBanList') ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', 'Clean banlist');
			}
		}
		else if($clean == 'ignorelist'){
			if( !$client->query('CleanIgnoreList') ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', 'Clean ignorelist');
			}
		}
		else if($clean == 'guestlist'){
			if( !$client->query('CleanGuestList') ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', 'Clean guestlist');
			}
		}
		else if($clean == 'blacklist'){
			if( !$client->query('CleanBlackList') ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', 'Clean blacklist');
			}
		}
	}
	// Blacklister
	else if( isset($_POST['blackListPlayer']) ){
		// Création du tableau de joueurs à blacklister
		$blackListPlayer = array();
		if( isset($_POST['banlist']) && count($_POST['banlist']) > 0 ){
			$blackListPlayer = array_merge($blackListPlayer, $_POST['banlist']);
		}
		if( isset($_POST['guestlist']) && count($_POST['guestlist']) > 0 ){
			$blackListPlayer = array_merge($blackListPlayer, $_POST['guestlist']);
		}
		if( isset($_POST['ignorelist']) && count($_POST['ignorelist']) > 0 ){
			$blackListPlayer = array_merge($blackListPlayer, $_POST['ignorelist']);
		}
		$blackListPlayer = array_unique($blackListPlayer);
		
		// BlackList de toutes les listes
		if( count($blackListPlayer) > 0 ){
			foreach($blackListPlayer as $player){
				if( !$client->query('BlackList', $player) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Blacklist player: '.$player);
				}
			}
		}
	}
	// Retirer un joueur d'une ou plusieurs listes
	else if( isset($_POST['removeList']) ){
		if( isset($_POST['banlist']) && count($_POST['banlist']) > 0 ){
			foreach($_POST['banlist'] as $player){
				if( !$client->query('UnBan', $player) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Unban player: '.$player);
				}
			}
		}
		else if( isset($_POST['blacklist']) && count($_POST['blacklist']) > 0 ){
			foreach($_POST['blacklist'] as $player){
				if( !$client->query('UnBlackList', $player) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Unblacklist player: '.$player);
				}
			}
		}
		else if( isset($_POST['guestlist']) && count($_POST['guestlist']) > 0 ){
			foreach($_POST['guestlist'] as $player){
				if( !$client->query('RemoveGuest', $player) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Remove guest player: '.$player);
				}
			}
		}
		else if( isset($_POST['ignorelist']) && count($_POST['ignorelist']) > 0 ){
			foreach($_POST['ignorelist'] as $player){
				if( !$client->query('UnIgnore', $player) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Unignore player: '.$player);
				}
			}
		}
	}
	
	
	// AJOUTER
	else if( isset($_POST['addPlayer']) ){
		// Variables
		$addPlayerList = $_POST['addPlayerList'];
		$addPlayerLogin = strtolower( trim($_POST['addPlayerLogin']) );
		$addPlayerTypeList = $_POST['addPlayerTypeList'];
		
		// PlayerLogin
		if($addPlayerList != 'none' && $addPlayerList != 'more'){
			$playerlogin = $addPlayerList;
		}else{
			$playerlogin = $addPlayerLogin;
		}
		
		// Requête
		if($playerlogin != Utils::t('Player login') ){
			// Inviter
			if($addPlayerTypeList == 'guestlist'){
				if( !$client->query('AddGuest', $playerlogin) ){
					AdminServ::error();
				}
				else{
					AdminServLogs::add('action', 'Add guest player: '.$playerlogin);
				}
			}
			// Blacklister
			else if($addPlayerTypeList == 'blacklist'){
				if( !$client->query('BlackList', $playerlogin) ){
					AdminServ::error();
				}
				else{
					AdminServLogs::add('action', 'Add blacklist player: '.$playerlogin);
				}
			}
		}
	}
	
	
	// PLAYLISTS LOCAL
	else if( isset($_POST['savePlaylist']) && isset($_POST['playlist']) && count($_POST['playlist'] > 0) ){
		$i = 0;
		foreach($_POST['playlist'] as $playlist){
			$playlistEx = explode('|', $playlist);
			$type = $playlistEx[0];
			$filename = $playlistEx[1];
			
			// Guestlist
			if($type == 'guestlist'){
				if( !$client->query('SaveGuestList', $filename) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Save guestlist');
				}
			}
			// BlackList
			elseif($type == 'blacklist'){
				if( !$client->query('SaveBlackList', $filename) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Save blacklist');
				}
			}
			$i++;
		}
		
		Utils::redirection(false, '?p='.USER_PAGE);
	}
	else if( isset($_POST['loadPlaylist']) && isset($_POST['playlist']) && count($_POST['playlist'] > 0) ){
		$i = 0;
		foreach($_POST['playlist'] as $playlist){
			$playlistEx = explode('|', $playlist);
			$type = $playlistEx[0];
			$filename = $playlistEx[1];
			
			// Guestlist
			if($type == 'guestlist'){
				if( !$client->query('LoadGuestList', $filename) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Load guestlist');
				}
			}
			// BlackList
			elseif($type == 'blacklist'){
				if( !$client->query('LoadBlackList', $filename) ){
					AdminServ::error();
					break;
				}
				else{
					AdminServLogs::add('action', 'Load blacklist');
				}
			}
			$i++;
		}
		
		Utils::redirection(false, '?p='.USER_PAGE);
	}
	else if( isset($_POST['deletePlaylist']) && isset($_POST['playlist']) && count($_POST['playlist'] > 0) ){
		foreach($_POST['playlist'] as $playlist){
			$playlistEx = explode('|', $playlist);
			$filename = $playlistEx[1];
			
			if( !File::delete($data['gameDataDirectory'].'Config/'.$filename) ){
				AdminServ::error(Utils::t('Unable to delete the playlist').' : '.$filename);
				break;
			}
			else{
				AdminServLogs::add('action', 'Delete playlist: '.$filename);
			}
		}
		
		Utils::redirection(false, '?p='.USER_PAGE);
	}
	else if( isset($_POST['createPlaylistValid']) && isset($_POST['createPlaylistName']) && $_POST['createPlaylistName'] != null ){
		// Fichier
		$filename = Str::replaceChars($_POST['createPlaylistName']);
		
		// Guestlist
		if( $filename != Str::replaceChars(Utils::t('Playlist name')) ){
			if($_POST['createPlaylistType'] == 'guestlist'){
				if( !$client->query('SaveGuestList', $filename) ){
					AdminServ::error();
				}
				else{
					AdminServLogs::add('action', 'Create playlist (guestlist): '.$filename);
				}
			}
			// Blacklist
			elseif($_POST['createPlaylistType'] == 'blacklist'){
				if( !$client->query('SaveBlackList', $filename) ){
					AdminServ::error();
				}
				else{
					AdminServLogs::add('action', 'Create playlist (blacklist): '.$filename);
				}
			}
		}
		
		Utils::redirection(false, '?p='.USER_PAGE);
	}
	
	// LECTURE
	$client->addCall('GetBanList', array(AdminServConfig::LIMIT_PLAYERS_LIST, 0) );
	$client->addCall('GetBlackList', array(AdminServConfig::LIMIT_PLAYERS_LIST, 0) );
	$client->addCall('GetGuestList', array(AdminServConfig::LIMIT_PLAYERS_LIST, 0) );
	$client->addCall('GetIgnoreList', array(AdminServConfig::LIMIT_PLAYERS_LIST, 0) );
	if( !$client->multiquery() ){
		AdminServ::error();
	}
	else{
		$queriesData = $client->getMultiqueryResponse();
		$data['banlist']['list'] = $queriesData['GetBanList'];
		$data['blacklist']['list'] = $queriesData['GetBlackList'];
		$data['guestlist']['list'] = $queriesData['GetGuestList'];
		$data['ignorelist']['list'] = $queriesData['GetIgnoreList'];
		$data['banlist']['count'] = count($data['banlist']['list']);
		$data['blacklist']['count'] = count($data['blacklist']['list']);
		$data['guestlist']['count'] = count($data['guestlist']['list']);
		$data['ignorelist']['count'] = count($data['ignorelist']['list']);
	}
	
	// Liste des joueurs présent sur le serveur
	$data['players']['listOptions'] = AdminServUI::getPlayerList();
	$data['players']['count'] = AdminServ::getNbPlayers();
?>
<?php
	// ENREGISTREMENT
	if( isset($_POST['savematchsetting']) && isset($_SESSION['adminserv']['matchset_maps_selected']) ){
		// Filename
		$matchSettingName = Str::replaceChars($_POST['matchSettingName']);
		$filename = $data['mapsDirectoryPath'].$args['directory'].$matchSettingName;
		if(File::getExtension($matchSettingName) != 'txt'){
			$filename .= '.txt';
		}
		
		$struct = array();
		
		// Gameinfos
		$gameinfos = AdminServ::getGameInfosStructFromPOST();
		$struct['gameinfos'] = array(
			'game_mode' => $gameinfos['GameMode'],
			'chat_time' => $gameinfos['ChatTime'],
			'finishtimeout' => $gameinfos['FinishTimeout'],
			'allwarmupduration' => $gameinfos['AllWarmUpDuration'],
			'disablerespawn' => $gameinfos['DisableRespawn'],
			'forceshowallopponents' => $gameinfos['ForceShowAllOpponents'],
			'rounds_pointslimit' => $gameinfos['RoundsPointsLimit'],
			'rounds_custom_points' => $gameinfos['RoundCustomPoints'],
			'rounds_usenewrules' => $gameinfos['RoundsUseNewRules'],
			'rounds_forcedlaps' => $gameinfos['RoundsForcedLaps'],
			'rounds_pointslimitnewrules' => $gameinfos['RoundsPointsLimitNewRules'],
			'team_pointslimit' => $gameinfos['TeamPointsLimit'],
			'team_maxpoints' => $gameinfos['TeamMaxPoints'],
			'team_usenewrules' => $gameinfos['TeamUseNewRules'],
			'team_pointslimitnewrules' => $gameinfos['TeamPointsLimitNewRules'],
			'timeattack_limit' => $gameinfos['TimeAttackLimit'],
			'timeattack_synchstartperiod' => $gameinfos['TimeAttackSynchStartPeriod'],
			'laps_nblaps' => $gameinfos['LapsNbLaps'],
			'laps_timelimit' => $gameinfos['LapsTimeLimit'],
			'cup_pointslimit' => $gameinfos['CupPointsLimit'],
			'cup_roundsperchallenge' => $gameinfos['CupRoundsPerMap'],
			'cup_nbwinners' => $gameinfos['CupNbWinners'],
			'cup_warmupduration' => $gameinfos['CupWarmUpDuration']
		);
		if(SERVER_VERSION_NAME != 'TmForever'){
			$struct['gameinfos']['script_name'] = $gameinfos['ScriptName'];
		}
		
		// HotSeat
		$struct['hotseat'] = array(
			'game_mode' => intval($_POST['hotSeatGameMode']),
			'time_limit' => TimeDate::secToMillisec( intval($_POST['hotSeatTimeLimit']) ),
			'rounds_count' => intval($_POST['hotSeatCountRound'])
		);
		
		// Filter
		$struct['filter'] = array(
			'is_lan' => array_key_exists('filterIsLan', $_POST),
			'is_internet' => array_key_exists('filterIsInternet', $_POST),
			'is_solo' => array_key_exists('filterIsSolo', $_POST),
			'is_hotseat' => array_key_exists('filterIsHotSeat', $_POST),
			'sort_index' => intval($_POST['filterSortIndex']),
			'random_map_order' => array_key_exists('filterRandomMaps', $_POST),
			'force_default_gamemode' => intval($_POST['filterDefaultGameMode']),
		);
		
		// ScriptSettings
		if( !$client->query('GetModeScriptInfo') ){
			AdminServ::error();
		}
		else{
			$scriptsettings = $client->getResponse();
			
			if( !empty($scriptsettings['ParamDescs']) ){
				foreach($scriptsettings['ParamDescs'] as $param){
					$struct['scriptsettings'][] = array(
						'name' => $param['Name'],
						'type' => $param['Type'],
						'value' => $param['Default']
					);
				}
			}
		}
		
		// Maps
		$struct['startindex'] = 1;
		$maps = $_SESSION['adminserv']['matchset_maps_selected']['lst'];
		if( isset($maps) && is_array($maps) && !empty($maps) ){
			$mapsField = (SERVER_VERSION_NAME == 'TmForever') ? 'challenge' : 'map';
			foreach($maps as $id => $values){
				$struct[$mapsField][$values['UId']] = $values['FileName'];
			}
		}
		
		
		// Enregistrement
		if( ($result = AdminServ::saveMatchSettings($filename, $struct)) !== true ){
			AdminServ::error(Utils::t('Unable to save the MatchSettings').' : '.$matchSettingName.' ('.$result.')');
		}
		else{
			$action = Utils::t('The MatchSettings "!matchSettingName" was successfully created in the folder', array('!matchSettingName' => $matchSettingName)).' : '.$data['mapsDirectoryPath'].$args['directory'];
			AdminServ::info($action);
			AdminServLogs::add('action', $action);
			Utils::redirection(false, '?p='.USER_PAGE .$hasDirectory);
		}
	}
	else{
		if( !isset($_GET['f']) ){
			unset($_SESSION['adminserv']['matchset_maps_selected']);
		}
	}
	
	
	// LECTURE
	$data['directoryList'] = Folder::getArborescence($data['mapsDirectoryPath'], AdminServConfig::$MAPS_HIDDEN_FOLDERS, substr_count($data['mapsDirectoryPath'], '/'));
	$data['matchSettings'] = array();
	// Édition
	if( isset($_GET['f']) && $_GET['f'] != null ){
		$data['pageTitle'] = Utils::t('Edit');
		$data['matchSettings']['name'] = $_GET['f'];
		$matchSettingsData = AdminServ::getMatchSettingsData($data['mapsDirectoryPath'].$args['directory'].$data['matchSettings']['name']);
		$data['gameInfos'] = array(
			'curr' => null,
			'next' => $matchSettingsData['gameinfos']
		);
		unset($matchSettingsData['gameinfos']);
		$data['matchSettings'] += $matchSettingsData;
		if( isset($data['matchSettings']['maps']) ){
			$maps = AdminServ::getMapListFromMatchSetting($data['matchSettings']['maps']);
			$data['matchSettings']['nbm'] = $maps['nbm']['count'];
			$_SESSION['adminserv']['matchset_maps_selected'] = $maps;
		}
		else{
			$data['matchSettings']['nbm'] = 0;
		}
	}
	else{
		$data['pageTitle'] = Utils::t('Create');
		$data['matchSettings']['name'] = 'match_settings';
		$gameInfos = AdminServ::getGameInfos();
		$data['gameInfos'] = array(
			'curr' => null,
			'next' => $gameInfos['next']
		);
		$data['matchSettings']['hotseat'] = array(
			'GameMode' => 1,
			'TimeLimit' => 300000,
			'RoundsCount' => 5
		);
		$data['matchSettings']['filter'] = array(
			'IsLan' => 1,
			'IsInternet' => 1,
			'IsSolo' => 0,
			'IsHotseat' => 1,
			'SortIndex' => 1000,
			'RandomMapOrder' => 0,
			'ForceDefaultGameMode' => 1
		);
		$data['matchSettings']['StartIndex'] = 0;
		$data['matchSettings']['nbm'] = 0;
	}
?>
<?php
	// GAME
	if(SERVER_VERSION_NAME == 'TmForever'){
		$queries = array(
			'removeMap' => 'RemoveChallengeList',
			'chooseNextMap' => 'ChooseNextChallengeList'
		);
	}
	else{
		$queries = array(
			'removeMap' => 'RemoveMapList',
			'chooseNextMap' => 'ChooseNextMapList'
		);
	}
	
	// ACTIONS
	if( isset($_POST['removeMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
		if( !$client->query($queries['removeMap'], $_POST['map']) ){
			AdminServ::error();
		}
		else{
			AdminServLogs::add('action', 'Remove map ('.count($_POST['map']).')');
			Utils::redirection(false, '?p='.USER_PAGE);
		}
	}
	else if( isset($_POST['chooseNextMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
		if( !$client->query($queries['chooseNextMap'], $_POST['map']) ){
			AdminServ::error();
		}
		else{
			AdminServLogs::add('action', 'Choose next map ('.count($_POST['map']).')');
			Utils::redirection(false, '?p='.USER_PAGE);
		}
	}
	
	// MAPLIST
	$data['maps'] = AdminServ::getMapList();
?>
<?php
	// GAME VERSION
	if(SERVER_VERSION_NAME == 'TmForever'){
		$queries = array(
			'insert' => 'InsertChallenge',
			'add' => 'AddChallenge'
		);
	}
	else{
		$queries = array(
			'insert' => 'InsertMap',
			'add' => 'AddMap'
		);
	}
	
	// ACTIONS
	if( isset($_POST['addMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
		foreach($_POST['map'] as $map){
			if( !$client->query($queries['add'], $data['mapsDirectoryPath'].$map) ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', 'Add map: '.$map);
			}
		}
	}
	else if( isset($_POST['insertMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
		foreach($_POST['map'] as $map){
			if( !$client->query($queries['insert'], $data['mapsDirectoryPath'].$map) ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', 'Insert map: '.$map);
			}
		}
	}
	else if( isset($_POST['downloadMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
		// Si on télécharge plusieurs fichiers, on envoi un zip
		$countMaps = count($_POST['map']);
		if($countMaps > 1){
			$struct = array();
			foreach($_POST['map'] as $map){
				$struct[] = $data['mapsDirectoryPath'].$map;
			}
			$zipError = null;
			$zipFileName = 'maps.zip';
			if( !Zip::create($zipFileName, $struct, $zipError) ){
				AdminServ::error($zipError);
			}
			else{
				File::download($zipFileName);
				AdminServLogs::add('action', 'Download packmap ('.$countMaps.' maps)');
				if( $result = File::delete($zipFileName) !== true ){
					AdminServ::error($result);
				}
			}
		}
		// Sinon on envoi le fichier seul
		else{
			File::download($data['mapsDirectoryPath'].$_POST['map'][0]);
			AdminServLogs::add('action', 'Download map: '.$_POST['map'][0]);
		}
	}
	else if( isset($_POST['renameMapValid']) && isset($_POST['map']) && count($_POST['map']) > 0 && isset($_POST['renameMapList']) && count($_POST['renameMapList']) > 0 ){
		$i = 0;
		foreach($_POST['renameMapList'] as $newMapName){
			$result = File::rename($data['mapsDirectoryPath'].$_POST['map'][$i], $data['mapsDirectoryPath'].$args['directory'].$newMapName);
			if($result !== true ){
				AdminServ::error(Utils::t('Unable to rename the map').' : '.$newMapName.' ('.$result.')');
				break;
			}
			else{
				AdminServLogs::add('action', 'Rename map: '.$_POST['map'][$i].' to '.$newMapName);
			}
			$i++;
		}
		
		Utils::redirection(false, '?p='.USER_PAGE .$hasDirectory);
	}
	else if( isset($_POST['renameAutoValid']) && isset($_POST['map']) && count($_POST['map']) > 0 && isset($_POST['renameMapList']) && count($_POST['renameMapList']) > 0 ){
		$i = 0;
		foreach($_POST['renameMapList'] as $newMapName){
			$result = File::rename($data['mapsDirectoryPath'].$_POST['map'][$i], $data['mapsDirectoryPath'].$args['directory'].Str::replaceChars($newMapName));
			if($result !== true){
				AdminServ::error(Utils::t('Unable to rename the map').' : '.$newMapName.' ('.$result.')');
				break;
			}
			else{
				AdminServLogs::add('action', 'Rename map (auto): '.$_POST['map'][$i].' to '.$newMapName);
			}
			$i++;
		}
		
		Utils::redirection(false, '?p='.USER_PAGE .$hasDirectory);
	}
	else if( isset($_POST['moveMapValid']) && isset($_POST['moveDirectoryList']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
		// Chemin
		if($_POST['moveDirectoryList'] == '.'){
			$newPath = $data['mapsDirectoryPath'];
		}
		else{
			$newPath = $_POST['moveDirectoryList'];
		}
		
		// Déplacement
		foreach($_POST['map'] as $map){
			$result = File::rename($data['mapsDirectoryPath'].$map, $newPath.basename($map) );
			if($result !== true ){
				AdminServ::error(Utils::t('Unable to move the map').' : '.$map.' ('.$result.')');
				break;
			}
			else{
				AdminServLogs::add('action', 'Move map: '.$map.' to '.$newPath.basename($map) );
			}
		}
		
		Utils::redirection(false, '?p='.USER_PAGE .$hasDirectory);
	}
	else if( isset($_POST['deleteMap']) && isset($_POST['map']) && count($_POST['map']) > 0 ){
		foreach($_POST['map'] as $map){
			$result = File::delete($data['mapsDirectoryPath'].$map);
			if($result !== true){
				AdminServ::error(Utils::t('Unable to delete the map').' : '.$map.' ('.$result.')');
				break;
			}
			else{
				AdminServLogs::add('action', 'Delete map: '.$map);
			}
		}
		
		Utils::redirection(false, '?p='.USER_PAGE .$hasDirectory);
	}
	// Save MatchSettings
	if( (isset($_POST['addMap']) || isset($_POST['insertMap'])) && SERVER_MATCHSET ){
		if( isset($_POST['SaveCurrentMatchSettings']) && array_key_exists('SaveCurrentMatchSettings', $_POST) ){
			if( !$client->query('SaveMatchSettings', $data['mapsDirectoryPath'] . SERVER_MATCHSET) ){
				AdminServ::error();
			}
		}
	}
	
	
	// MAPLIST
	$sort = null;
	if( isset($_GET['sort']) && $_GET['sort'] != null){
		$sort = addslashes($_GET['sort']);
	}
	$data['maps'] = AdminServ::getLocalMapList($data['currentDir'], $args['directory'], $sort);
?>
<?php
	// ACTIONS
	if( isset($_POST['saveMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
		foreach($_POST['matchset'] as $matchset){
			if( !$client->query('SaveMatchSettings', $data['mapsDirectoryPath'].$matchset) ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', 'Save matchsettings: '.$matchset);
			}
		}
		Utils::redirection(false, '?p='.USER_PAGE.$data['hasDirectory']);
	}
	else if( isset($_POST['loadMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
		foreach($_POST['matchset'] as $matchset){
			if( !$client->query('LoadMatchSettings', $data['mapsDirectoryPath'].$matchset) ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', 'Load matchsettings: '.$matchset);
			}
		}
		Utils::redirection(false, '?p='.USER_PAGE.$data['hasDirectory']);
	}
	else if( isset($_POST['addMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
		foreach($_POST['matchset'] as $matchset){
			if( !$client->query('AppendPlaylistFromMatchSettings', $data['mapsDirectoryPath'].$matchset) ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', 'Append playlist from matchsettings: '.$matchset);
			}
		}
	Utils::redirection(false, '?p='.USER_PAGE.$data['hasDirectory']);
	}
	else if( isset($_POST['insertMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
		foreach($_POST['matchset'] as $matchset){
			if( !$client->query('InsertPlaylistFromMatchSettings', $data['mapsDirectoryPath'].$matchset) ){
				AdminServ::error();
			}
			else{
				AdminServLogs::add('action', 'Insert playlist from matchsettings: '.$matchset);
			}
		}
		Utils::redirection(false, '?p='.USER_PAGE.$data['hasDirectory']);
	}
	else if( isset($_POST['editMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
		AdminServLogs::add('action', 'Edit matchsettings: '.$_POST['matchset'][0]);
		// Redirection sur la page de création d'un matchsettings
		Utils::redirection(false, '?p=maps-creatematchset'.$data['hasDirectory'].'&f='.$_POST['matchset'][0]);
	}
	else if( isset($_POST['deleteMatchset']) && isset($_POST['matchset']) && count($_POST['matchset']) > 0 ){
		foreach($_POST['matchset'] as $matchset){
			if( !File::delete($data['mapsDirectoryPath'].$matchset) ){
				AdminServ::error(Utils::t('Unable to delete the playlist').' : '.$matchset);
			}
			else{
				AdminServLogs::add('action', 'Delete matchsettings: '.$matchset);
			}
		}
		Utils::redirection(false, '?p='.USER_PAGE.$data['hasDirectory']);
	}
	
	
	// MATCH SETTINGS LIST
	$data['matchsettingsList'] = AdminServ::getLocalMatchSettingList($data['currentDir'], $args['directory']);
?>
<?php
	// GAME VERSION
	if(SERVER_VERSION_NAME == 'TmForever'){
		$queries = array(
			'chooseNextMap' => 'ChooseNextChallengeList'
		);
	}
	else{
		$queries = array(
			'chooseNextMap' => 'ChooseNextMapList'
		);
	}
	
	// ACTIONS
	if( isset($_POST['save']) && isset($_POST['list']) && $_POST['list'] != null ){
		$list = explode(',', $_POST['list']);
		
		if( !$client->query($queries['chooseNextMap'], $list) ){
			AdminServ::error();
		}
		else{
			AdminServLogs::add('action', 'Order map list');
			Utils::redirection(false, '?p='.USER_PAGE);
		}
	}
	
	
	// MAPLIST
	$data['maps'] = AdminServ::getMapList();
	unset($data['maps']['lst'][$data['maps']['cid']]);
?>
<?php	// LOCAL MODE	$localPages = array(		'maps-local',		'maps-upload',		'maps-matchset',		'maps-creatematchset'	);	$data['mapsDirectoryPath'] = AdminServ::getMapsDirectoryPath();	define('IS_LOCAL', file_exists($data['mapsDirectoryPath']));		// LECTURE	if( IS_LOCAL && in_array(USER_PAGE, $localPages) ){		if( !Utils::isWinServer() ){			$checkRightsList[$data['mapsDirectoryPath']] = 755;			$checkRightsList[AdminServConfig::$PATH_RESOURCES . 'cache'] = 777;			AdminServ::checkRights($checkRightsList);		}				// Read current directory		$matchsettingsPages = in_array(USER_PAGE, array('maps-matchset', 'maps-creatematchset'));		$hiddenFolders = ($matchsettingsPages) ? AdminServConfig::$MATCHSET_HIDDEN_FOLDERS : AdminServConfig::$MAPS_HIDDEN_FOLDERS;		$hiddenFiles = ($matchsettingsPages) ? AdminServConfig::$MAP_EXTENSION : AdminServConfig::$MATCHSET_EXTENSION;		$data['currentDir'] = Folder::read($data['mapsDirectoryPath'].$args['directory'], $hiddenFolders, $hiddenFiles, intval(AdminServConfig::RECENT_STATUS_PERIOD * 3600) );	}	else{		$notLocalPages = array(			'maps-local',			'maps-matchset',			'maps-creatematchset'		);		if( in_array(USER_PAGE, $notLocalPages) ){			Utils::redirection(false, '?p=maps-list');		}	}		// ACTIONS	$data['hasDirectory'] = null;	if($args['directory']){		$data['hasDirectory'] = '&d='.$args['directory'];	}		// Nouveau dossier	if( isset($_POST['newFolderValid']) && $_POST['newFolderName'] != null || isset($_POST['newFolderName']) ){		if( Folder::create($data['mapsDirectoryPath'].$args['directory'].Str::replaceChars($_POST['newFolderName'])) !== true ){			AdminServ::error(Utils::t('Unable to create the folder').' : '.$_POST['newFolderName']);		}		else{			AdminServLogs::add('action', 'Create new folder: '.$_POST['newFolderName']);			Utils::redirection(false, '?p='.USER_PAGE .$data['hasDirectory']);		}	}	// Renommer un dossier	else if( isset($_POST['optionFolderHiddenFieldAction']) && $_POST['optionFolderHiddenFieldAction'] == 'rename'){		$newDirectory = addslashes($_POST['optionFolderHiddenFieldValue']);				if( ($result = Folder::rename($data['mapsDirectoryPath'].$args['directory'], $data['mapsDirectoryPath'].$newDirectory)) !== true ){			AdminServ::error(Utils::t('Unable to rename the folder').' : '.$args['directory'].' ('.$result.')');		}		else{			AdminServLogs::add('action', 'Rename folder: '.$args['directory'].' to '.$newDirectory);			Utils::redirection(false, '?p='.USER_PAGE .'&d='.$newDirectory.'/');		}	}	// Déplacer un dossier	else if( isset($_POST['optionFolderHiddenFieldAction']) && $_POST['optionFolderHiddenFieldAction'] == 'move'){		$newPath = addslashes($_POST['optionFolderHiddenFieldValue']);		if($newPath == '.'){			$newPath = $data['mapsDirectoryPath'];		}		$newPath .= basename($args['directory']).'/';		$newPathFromMapsPath = str_replace($data['mapsDirectoryPath'], '', $newPath);		if($newPathFromMapsPath){			$newPathFromMapsPath = '&d='.$newPathFromMapsPath;		}				if( ($result = Folder::rename($data['mapsDirectoryPath'].$args['directory'], $newPath)) !== true ){			AdminServ::error(Utils::t('Unable to move the folder').' : '.$args['directory'].' ('.$result.')');		}		else{			AdminServLogs::add('action', 'Move folder: '.$args['directory'].' to '.$newPathFromMapsPath);			Utils::redirection(false, '?p='.USER_PAGE .$newPathFromMapsPath);		}	}	// Supprimer un dossier	else if( isset($_POST['optionFolderHiddenFieldAction']) && $_POST['optionFolderHiddenFieldAction'] == 'delete'){		if( ($result = Folder::delete($data['mapsDirectoryPath'].$args['directory'])) !== true ){			AdminServ::error(Utils::t('Unable to delete the folder').' : '.$args['directory'].' ('.$result.')');		}		else{			// Clean cache			$cache = new AdminServCache();			$cacheKey = 'mapslist-'.Str::replaceChars($data['mapsDirectoryPath'].$args['directory']);			$cache->delete($cacheKey);						AdminServLogs::add('action', 'Delete folder: '.$args['directory']);			Utils::redirection(false, '?p='.USER_PAGE);		}	}?>
<?php
	// Nombre de plugins
	$data['nbplugins'] = AdminServPlugin::countPlugins();
	if($data['nbplugins']['count'] === 0){
		Utils::redirection();
	}
?>
<?php
	// GAMEDATA
	if( AdminServAdminLevel::isType('Admin') ){
		if( !$client->query('GameDataDirectory') ){
			AdminServ::error();
		}
		else{
			$gameDataDirectory = $client->getResponse();
			define('IS_LOCAL', file_exists($gameDataDirectory));
			
			if(IS_LOCAL){
				$srvConfigDirectory = $gameDataDirectory.'Config/';
				$srvoptsConfigDirectory = $srvConfigDirectory.'AdminServ/ServerOptions/';
				if( !Utils::isWinServer() ){
					AdminServ::checkRights(array($srvConfigDirectory => 777));
				}
				
				if( !file_exists($srvoptsConfigDirectory) ){
					if( ($result = Folder::create($srvoptsConfigDirectory)) !== true ){
						AdminServ::error(Utils::t('Unable to create the folder').' : '.$srvoptsConfigDirectory.' ('.$result.')');
					}
				}
				
				$data['srvoptsConfigFiles'] = Folder::read($srvoptsConfigDirectory, array(), array(), intval(AdminServConfig::RECENT_STATUS_PERIOD * 3600) );
			}
		}
	}
	
	
	// ENREGISTREMENT
	if( isset($_POST['savesrvopts']) ){
		// Récupération des données
		$struct = AdminServ::getServerOptionsStruct();
		$ChangeAuthPassword = null;
		if( isset($_POST['ChangeAuthPassword']) && $_POST['ChangeAuthPassword'] != null ){
			$ChangeAuthLevel = $_POST['ChangeAuthLevel'];
			$ChangeAuthPassword = trim($_POST['ChangeAuthPassword']);
		}
		$srvoptsImportExport = false;
		if( array_key_exists('srvoptsImportExport', $_POST) ){
			$srvoptsImportExport = $_POST['srvoptsImportExport'];
		}
		
		// Enregistrement
		if($ChangeAuthPassword){
			if(USER_ADMINLEVEL === $ChangeAuthLevel){
				$_SESSION['adminserv']['password'] = $ChangeAuthPassword;
			}
			AdminServ::info( Utils::t('You changed the password "!authLevel", remember it at the next connection!', array('!authLevel' => $ChangeAuthLevel)) );
			AdminServLogs::add('action', 'Change authentication password for '.$ChangeAuthLevel.' level');
		}
		elseif($srvoptsImportExport){
			// Import
			if($srvoptsImportExport == 'Import'){
				$srvoptsImportName = $_POST['srvoptsImportName'];
				if($srvoptsImportName != 'none'){
					$struct = AdminServ::importServerOptions($srvoptsConfigDirectory.$srvoptsImportName);
					if( AdminServ::setServerOptions($struct) ){
						AdminServLogs::add('action', 'Import server options from '.$srvoptsConfigDirectory.$srvoptsImportName);
					}
				}
			}
			// Export
			elseif($srvoptsImportExport == 'Export'){
				$srvoptsExportName = Str::replaceChars($_POST['srvoptsExportName']);
				AdminServ::exportServerOptions($srvoptsConfigDirectory.$srvoptsExportName.'.txt', $struct);
			}
		}
		elseif( AdminServ::setServerOptions($struct) ){
			AdminServLogs::add('action', 'Save server options');
		}
		Utils::redirection(false, '?p='.USER_PAGE);
	}
	
	
	// LECTURE
	$data['srvOpt'] = AdminServ::getServerOptions();
	$data['adminLevels'] = AdminServAdminLevel::getServerList();
?>
<section class="cadre">
	<h1><?php echo Utils::t('Chat'); ?></h1>
	<div class="title-detail">
		<ul>
			<li class="last"><a id="checkServerLines" href="?p=chat" data-val="0" data-txt="<?php echo Utils::t('Show server lines'); ?>"><?php echo Utils::t('Hide server lines'); ?></a></li>
		</ul>
	</div>
	
	<div id="chat"><?php echo $data['serverLines']; ?></div>
	
	<?php if (AdminServAdminLevel::hasPermission('chat_sendmessage')): ?>
		<div class="options">
			<input class="text" type="text" name="chatNickname" id="chatNickname" value="<?php echo $data['nickname']; ?>" data-default-value="<?php echo Utils::t('Nickname'); ?>" />
			<select name="chatColor" id="chatColor" title="<?php echo Utils::t('Default color: yellow'); ?>">
				<?php echo $data['colorOptions']; ?>
			</select>
			<input class="text" type="text" name="chatMessage" id="chatMessage" value="<?php echo Utils::t('Message'); ?>" data-default-value="<?php echo Utils::t('Message'); ?>" />
			<select name="chatDestination" id="chatDestination" title="<?php echo $data['destination']['title']; ?>">
				<option value="server"><?php echo Utils::t('Destination'); ?></option>
				<?php echo $data['destination']['list']; ?>
			</select>
			<input class="button dark" type="submit" name="chatSend" id="chatSend" value="<?php echo Utils::t('Send'); ?>" />
		</div>
	<?php endif; ?>
</section>
<section class="cadre">
	<h1><?php echo (defined('IS_LEVEL_EDITION')) ? Utils::t('Edit level') : Utils::t('Add level'); ?></h1>
	<form method="post" action="?p=<?php echo USER_PAGE; if ($args['id'] !== -1): echo '&id='.$args['id']; endif; ?>">
		<div class="content">
			<fieldset>
				<legend><?php echo Utils::t('Admin level'); ?></legend>
				<table>
					<tr>
						<td class="key"><label for="addLevelName"><?php echo Utils::t('Level name'); ?></label></td>
						<td class="value">
							<input class="text width3" type="text" name="addLevelName" id="addLevelName" value="<?php echo $data['name']; ?>" />
						</td>
						<td class="info"></td>
					</tr>
					<tr>
						<td class="key"><label for="addLevelType"><?php echo Utils::t('Level type'); ?></label></td>
						<td class="value">
							<?php if (!empty($data['types'])): ?>
								<select name="addLevelType" id="addLevelType">
									<?php foreach ($data['types'] as $type): ?>
										<option value="<?php echo $type; ?>"<?php echo (defined('IS_LEVEL_EDITION') && $type == $data['adminlevel']['type']) ? ' selected="selected"' : ''; ?>><?php echo $type; ?></option>
									<?php endforeach; ?>
								</select>
							<?php endif; ?>
						</td>
						<td class="info"></td>
					</tr>
				</table>
			</fieldset>
			
			<fieldset class="adminlevelSortableList">
				<legend><?php echo Utils::t('Access'); ?></legend>
				<table>
					<tr>
						<td class="key"><?php echo Utils::t('Add access'); ?></td>
						<td class="value">
							<h3><?php echo Utils::t('All access'); ?></h3>
							<ul id="defaultAccess" class="adminlevelAccessList">
								<?php if (!empty($data['access']['default'])): ?>
									<?php foreach ($data['access']['default'] as $accessName): ?>
										<li class="defaultName"><?php echo $accessName; ?></li>
									<?php endforeach; ?>
								<?php endif; ?>
							</ul>
						</td>
						<td class="value">
							<h3><?php echo Utils::t('Selected access'); ?></h3>
							<ul id="selectedAccess" class="adminlevelAccessList">
								<?php if (!empty($data['access']['selected'])): ?>
									<?php foreach ($data['access']['selected'] as $accessName): ?>
										<li class="selectedName"><?php echo $accessName; ?></li>
									<?php endforeach; ?>
								<?php endif; ?>
							</ul>
							<input type="hidden" name="selectedAccessSortList" id="selectedAccessSortList" value="" />
						</td>
					</tr>
				</table>
			</fieldset>
			
			<fieldset class="adminlevelSortableList">
				<legend><?php echo Utils::t('Permissions'); ?></legend>
				<table>
					<tr>
						<td class="key"><?php echo Utils::t('Add permission'); ?></td>
						<td class="value">
							<h3><?php echo Utils::t('All permissions'); ?></h3>
							<ul id="defaultPermission" class="adminlevelPermissionList">
								<?php if (!empty($data['permission']['default'])): ?>
									<?php foreach ($data['permission']['default'] as $permissionName): ?>
										<li class="defaultName"><?php echo $permissionName; ?></li>
									<?php endforeach; ?>
								<?php endif; ?>
							</ul>
						</td>
						<td class="value">
							<h3><?php echo Utils::t('Selected permissions'); ?></h3>
							<ul id="selectedPermission" class="adminlevelPermissionList">
								<?php if (!empty($data['permission']['selected'])): ?>
									<?php foreach ($data['permission']['selected'] as $permissionName): ?>
										<li class="selectedName"><?php echo $permissionName; ?></li>
									<?php endforeach; ?>
								<?php endif; ?>
							</ul>
							<input type="hidden" name="selectedPermissionSortList" id="selectedPermissionSortList" value="" />
						</td>
					</tr>
				</table>
			</fieldset>
		</div>
		
		<div class="fright save">
			<input class="button light" type="submit" name="savelevel" id="savelevel" value="<?php echo Utils::t('Save'); ?>" />
		</div>
	</form>
</section>
<section class="cadre">
	<h1><?php echo (defined('IS_SERVER_EDITION')) ? Utils::t('Edit server') : Utils::t('Add server'); ?></h1>
	<form method="post" action="?p=<?php echo USER_PAGE; if ($args['id'] !== -1): echo '&id='.$args['id']; endif; ?>">
		<div class="content">
			<fieldset>
				<legend><?php echo Utils::t('Connection information'); ?></legend>
				<table>
					<tr>
						<td class="key"><label for="addServerName"><?php echo Utils::t('Server name'); ?></label></td>
						<td class="value">
							<input class="text width3" type="text" name="addServerName" id="addServerName" value="<?php echo $data['name']; ?>" />
						</td>
						<td class="info">
							<?php echo Utils::t('Server name without color'); ?>
						</td>
					</tr>
					<tr>
						<td class="key"><label for="addServerAddress"><?php echo Utils::t('Address'); ?></label></td>
						<td class="value">
							<input class="text width3" type="text" name="addServerAddress" id="addServerAddress" value="<?php echo $data['address']; ?>" />
						</td>
						<td class="info">
							<?php echo Utils::t('IP address or domain name'); ?>
						</td>
					</tr>
					<tr>
						<td class="key"><label for="addServerPort"><?php echo Utils::t('XMLRPC port'); ?></label></td>
						<td class="value">
							<input class="text width3" type="number" name="addServerPort" id="addServerPort" value="<?php echo $data['port']; ?>" />
						</td>
						<td class="info">
							<?php echo Utils::t('Port for remote control'); ?>
						</td>
					</tr>
                    <tr>
                        <td class="key"><label for="addDisplayServPassword"><?php echo Utils::t('DisplayServ Password'); ?></label></td>
                        <td class="value">
                            <input class="text width3" type="text" name="addDisplayServPassword" id="addDisplayServPassword" value="<?php echo $data['ds_pw']; ?>" />
                        </td>
                        <td class="info">
                            <?php echo Utils::t('User password from dedicated config'); ?>
                        </td>
                    </tr>
				</table>
			</fieldset>
			
			<fieldset>
				<legend><?php echo Utils::t('Optionnal information'); ?></legend>
				<table>
					<tr>
						<td class="key"><label for="addServerMapsBasePath"><?php echo Utils::t('Maps base folder'); ?></label></td>
						<td class="value">
							<input class="text width3" type="text" name="addServerMapsBasePath" id="addServerMapsBasePath" value="<?php echo $data['mapsbasepath']; ?>" />
						</td>
						<td class="info">
							<?php echo Utils::t('Default path from maps folder for listing maps'); ?>
						</td>
					</tr>
					<tr>
						<td class="key"><label for="addServerMatchSet"><?php echo Utils::t('Server MatchSettings'); ?></label></td>
						<td class="value">
							<input class="text width3" type="text" name="addServerMatchSet" id="addServerMatchSet" value="<?php echo $data['matchsettings']; ?>" />
						</td>
						<td class="info">
							<?php echo Utils::t('Current server MatchSettings name'); ?>
						</td>
					</tr>
					<tr>
						<td class="key"><label for="addServerAdmLvlSA"><?php echo Utils::t('SuperAdmin level'); ?></label></td>
						<td class="value">
							<input class="text width3" type="text" name="addServerAdmLvlSA" id="addServerAdmLvlSA" value="<?php echo $data['adminlevel']['SuperAdmin']; ?>" />
						</td>
						<td rowspan="3" class="info">
							<?php echo Utils::t('Possible values for the admin level:'); ?><br />
							<?php echo Utils::t('all => all access'); ?><br />
							<?php echo Utils::t('local => local network access'); ?><br />
							<?php echo Utils::t('192.168.0.1, 192.168.0.2 => access to one or more IP address'); ?><br />
							<?php echo Utils::t('none => removed from the access list'); ?>
						</td>
					</tr>
					<tr>
						<td class="key"><label for="addServerAdmLvlADM"><?php echo ucwords(Utils::t('Admin level')); ?></label></td>
						<td class="value">
							<input class="text width3" type="text" name="addServerAdmLvlADM" id="addServerAdmLvlADM" value="<?php echo $data['adminlevel']['Admin']; ?>" />
						</td>
					</tr>
					<tr>
						<td class="key"><label for="addServerAdmLvlUSR"><?php echo Utils::t('User level'); ?></label></td>
						<td class="value">
							<input class="text width3" type="text" name="addServerAdmLvlUSR" id="addServerAdmLvlUSR" value="<?php echo $data['adminlevel']['User']; ?>" />
						</td>
					</tr>
				</table>
			</fieldset>
		</div>
		
		<div class="fright save">
			<input class="button light" type="submit" name="saveserver" id="saveserver" value="<?php echo Utils::t('Save'); ?>" />
		</div>
	</form>
</section>
<section class="cadre">
	<h1><?php echo Utils::t('Admin levels list'); ?></h1>
	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
	<table id="levelList">
		<thead>
			<tr>
				<th class="thleft"><?php echo Utils::t('Name'); ?></th>
				<th><?php echo Utils::t('Type'); ?></th>
				<th><?php echo Utils::t('Access'); ?></th>
				<th><?php echo Utils::t('Permissions'); ?></th>
				<th class="thright"><?php echo Utils::t('Manage'); ?></th>
			</tr>
		</thead>
		<tbody>
			<tr class="table-separation"><td colspan="8"></td></tr>
			<?php if($data['count'] > 0): ?>
				<?php $i = 0; ?>
				<?php foreach ($data['levels'] as $levelData): ?>
					<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
						<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/players.png" alt="" /><?php echo $levelData['name']; ?></td>
						<td><?php echo $levelData['type']; ?></td>
						<td><?php echo $levelData['allowed_access']; ?></td>
						<td><?php echo $levelData['allowed_permissions']; ?></td>
						<td class="checkbox"><input type="radio" name="level[]" value="<?php echo $levelData['name']; ?>" /></td>
					</tr>
					<?php $i++; ?>
				<?php endforeach; ?>
			<?php else: ?>
				<tr class="no-line">
					<td class="center" colspan="8"><?php echo Utils::t('No admin level'); ?></td>
				</tr>
			<?php endif; ?>
		</tbody>
	</table>
	
	<div class="options">
		<div class="fleft">
			<span class="nb-line">
				<?php echo $data['count'].' '.(($data['count'] > 1) ? Utils::t('admin levels') : Utils::t('admin level')); ?>
			</span>
		</div>
		<div class="fright">
			<div class="selected-files-label locked">
				<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
				<div class="selected-files-option">
					<input class="button dark" type="submit" name="deletelevel" id="deletelevel" data-confirm-text="<?php echo Utils::t('Do you really want to remove this selection?'); ?>" value="<?php echo Utils::t('Delete'); ?>" />
					<input class="button dark" type="submit" name="duplicatelevel" id="duplicatelevel" value="<?php echo Utils::t('Duplicate'); ?>" />
					<input class="button dark" type="submit" name="editlevel" id="editlevel" value="<?php echo Utils::t('Modify'); ?>" />
				</div>
			</div>
		</div>
	</div>
	</form>
</section>
<section class="cadre">
	<h1><?php echo Utils::t('Levels order'); ?></h1>
	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
		<div class="content">
			<ul id="sortableLevelsList">
			<?php foreach ($data['levels'] as $levelName => $levelData): ?>
				<li class="ui-state-default">
					<div class="ui-icon ui-icon-arrowthick-2-n-s"></div>
					<div class="order-server-name"><?php echo $levelName; ?></div>
					<div class="order-server-addr-port"><?php echo $levelData['adminlevel']['type']; ?></div>
				</li>
			<?php endforeach; ?>
			</ul>
		</div>
		
		<div class="fright save">
			<input class="button light" type="button" id="reset" name="reset" value="<?php echo Utils::t('Reset'); ?>" />
			<input class="button light" type="submit" id="save" name="save" value="<?php echo Utils::t('Save'); ?>" />
			<input type="hidden" id="list" name="list" value="" />
		</div>
	</form>
</section>
<section class="cadre">
	<h1><?php echo Utils::t('Change password'); ?></h1>
	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
		<div class="content">
			<fieldset>
				<legend><?php echo Utils::t('Password'); ?></legend>
				<table>
					<tr>
						<td class="key"><label for="changePasswordCurrent"><?php echo Utils::t('Current'); ?></label></td>
						<td class="value"><input class="text width3" type="password" name="changePasswordCurrent" id="changePasswordCurrent" value="" /></td>
					</tr>
					<tr>
						<td class="key"><label for="changePasswordNew"><?php echo Utils::t('New'); ?></label></td>
						<td class="value"><input class="text width3" type="password" name="changePasswordNew" id="changePasswordNew" value="" /></td>
					</tr>
				</table>
			</fieldset>
		</div>
		
		<div class="fright save">
			<input class="button light" type="submit" name="savepassword" id="savepassword" value="<?php echo Utils::t('Save'); ?>" />
		</div>
	</form>
</section>
<section class="cadre">
	<h1><?php echo Utils::t('Servers list'); ?></h1>
	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
	<table id="serverList">
		<thead>
			<tr>
				<th class="thleft"><?php echo Utils::t('Server name'); ?></th>
				<th><?php echo Utils::t('Address'); ?></th>
				<th><?php echo Utils::t('Port'); ?></th>
				<th><?php echo Utils::t('MatchSettings'); ?></th>
				<th><?php echo Utils::t('SuperAdmin level'); ?></th>
				<th><?php echo ucwords( Utils::t('Admin level') ); ?></th>
				<th><?php echo Utils::t('User level'); ?></th>
				<th class="thright"><?php echo Utils::t('Manage'); ?></th>
			</tr>
		</thead>
		<tbody>
			<tr class="table-separation"><td colspan="8"></td></tr>
			<?php if($data['count'] > 0): ?>
				<?php $i = 0; ?>
				<?php foreach ($data['servers'] as $serverName => $serverData): ?>
					<?php
						// MatchSettings
						$matchSettings = ($serverData['matchsettings']) ? $serverData['matchsettings'] : Utils::t('None');
						
						// Niveaux admins
						$adminLevelsStatus = array();
						foreach($data['adminLevelsType'] as $level){
							if( array_key_exists($level, $serverData['adminlevel']) ){
								if( is_array($serverData['adminlevel'][$level]) ){
									$adminLevelsStatus[] = Utils::t('IP address');
								}
								else if($serverData['adminlevel'][$level] === 'local'){
									$adminLevelsStatus[] = Utils::t('Local network');
								}
								else if($serverData['adminlevel'][$level] === 'all'){
									$adminLevelsStatus[] = Utils::t('All');
								}
								else if($serverData['adminlevel'][$level] === 'none'){
									$adminLevelsStatus[] = Utils::t('Removed');
								}
								else{
									$adminLevelsStatus[] = Utils::t('Missing');
								}
							}
							else{
								$adminLevelsStatus[] = Utils::t('Missing');
							}
						}
					?>
					<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
						<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/servers.png" alt="" /><?php echo $serverName; ?></td>
						<td><?php echo $serverData['address']; ?></td>
						<td><?php echo $serverData['port']; ?></td>
						<td><?php echo $matchSettings; ?></td>
						<td><?php echo $adminLevelsStatus[0]; ?></td>
						<td><?php echo $adminLevelsStatus[1]; ?></td>
						<td><?php echo $adminLevelsStatus[2]; ?></td>
						<td class="checkbox"><input type="radio" name="server[]" value="<?php echo $serverName; ?>" /></td>
					</tr>
					<?php $i++; ?>
				<?php endforeach; ?>
			<?php else: ?>
				<tr class="no-line">
					<td class="center" colspan="8"><?php echo Utils::t('No server'); ?></td>
				</tr>
			<?php endif; ?>
		</tbody>
	</table>
	
	<div class="options">
		<div class="fleft">
			<span class="nb-line">
				<?php echo $data['count'].' '.(($data['count'] > 1) ? Utils::t('servers') : Utils::t('server')); ?>
			</span>
		</div>
		<div class="fright">
			<div class="selected-files-label locked">
				<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
				<div class="selected-files-option">
					<input class="button dark" type="submit" name="deleteserver" id="deleteserver" data-confirm-text="<?php echo Utils::t('Do you really want to remove this selection?'); ?>" value="<?php echo Utils::t('Delete'); ?>" />
					<input class="button dark" type="submit" name="duplicateserver" id="duplicateserver" value="<?php echo Utils::t('Duplicate'); ?>" />
					<input class="button dark" type="submit" name="editserver" id="editserver" value="<?php echo Utils::t('Modify'); ?>" />
				</div>
			</div>
		</div>
	</div>
	</form>
</section>
<section class="cadre">
	<h1><?php echo Utils::t('Servers order'); ?></h1>
	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
		<div class="content">
			<ul id="sortableServersList">
			<?php foreach ($data['servers'] as $serverName => $serverData): ?>
				<li class="ui-state-default">
					<div class="ui-icon ui-icon-arrowthick-2-n-s"></div>
					<div class="order-server-name"><?php echo $serverName; ?></div>
					<div class="order-server-addr-port"><?php echo $serverData['address'].' / '.$serverData['port']; ?></div>
				</li>
			<?php endforeach; ?>
			</ul>
		</div>
		
		<div class="fright save">
			<input class="button light" type="button" id="reset" name="reset" value="<?php echo Utils::t('Reset'); ?>" />
			<input class="button light" type="submit" id="save" name="save" value="<?php echo Utils::t('Save'); ?>" />
			<input type="hidden" id="list" name="list" value="" />
		</div>
	</form>
</section>
<?php if (isset($_SESSION['adminserv']['check_password']) && $_SESSION['adminserv']['check_password'] === true): // Demande de password ?>
<section class="config-servers">
	<form method="post" action="./config/">
		<fieldset>
			<legend><?php echo Utils::t('Servers configuration'); ?></legend>
			<div class="connection-label">
				<label for="checkPassword"><?php echo Utils::t('Password'); ?> :</label>
				<input class="text" type="password" name="checkPassword" id="checkPassword" value="" />
			</div>
			<div class="connection-login">
				<input class="button light" type="submit" name="configcheckpassword" id="configcheckpassword" value="<?php echo Utils::t('Connection'); ?>" />
			</div>
			<div class="connection-cancel">
				<a class="button light" href="./?logout"><?php echo Utils::t('Cancel'); ?></a>
			</div>
		</fieldset>
	</form>
</section>
<?php elseif (isset($_SESSION['adminserv']['get_password']) && $_SESSION['adminserv']['get_password'] === true): // Demande de création password ?>
<section class="config-servers no-server">
	<form method="post" action="./config/">
		<fieldset>
			<legend><?php echo Utils::t('Online configuration'); ?></legend>
			<div class="connection-label">
				<label for="savePassword"><?php echo Utils::t('Password'); ?> :</label>
				<input class="text" type="password" name="savePassword" id="savePassword" value="" />
			</div>
			<div class="connection-login">
				<input class="button light" type="submit" name="configsavepassword" id="configsavepassword" value="<?php echo Utils::t('Save'); ?>" />
			</div>
		</fieldset>
	</form>
</section>
<?php else: // Affichage de DisplayServ ?>
<section class="displayserv">
	<?php if (AdminServConfig::USE_DISPLAYSERV): ?>
		<link rel="stylesheet" href="<?php echo AdminServConfig::$PATH_RESOURCES; ?>css/displayserv.css" />
		<script src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>js/displayserv.js"></script>
		<script>
			$(document).ready(function(){
				$('#displayserv').displayServ({
					color: '<?php echo AdminServUI::getThemeColor(); ?>'
				});
			});
		</script>
		<div id="displayserv"></div>
	<?php endif; ?>
</section>
<?php endif; ?>
					</div><!-- #content-inner -->				</div><!-- #content -->								<footer>					<div id="footer-inner">						© 2006-<?php echo date('Y'); ?> <a href="http://www.zone-kev717.info"><strong>Kev717</strong></a> - updated by <a href="http://forum.maniaplanet.com/memberlist.php?mode=viewprofile&u=282"><strong>Chris92</strong></a> | AdminServ <?php echo ADMINSERV_VERSION; ?>												<span id="path_resources" hidden="hidden"><?php echo AdminServConfig::$PATH_RESOURCES; ?></span>						<?php if (ADMINSERV_TIMER): ?>							<p>Script executé en <?php echo AdminServ::endTimer(); ?> sec</p>						<?php endif; ?>					</div>				</footer>							</div><!-- #page-inner -->		</div><!-- #page -->	</body></html>
<tr>
	<td class="key"><label for="Next<?php echo $data['gameInfosField']['id']; ?>"><?php echo Utils::t($data['gameInfosField']['name']); ?></label></td>
	<?php if ($data['gameInfosField']['gameInfos']['curr'] != null): ?>
		<td class="value">
			<input class="text width2" type="text" name="Curr<?php echo $data['gameInfosField']['id']; ?>" id="Curr<?php echo $data['gameInfosField']['id']; ?>" readonly="readonly" value="<?php if (isset($data['gameInfosField']['gameInfos']['curr'][$data['gameInfosField']['id']])): echo $data['gameInfosField']['gameInfos']['curr'][$data['gameInfosField']['id']]; endif; ?>" />
		</td>
	<?php endif; ?>
	<td class="value">
		<input class="text width2" type="<?php echo (isset($data['gameInfosField']['gameInfos']['next'][$data['gameInfosField']['id']]) && is_numeric($data['gameInfosField']['gameInfos']['next'][$data['gameInfosField']['id']])) ? 'number" min="0"' : 'text'; ?>" name="Next<?php echo $data['gameInfosField']['id']; ?>" id="Next<?php echo $data['gameInfosField']['id']; ?>" value="<?php if (isset($data['gameInfosField']['gameInfos']['next'][$data['gameInfosField']['id']])): echo $data['gameInfosField']['gameInfos']['next'][$data['gameInfosField']['id']]; endif; ?>" />
	</td>
	<td class="preview"></td>
</tr>
<?php if (SERVER_VERSION_NAME == 'ManiaPlanet'): ?>
	<fieldset id="gameMode-script" class="gameinfos_script" hidden="hidden">
		<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/options.png" alt="" /><?php echo AdminServ::getGameModeName(0); ?></legend>
		<table class="game_infos">
			<tr>
				<td class="key"><label for="NextScriptName"><?php echo Utils::t('Script name'); ?></label></td>
				<?php if ($data['gameInfos']['curr'] != null): ?>
					<td class="value">
						<input class="text width2" type="text" name="CurrScriptName" id="CurrScriptName" readonly="readonly" value="<?php echo $data['gameInfos']['curr']['ScriptName']; ?>" />
					</td>
				<?php endif; ?>
				<?php if ($data['gameInfos']['next'] != null): ?>
					<td class="value">
						<input class="text width2" type="text" name="NextScriptName" id="NextScriptName" value="<?php echo $data['gameInfos']['next']['ScriptName']; ?>" />
					</td>
					<td class="preview">
					<?php if ($data['gameInfos']['next']['GameMode'] == 0): ?>
						<a id="getScriptSettings" href="" data-infotext="<?php echo Utils::t('Script settings updated.'); ?>"><?php echo Utils::t('Script settings'); ?></a>
					<?php endif; ?>
					</td>
				<?php endif; ?>
			</tr>
		</table>
	</fieldset>
	<?php if ($data['gameInfos']['next']['GameMode'] == 0): ?>
		<div id="getScriptSettingsDialog" data-title="<?php echo Utils::t('Script settings'); ?>" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-save="<?php echo Utils::t('Save'); ?>" hidden="hidden">
			<div id="dialogScriptInfo">
				<h2><?php echo Utils::t('Script info'); ?></h2>
				<div class="content">
					<table>
						<tbody>
							<tr>
								<td class="key"><?php echo Utils::t('Name'); ?></td>
								<td class="value" id="dialogScriptInfoName"></td>
							</tr>
							<tr>
								<td class="key"><?php echo Utils::t('Compatible map types'); ?></td>
								<td class="value" id="dialogScriptInfoCompatibleMapTypes"></td>
							</tr>
							<tr class="dialogScriptInfoDesc" hidden="hidden">
								<td class="key"><?php echo Utils::t('Description'); ?></td>
								<td class="value" id="dialogScriptInfoDesc"></td>
							</tr>
						</tbody>
					</table>
				</div>
			</div>
			<div id="dialogScriptSettings">
				<h2><?php echo Utils::t('Script parameters'); ?></h2>
				<table>
					<thead>
						<tr>
							<th class="thleft"><?php echo Utils::t('Name'); ?></th>
							<th><?php echo Utils::t('Value'); ?></th>
							<th class="thright"><?php echo Utils::t('Description'); ?></th>
						</tr>
					</thead>
					<tbody></tbody>
				</table>
			</div>
		</div>
	<?php endif; ?>
<?php endif; ?>

<fieldset id="gameMode-rounds" class="gameinfos_round" hidden="hidden">
	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_rounds.png" alt="" /><?php echo AdminServ::getGameModeName(1, true); ?></legend>
	<table class="game_infos">
		<tr>
			<td class="key"><label for="NextRoundsUseNewRules"><?php echo Utils::t('Use new rules'); ?></label></td>
			<?php if ($data['gameInfos']['curr'] != null): ?>
				<td class="value">
					<input class="text width2" type="text" name="CurrRoundsUseNewRules" id="CurrRoundsUseNewRules" readonly="readonly" value="<?php echo ($data['gameInfos']['curr']['RoundsUseNewRules'] != null) ? Utils::t('Enable') : Utils::t('Disable'); ?>" />
				</td>
			<?php endif; ?>
			<td class="value">
				<input class="text" type="checkbox" name="NextRoundsUseNewRules" id="NextRoundsUseNewRules" value=""<?php if ($data['gameInfos']['next']['RoundsUseNewRules'] != null): echo ' checked="checked"'; endif; ?> />
			</td>
			<td class="preview"></td>
		</tr>
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Points limit', 'RoundsPointsLimit'); ?>
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Custom points limit', 'RoundCustomPoints'); ?>
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Force laps', 'RoundsForcedLaps'); ?>
	</table>
</fieldset>

<fieldset id="gameMode-timeattack" class="gameinfos_timeattack" hidden="hidden">
	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_timeattack.png" alt="" /><?php echo AdminServ::getGameModeName(2, true); ?></legend>
	<table class="game_infos">
		<tr>
			<td class="key"><label for="NextTimeAttackLimit"><?php echo Utils::t('Time limit'); ?> <span>(<?php echo Utils::t('sec'); ?>)</span></label></td>
			<?php if ($data['gameInfos']['curr'] != null): ?>
				<td class="value">
					<input class="text width2" type="text" name="CurrTimeAttackLimit" id="CurrTimeAttackLimit" readonly="readonly" value="<?php echo TimeDate::millisecToSec($data['gameInfos']['curr']['TimeAttackLimit']); ?>" />
				</td>
			<?php endif; ?>
			<td class="value">
				<input class="text width2" type="number" min="0" name="NextTimeAttackLimit" id="NextTimeAttackLimit" value="<?php echo TimeDate::millisecToSec($data['gameInfos']['next']['TimeAttackLimit']); ?>" />
			</td>
			<td class="preview"></td>
		</tr>
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Start synchronization period', 'TimeAttackSynchStartPeriod'); ?>
	</table>
</fieldset>

<fieldset id="gameMode-team" class="gameinfos_team" hidden="hidden">
	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_team.png" alt="" /><?php echo AdminServ::getGameModeName(3, true); ?></legend>
	<table class="game_infos">
		<tr>
			<td class="key"><label for="NextTeamUseNewRules"><?php echo Utils::t('Use new rules'); ?></label></td>
			<?php if ($data['gameInfos']['curr'] != null): ?>
				<td class="value">
					<input class="text width2" type="text" name="CurrTeamUseNewRules" id="CurrTeamUseNewRules" readonly="readonly" value="<?php echo ($data['gameInfos']['curr']['TeamUseNewRules'] != null) ? Utils::t('Enable') : Utils::t('Disable'); ?>" />
				</td>
			<?php endif; ?>
			<td class="value">
				<input class="text" type="checkbox" name="NextTeamUseNewRules" id="NextTeamUseNewRules" value=""<?php if ($data['gameInfos']['next']['TeamUseNewRules'] != null): echo ' checked="checked"'; endif; ?> />
			</td>
			<td class="preview"></td>
		</tr>
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Points limit', 'TeamPointsLimit'); ?>
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Maximal points', 'TeamMaxPoints'); ?>
	</table>
</fieldset>

<fieldset id="gameMode-laps" class="gameinfos_laps" hidden="hidden">
	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_laps.png" alt="" /><?php echo AdminServ::getGameModeName(4, true); ?></legend>
	<table class="game_infos">
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Number of laps', 'LapsNbLaps'); ?>
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], Utils::t('Time limit').' <span>('.Utils::t('sec').')</span>', 'LapsTimeLimit'); ?>
	</table>
</fieldset>

<fieldset id="gameMode-cup" class="gameinfos_cup" hidden="hidden">
	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_cup.png" alt="" /><?php echo AdminServ::getGameModeName(5); ?></legend>
	<table class="game_infos">
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Points limit', 'CupPointsLimit'); ?>
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Rounds per map', 'CupRoundsPerMap'); ?>
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'Number of winners', 'CupNbWinners'); ?>
		<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'All WarmUp duration', 'CupWarmUpDuration'); ?>
	</table>
</fieldset>
<fieldset class="gameinfos_general">
	<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/restartrace.png" alt="" /><?php echo Utils::t('General'); ?></legend>
	<table>
		<?php if (AdminServAdminLevel::hasPermission('gameinfos_general_gamemode')): ?>
			<tr>
				<td class="key"><label for="NextGameMode"><?php echo Utils::t('Game mode'); ?></label></td>
				<?php if ($data['gameInfos']['curr'] != null): ?>
					<td class="value">
						<input class="text width2" type="text" name="CurrGameMode" id="CurrGameMode" readonly="readonly" value="<?php echo AdminServ::getGameModeName($data['gameInfos']['curr']['GameMode']); ?>" />
					</td>
				<?php endif; ?>
				<td class="value">
					<select class="width2" name="NextGameMode" id="NextGameMode">
						<?php echo AdminServUI::getGameModeList($data['gameInfos']['next']['GameMode']); ?>
					</select>
				</td>
				<td class="preview"></td>
			</tr>
		<?php endif; ?>
		<?php if (AdminServAdminLevel::hasPermission('gameinfos_general_options')): ?>
			<tr>
				<td class="key"><label for="NextChatTime"><?php echo Utils::t('Map end time'); ?> <span>(<?php echo Utils::t('sec'); ?>)</span></label></td>
				<?php if ($data['gameInfos']['curr'] != null): ?>
					<td class="value">
						<input class="text width2" type="text" name="CurrChatTime" id="CurrChatTime" readonly="readonly" value="<?php echo TimeDate::millisecToSec($data['gameInfos']['curr']['ChatTime'] + 8000); ?>" />
					</td>
				<?php endif; ?>
				<td class="value">
					<input class="text width2" type="number" min="0" name="NextChatTime" id="NextChatTime" value="<?php echo TimeDate::millisecToSec($data['gameInfos']['next']['ChatTime'] + 8000); ?>" />
				</td>
				<td class="preview"></td>
			</tr>
			<tr>
				<td class="key"><label for="NextFinishTimeout"><?php echo Utils::t('Round/lap end time'); ?> <span>(<?php echo Utils::t('sec'); ?>)</span></label></td>
				<?php if ($data['gameInfos']['curr'] != null): ?>
					<td class="value">
						<input class="text width2" type="text" name="CurrFinishTimeout" id="CurrFinishTimeout" readonly="readonly" value="<?php if ($data['gameInfos']['curr']['FinishTimeout'] == 0): echo Utils::t('Default').' (15'.Utils::t('sec'); elseif ($data['gameInfos']['curr']['FinishTimeout'] == 1): echo Utils::t('Auto (based on map)'); else: echo TimeDate::millisecToSec($data['gameInfos']['curr']['FinishTimeout']); endif; ?>" />
					</td>
				<?php endif; ?>
				<td class="value next">
					<select class="width2" name="NextFinishTimeout" id="NextFinishTimeout"<?php if ($data['gameInfos']['next']['FinishTimeout'] > 1): echo ' hidden="hidden"'; endif; ?>>
						<option value="0"<?php if ($data['gameInfos']['next']['FinishTimeout'] == 0): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Default');?> (15<?php echo Utils::t('sec'); ?>)</option>
						<option value="1"<?php if ($data['gameInfos']['next']['FinishTimeout'] == 1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Auto (based on map)'); ?></option>
						<option value="more"><?php echo Utils::t('Choose time'); ?></option>
					</select>
					<input class="text width2" type="number" min="0" name="NextFinishTimeoutValue" id="NextFinishTimeoutValue" value="<?php if ($data['gameInfos']['next']['FinishTimeout'] > 1): echo TimeDate::millisecToSec($data['gameInfos']['next']['FinishTimeout']); endif; ?>"<?php if ($data['gameInfos']['next']['FinishTimeout'] < 2): echo ' hidden="hidden"'; endif; ?> />
				</td>
				<td class="preview"<?php if ($data['gameInfos']['next']['FinishTimeout'] < 2): echo ' hidden="hidden"'; endif; ?>>
					<a class="returnDefaultValue" href="?p=<?php echo USER_PAGE; ?>"><?php echo Utils::t('Return to the default value'); ?></a>
				</td>
			</tr>
		<?php endif; ?>
			<?php if (AdminServAdminLevel::hasPermission('gameinfos_general_warmup')): ?>
				<?php echo AdminServUI::getGameInfosField($data['gameInfos'], 'All WarmUp duration', 'AllWarmUpDuration'); ?>
			<?php endif; ?>
		<?php if (AdminServAdminLevel::hasPermission('gameinfos_general_options')): ?>
			<tr>
				<td class="key"><label for="NextDisableRespawn"><?php echo Utils::t('Respawn'); ?></label></td>
				<?php if ($data['gameInfos']['curr'] != null): ?>
					<td class="value">
						<input class="text width2" type="text" name="CurrDisableRespawn" id="CurrDisableRespawn" readonly="readonly" value="<?php echo ($data['gameInfos']['curr']['DisableRespawn'] === false) ? Utils::t('Enable') : Utils::t('Disable'); ?>" />
					</td>
				<?php endif; ?>
				<td class="value">
					<input class="text" type="checkbox" name="NextDisableRespawn" id="NextDisableRespawn" value=""<?php if ($data['gameInfos']['next']['DisableRespawn'] === false): echo ' checked="checked"'; endif; ?> />
				</td>
				<td class="preview"></td>
			</tr>
			<tr>
				<td class="key"><label for="NextForceShowAllOpponents"><?php echo Utils::t('Force show of all opponents'); ?></label></td>
				<?php if ($data['gameInfos']['curr'] != null): ?>
					<td class="value">
						<input class="text width2" type="text" name="CurrForceShowAllOpponents" id="CurrForceShowAllOpponents" readonly="readonly" value="<?php if ($data['gameInfos']['curr']['ForceShowAllOpponents'] == 0): echo Utils::t('Let player choose'); elseif ($data['gameInfos']['curr']['ForceShowAllOpponents'] == 1): echo Utils::t('All opponents'); else: echo $data['gameInfos']['curr']['ForceShowAllOpponents'].' '.Utils::t('minimal opponents'); endif; ?>" />
					</td>
				<?php endif; ?>
				<td class="value next">
					<select class="width2" name="NextForceShowAllOpponents" id="NextForceShowAllOpponents"<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] > 1): echo ' hidden="hidden"'; endif;?>>
						<option value="0"<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] == 0): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Let player choose'); ?></option>
						<option value="1"<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] == 1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('All opponents'); ?></option>
						<option value="more"><?php echo Utils::t('Choose opponents number'); ?></option>
					</select>
					<input class="text width2" type="text" name="NextForceShowAllOpponentsValue" id="NextForceShowAllOpponentsValue" value="<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] > 1): echo $data['gameInfos']['next']['ForceShowAllOpponents']; endif; ?>"<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] < 2): echo ' hidden="hidden"'; endif; ?> />
				</td>
				<td class="preview"<?php if ($data['gameInfos']['next']['ForceShowAllOpponents'] < 2): echo ' hidden="hidden"'; endif; ?>>
					<a class="returnDefaultValue" href="?p=<?php echo USER_PAGE; ?>"><?php echo Utils::t('Return to the default value'); ?></a>
				</td>
			</tr>
		<?php endif; ?>
	</table>
</fieldset>
<section class="cadre">
	<h1><?php echo Utils::t('Game information'); ?></h1>
	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
		<div class="content gameinfos">
			<?php if (AdminServAdminLevel::hasPermission(array('gameinfos_general_gamemode', 'gameinfos_general_warmup', 'gameinfos_general_options'))): ?>
				<?php echo AdminServUI::getTemplate('gameinfos-general'); ?>
			<?php endif; ?>
			
			<?php if (SERVER_VERSION_NAME == 'ManiaPlanet' && AdminServ::checkDisplayTeamMode($data['gameInfos']['next']['GameMode'], $data['gameInfos']['next']['ScriptName']) && AdminServAdminLevel::hasPermission('gameinfos_teams_options')): ?>
				<fieldset class="gameinfos_teaminfos">
					<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/players.png" alt="" /><?php echo Utils::t('Team infos'); ?></legend>
					<table>
						<tr>
							<td class="key"><label for="teamInfo1Name"><?php echo Utils::t('Team 1'); ?></label></td>
							<td class="value">
								<input class="text width2" type="text" name="teamInfo1Name" id="teamInfo1Name" value="<?php echo $data['teamInfo']['team1']['name']; ?>" />
								<div class="colorSelectorWrapper">
									<div id="colorPickerTeam1" class="colorSelector" title="<?php echo Utils::t('Color'); ?>"></div>
									<input type="hidden" name="teamInfo1Color" id="teamInfo1Color" value="<?php echo $data['teamInfo']['team1']['color']; ?>" />
									<input type="hidden" name="teamInfo1ColorHex" id="teamInfo1ColorHex" value="<?php echo $data['teamInfo']['team1']['colorhex']; ?>" />
								</div>
							</td>
							<td class="value">
								<input class="text width2" type="text" name="teamInfo1Country" id="teamInfo1Country" value="<?php echo $data['teamInfo']['team1']['country']; ?>" />
							</td>
							<td class="preview"></td>
						</tr>
						<tr>
							<td class="key"><label for="teamInfo2Name"><?php echo Utils::t('Team 2'); ?></label></td>
							<td class="value">
								<input class="text width2" type="text" name="teamInfo2Name" id="teamInfo2Name" value="<?php echo $data['teamInfo']['team2']['name']; ?>" />
								<div class="colorSelectorWrapper">
									<div id="colorPickerTeam2" class="colorSelector" title="<?php echo Utils::t('Color'); ?>"></div>
									<input type="hidden" name="teamInfo2Color" id="teamInfo2Color" value="<?php echo $data['teamInfo']['team2']['color']; ?>" />
									<input type="hidden" name="teamInfo2ColorHex" id="teamInfo2ColorHex" value="<?php echo $data['teamInfo']['team2']['colorhex']; ?>" />
								</div>
							</td>
							<td class="value">
								<input class="text width2" type="text" name="teamInfo2Country" id="teamInfo2Country" value="<?php echo $data['teamInfo']['team2']['country']; ?>" />
							</td>
							<td class="preview"></td>
						</tr>
					</table>
				</fieldset>
			<?php endif; ?>
			
			<?php if (AdminServAdminLevel::hasPermission('gameinfos_gamemode_options')): ?>
				<?php echo AdminServUI::getTemplate('gameinfos-gamemode'); ?>
			<?php endif; ?>
		</div>
		
		<?php if (SERVER_MATCHSET && AdminServAdminLevel::hasPermission('maps_matchsettings_save')): ?>
			<div class="fleft options-checkbox">
				<input class="text inline" type="checkbox" name="SaveCurrentMatchSettings" id="SaveCurrentMatchSettings"<?php if (AdminServConfig::AUTOSAVE_MATCHSETTINGS === true): echo ' checked="checked"'; endif; ?> value="" /><label for="SaveCurrentMatchSettings" title="<?php echo SERVER_MATCHSET; ?>"><?php echo Utils::t('Save the current MatchSettings'); ?></label>
			</div>
		<?php endif; ?>
		<div class="fright save">
			<input class="button light" type="submit" name="savegameinfos" id="savegameinfos" value="<?php echo Utils::t('Save'); ?>" />
		</div>
	</form>
</section>
<section class="cadre left<?php if ($data['isTeamGameMode']): echo ' isTeamGameMode'; endif; ?>">
	<h1><?php echo Utils::t('Current map'); ?></h1>
	<form method="post" action=".">
	<div class="content">
		<table class="current_map">
			<tr>
				<td class="key"><?php echo Utils::t('Name'); ?></td>
				<td class="value" id="map_name"><?php echo $data['serverInfo']['map']['name']; ?></td>
			</tr>
			<tr>
				<td class="key"><?php echo Utils::t('Author'); ?></td>
				<td class="value" id="map_author"><?php echo $data['serverInfo']['map']['author']; ?></td>
			</tr>
			<tr>
				<td class="key"><?php echo Utils::t('Environment'); ?></td>
				<td class="value" id="map_enviro"><?php echo $data['serverInfo']['map']['enviro']; ?><img src="<?php echo AdminServConfig::$PATH_RESOURCES .'images/env/'.strtolower($data['serverInfo']['map']['enviro']); ?>.png" alt="" /></td>
			</tr>
			<tr>
				<td class="key"><?php echo Utils::t('Map UId'); ?></td>
				<td class="value" id="map_uid"><?php echo $data['serverInfo']['map']['uid']; ?></td>
			</tr>
			<tr>
				<td class="key"><?php echo Utils::t('Game mode'); ?></td>
				<td class="value <?php echo strtolower($data['serverInfo']['srv']['gameModeName']); ?>" id="map_gamemode">
					<?php if (isset($data['serverInfo']['srv']['gameModeScriptName'])): ?>
						<?php echo $data['serverInfo']['srv']['gameModeScriptName']; ?> <span class="scriptName">(<?php echo $data['serverInfo']['srv']['gameModeName']; ?>)</span>
					<?php else: ?>
						<?php echo $data['serverInfo']['srv']['gameModeName']; ?>
					<?php endif; ?>
				</td>
			</tr>
			<?php if ($data['serverInfo']['map']['callvote']['login'] && AdminServAdminLevel::hasPermission('cancel_vote')): ?>
				<tr>
					<td class="key"><?php echo Utils::t('Current vote'); ?></td>
					<td class="value" id="map_currentcallvote">
						<?php echo $data['serverInfo']['map']['callvote']['login'].' : '.$data['serverInfo']['map']['callvote']['cmdname'].' ('.$data['serverInfo']['map']['callvote']['cmdparam'].')'; ?>
						<input class="button light" type="submit" name="CancelVote" id="CancelVote" value="<?php echo Utils::t('Cancel vote'); ?>" />
					</td>
				</tr>
			<?php endif; ?>
			<?php if (AdminServ::isGameMode('Team', $data['serverInfo']['srv']['gameModeId']) && AdminServAdminLevel::hasPermission('force_scores')): ?>
				<tr>
					<td class="key"><?php echo Utils::t('Scores'); ?></td>
					<td class="value" id="map_teamscore">
						<span class="team_0" title="<?php echo Utils::t('Blue team'); ?>"></span>
						<input class="text" type="number" min="0" name="ScoreTeamBlue" id="ScoreTeamBlue" value="<?php echo $data['serverInfo']['map']['scores']['blue']; ?>" />
						<span class="team_1" title="<?php echo Utils::t('Red team'); ?>"></span>
						<input class="text" type="number" min="0" name="ScoreTeamRed" id="ScoreTeamRed" value="<?php echo $data['serverInfo']['map']['scores']['red']; ?>" />
						<input class="button light" type="submit" name="ForceScores" id="ForceScores" value="<?php echo Utils::t('Force the scores'); ?>" />
					</td>
				</tr>
			<?php endif; ?>
		</table>
		<?php if ($data['serverInfo']['map']['thumb'] != null): ?>
			<div id="map_thumbnail" data-text-thumbnail="<?php echo Utils::t('No thumbnail'); ?>">
				<img src="data:image/jpeg;base64,<?php echo $data['serverInfo']['map']['thumb']; ?>" alt="<?php echo Utils::t('No thumbnail'); ?>" />
			</div>
		<?php endif; ?>
	</div>
	</form>
	
	<h1><?php echo Utils::t('Server'); ?></h1>
	<div class="content">
		<table>
			<tr>
				<td class="key"><?php echo Utils::t('Server name'); ?></td>
				<td class="value" id="server_name"><?php echo $data['serverInfo']['srv']['name']; ?></td>
			</tr>
			<tr>
				<td class="key"><?php echo Utils::t('Status'); ?></td>
				<td class="value" id="server_status"><?php echo $data['serverInfo']['srv']['status']; ?></td>
			</tr>
			<tr>
				<td class="key"><?php echo Utils::t('Server login'); ?></td>
				<td class="value"><?php echo SERVER_LOGIN; ?></td>
			</tr>
			<tr>
				<td class="key"><?php echo Utils::t('Connected on'); ?></td>
				<td class="value" id="srv_version_name">
					<?php if (defined('IS_RELAY') && IS_RELAY && isset($data['mainServerLogin']) && $data['mainServerLogin'] !== null): ?>
						<?php echo $data['mainServerLogin']; ?> (<span class="<?php echo strtolower(SERVER_VERSION_NAME); ?>"><?php echo SERVER_VERSION_NAME; ?></span>)
					<?php else: ?>
						<span class="<?php echo strtolower(SERVER_VERSION_NAME); ?>"><?php echo SERVER_VERSION_NAME; ?></span>
					<?php endif; ?>
				</td>
			</tr>
			<tr>
				<td class="key"><?php echo Utils::t('Dedicated version'); ?></td>
				<td class="value"><?php echo SERVER_BUILD.' ('. SERVER_VERSION .')'; ?></td>
			</tr>
		</table>
	</div>
	
	<?php if (AdminServAdminLevel::isType('SuperAdmin')): ?>
		<h1><?php echo Utils::t('Statistics'); ?></h1>
		<div class="content last">
			<table>
				<tr>
					<td class="key"><?php echo Utils::t('Uptime'); ?></td>
					<td class="value" id="network_uptime"><?php echo $data['serverInfo']['net']['uptime']; ?></td>
				</tr>
				<tr>
					<td class="key"><?php echo Utils::t('Number of connections'); ?></td>
					<td class="value" id="network_nbrconnection"><?php echo $data['serverInfo']['net']['nbrconnection']; ?></td>
				</tr>
				<tr>
					<td class="key"><?php echo Utils::t('Average connection time'); ?></td>
					<td class="value" id="network_meanconnectiontime"><?php echo $data['serverInfo']['net']['meanconnectiontime']; ?></td>
				</tr>
				<tr>
					<td class="key"><?php echo Utils::t('Average number of players'); ?></td>
					<td class="value" id="network_meannbrplayer"><?php echo $data['serverInfo']['net']['meannbrplayer']; ?></td>
				</tr>
				<tr>
					<td class="key"><?php echo Utils::t('Recv net rate'); ?></td>
					<td class="value" id="network_recvnetrate"><?php echo $data['serverInfo']['net']['recvnetrate']; ?></td>
				</tr>
				<tr>
					<td class="key"><?php echo Utils::t('Send net rate'); ?></td>
					<td class="value" id="network_sendnetrate"><?php echo $data['serverInfo']['net']['sendnetrate']; ?></td>
				</tr>
				<tr>
					<td class="key"><?php echo Utils::t('Total receiving size'); ?></td>
					<td class="value" id="network_totalreceivingsize"><?php echo $data['serverInfo']['net']['totalreceivingsize']; ?></td>
				</tr>
				<tr>
					<td class="key"><?php echo Utils::t('Total sending size'); ?></td>
					<td class="value" id="network_totalsendingsize"><?php echo $data['serverInfo']['net']['totalsendingsize']; ?></td>
				</tr>
			</table>
		</div>
	<?php endif; ?>
</section>

<section class="cadre right<?php if ($data['isTeamGameMode']): echo ' isTeamGameMode'; endif; ?>">
	<h1><?php echo Utils::t('Players'); ?></h1>
	<div class="title-detail">
		<ul>
			<li><a id="detailMode" href="." data-statusmode="<?php echo USER_MODE_GENERAL; ?>" data-textdetail="<?php echo Utils::t('Detailed mode'); ?>" data-textsimple="<?php echo Utils::t('Simple mode'); ?>"><?php echo (USER_MODE_GENERAL == 'detail') ? Utils::t('Simple mode') : Utils::t('Detailed mode'); ?></a></li>
			<li class="last"><input type="checkbox" name="checkAll" id="checkAll" value=""<?php if (!is_array($data['serverInfo']['ply'])): echo ' disabled="disabled"'; endif; ?> /></li>
		</ul>
	</div>
	
	<!-- Liste des joueurs -->
	<form method="post" action=".">
	<div id="playerlist">
		<table>
			<thead>
				<tr>
					<?php if ($data['isTeamGameMode']): ?>
						<th class="detailModeTh thleft"<?php if (USER_MODE_GENERAL == 'simple'): echo ' hidden="hidden"'; endif; ?>><a href="?sort=team"><?php echo Utils::t('Team'); ?></a></th>
					<?php endif; ?>
					<th class="firstTh <?php if (USER_MODE_GENERAL == 'simple' || !$data['isTeamGameMode']): echo 'thleft'; endif; ?>"><a href="?sort=nickname"><?php echo Utils::t('Nickname'); ?></a></th>
					<?php if (!$data['isTeamGameMode']): ?>
						<th class="detailModeTh"<?php if (USER_MODE_GENERAL == 'simple'): echo ' hidden="hidden"'; endif; ?>><a href="?sort=ladder"><?php echo Utils::t('Ladder'); ?></a></th>
					<?php endif; ?>
					<th><a href="?sort=login"><?php echo Utils::t('Login'); ?></a></th>
					<th><a href="?sort=status"><?php echo Utils::t('Status'); ?></a></th>
					<th class="thright"></th>
				</tr>
			</thead>
			<tbody>
				<tr class="table-separation"><td colspan="<?php echo ($data['isTeamGameMode']) ? '6' : '5'; ?>"></td></tr>
				<?php if ($data['serverInfo']['nbp'] > 0): ?>
					<?php $i = 0; ?>
					<?php foreach ($data['serverInfo']['ply'] as $player): ?>
						<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
							<?php if ($data['isTeamGameMode'] && USER_MODE_GENERAL == 'detail'): ?>
								<td class="detailModeTd imgleft"><span class="team_<?php echo $player['TeamId']; ?>" title="<?php echo $player['TeamName']; ?>">&nbsp;</span><?php echo $player['TeamName']; ?></td>
							<?php endif; ?>
							<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/solo.png" alt="" /><?php echo $player['NickName']; ?></td>
							<?php if (!$data['isTeamGameMode']): ?>
								<td class="detailModeTd imgleft"<?php if (USER_MODE_GENERAL == 'simple'): ' hidden="hidden"'; endif; ?>><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/leagueladder.png" alt="" /><?php echo $player['LadderRanking']; ?></td>
							<?php endif; ?>
							<td><?php echo $player['Login']; ?></td>
							<td><?php echo $player['PlayerStatus']; ?></td>
							<td class="checkbox"><input type="checkbox" name="player[]" value="<?php echo $player['Login']; ?>" /></td>
						</tr>
						<?php $i++; ?>
					<?php endforeach; ?>
				<?php else: ?>
					<tr class="no-line">
						<td class="center" colspan="<?php echo ($data['isTeamGameMode']) ? '6' : '5'; ?>"><?php echo $data['serverInfo']['ply']; ?></td>
					</tr>
				<?php endif; ?>
			</tbody>
		</table>
	</div>
	
	<div class="options">
		<div class="fleft">
			<span class="nb-line"><?php echo $data['serverInfo']['nbp']; ?></span>
		</div>
		<div class="fright">
			<div class="selected-files-label locked">
				<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
				<span class="selected-files-count">(0)</span>
				<div class="selected-files-option">
					<?php if (AdminServAdminLevel::hasPermission('player_ignore')): ?>
						<input class="button dark" type="submit" name="IgnoreLoginList" id="IgnoreLoginList" value="<?php echo Utils::t('Ignore'); ?>" />
					<?php endif; ?>
					<?php if (AdminServAdminLevel::hasPermission('player_guest')): ?>
						<input class="button dark" type="submit" name="GuestLoginList" id="GuestLoginList" value="<?php echo Utils::t('Guest'); ?>" />
					<?php endif; ?>
					<?php if (AdminServAdminLevel::hasPermission('player_ban')): ?>
						<input class="button dark" type="submit" name="BanLoginList" id="BanLoginList" value="<?php echo Utils::t('Ban'); ?>" />
					<?php endif; ?>
					<?php if (AdminServAdminLevel::hasPermission('player_kick')): ?>
						<input class="button dark" type="submit" name="KickLoginList" id="KickLoginList" value="<?php echo Utils::t('Kick'); ?>" />
					<?php endif; ?>
					<?php if ($data['isTeamGameMode'] && AdminServAdminLevel::hasPermission('player_changeteam')): ?>
						<input class="button dark" type="submit" name="ForceBlueTeam" id="ForceBlueTeam" value="<?php echo Utils::t('Blue team'); ?>" />
						<input class="button dark" type="submit" name="ForceRedTeam" id="ForceRedTeam" value="<?php echo Utils::t('Red team'); ?>" />
					<?php endif; ?>
					<?php if (AdminServAdminLevel::hasPermission('player_forcetospectator')): ?>
						<input class="button dark" type="submit" name="ForceSpectatorList" id="ForceSpectatorList" value="<?php echo Utils::t('Spectator'); ?>" />
					<?php endif; ?>
					<?php if (AdminServAdminLevel::hasPermission('player_forcetoplayer')): ?>
						<input class="button dark" type="submit" name="ForcePlayerList" id="ForcePlayerList" value="<?php echo Utils::t('Player'); ?>" />
					<?php endif; ?>
				</div>
			</div>
		</div>
	</div>
	
	<input type="hidden" id="currentSort" name="currentSort" value="" />
	<input type="hidden" id="isTeamGameMode" name="isTeamGameMode" value="<?php echo $data['isTeamGameMode']; ?>" />
	</form>
</section>
<section class="cadre left">
	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
	<div id="banlist">
		<h1>Banlist<?php if ($data['banlist']['count'] > 0): ' ('.$data['banlist']['count'].')'; endif; ?></h1>
		<div class="title-detail">
			<ul>
				<li><a class="cleanList" href="?p=<?php echo USER_PAGE; ?>&amp;clean=banlist" data-empty="<?php echo Utils::t('The list is already empty.'); ?>"><?php echo Utils::t('Clean the list'); ?></a></li>
				<li class="last"><input type="checkbox" name="checkAllBanlist" id="checkAllBanlist" value=""<?php if ($data['banlist']['count'] == 0): echo ' disabled="disabled"'; endif; ?> /></li>
			</ul>
		</div>
		<table>
			<thead>
				<tr>
					<th class="thleft"><?php echo Utils::t('Login'); ?></th>
					<th><?php echo Utils::t('IP address'); ?></th>
					<th><?php echo Utils::t('Client'); ?></th>
					<th class="thright"></th>
				</tr>
			</thead>
			<tbody>
				<tr class="table-separation"><td colspan="4"></td></tr>
				<?php if ($data['banlist']['count'] > 0): ?>
					<?php $i = 0; ?>
					<?php foreach ($data['banlist']['list'] as $player): ?>
						<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
							<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/solo.png" alt="" /><?php echo $player['Login']; ?></td>
							<td><?php echo $player['IPAddress']; ?></td>
							<td><?php echo $player['ClientName']; ?></td>
							<td class="checkbox"><input type="checkbox" name="banlist[]" value="<?php echo $player['Login']; ?>" /></td>
						</tr>
						<?php $i++; ?>
					<?php endforeach; ?>
				<?php else: ?>
					<tr class="no-line">
						<td class="center" colspan="4"><?php echo Utils::t('No player'); ?></td>
					</tr>
				<?php endif; ?>
			</tbody>
		</table>
	</div>
	
	<div id="blacklist">
		<h1>Blacklist<?php if ($data['blacklist']['count'] > 0): echo ' ('.$data['blacklist']['count'].')'; endif; ?></h1>
		<div class="title-detail">
			<ul>
				<li><a class="cleanList" href="?p=<?php echo USER_PAGE; ?>&amp;clean=blacklist" data-empty="<?php echo Utils::t('The list is already empty.'); ?>"><?php echo Utils::t('Clean the list'); ?></a></li>
				<li class="last"><input type="checkbox" name="checkAllBlacklist" id="checkAllBlacklist" value=""<?php if ($data['blacklist']['count'] == 0): echo ' disabled="disabled"'; endif; ?> /></li>
			</ul>
		</div>
		<table>
			<thead>
				<tr>
					<th class="thleft"><?php echo Utils::t('Login'); ?></th>
					<th class="thright"></th>
				</tr>
			</thead>
			<tbody>
				<tr class="table-separation"><td colspan="2"></td></tr>
				<?php if ($data['blacklist']['count'] > 0): ?>
					<?php $i = 0; ?>
					<?php foreach ($data['blacklist']['list'] as $player): ?>
						<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
							<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/solo.png" alt="" /><?php echo $player['Login']; ?></td>
							<td class="checkbox"><input type="checkbox" name="blacklist[]" value="<?php echo $player['Login']; ?>" /></td>
						</tr>
						<?php $i++; ?>
					<?php endforeach; ?>
				<?php else: ?>
					<tr class="no-line">
						<td class="center" colspan="2"><?php echo Utils::t('No player'); ?></td>
					</tr>
				<?php endif; ?>
			</tbody>
		</table>
	</div>
	
	<div id="guestlist">
		<h1>Guestlist<?php if ($data['guestlist']['count'] > 0): echo ' ('.$data['guestlist']['count'].')'; endif; ?></h1>
		<div class="title-detail">
			<ul>
				<li><a class="cleanList" href="?p=<?php echo USER_PAGE; ?>&amp;clean=guestlist" data-empty="<?php echo Utils::t('The list is already empty.'); ?>"><?php echo Utils::t('Clean the list'); ?></a></li>
				<li class="last"><input type="checkbox" name="checkAllGuestlist" id="checkAllGuestlist" value=""<?php if ($data['guestlist']['count'] == 0): echo ' disabled="disabled"'; endif; ?> /></li>
			</ul>
		</div>
		<table>
			<thead>
				<tr>
					<th class="thleft"><?php echo Utils::t('Login'); ?></th>
					<th class="thright"></th>
				</tr>
			</thead>
			<tbody>
				<tr class="table-separation"><td colspan="2"></td></tr>
				<?php if ($data['guestlist']['count'] > 0): ?>
					<?php $i = 0; ?>
					<?php foreach ($data['guestlist']['list'] as $player): ?>
						<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
							<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/solo.png" alt="" /><?php echo $player['Login']; ?></td>
							<td class="checkbox"><input type="checkbox" name="guestlist[]" value="<?php echo $player['Login']; ?>" /></td>
						</tr>
						<?php $i++; ?>
					<?php endforeach; ?>
				<?php else: ?>
					<tr class="no-line">
						<td class="center" colspan="2"><?php echo Utils::t('No player'); ?></td>
					</tr>
				<?php endif; ?>
			</tbody>
		</table>
	</div>
	
	<div id="ignorelist">
		<h1>Ignorelist<?php if ($data['ignorelist']['count'] > 0): echo ' ('.$data['ignorelist']['count'].')'; endif; ?></h1>
		<div class="title-detail">
			<ul>
				<li><a class="cleanList" href="?p=<?php echo USER_PAGE; ?>&amp;clean=ignorelist" data-empty="<?php echo Utils::t('The list is already empty.'); ?>"><?php echo Utils::t('Clean the list'); ?></a></li>
				<li class="last"><input type="checkbox" name="checkAllIgnorelist" id="checkAllIgnorelist" value=""<?php if ($data['ignorelist']['count'] == 0): echo ' disabled="disabled"'; endif; ?> /></li>
			</ul>
		</div>
		<table>
			<thead>
				<tr>
					<th class="thleft"><?php echo Utils::t('Login'); ?></th>
					<th class="thright"></th>
				</tr>
			</thead>
			<tbody>
				<tr class="table-separation"><td colspan="2"></td></tr>
				<?php if ($data['ignorelist']['count'] > 0): ?>
					<?php $i = 0; ?>
					<?php foreach ($data['ignorelist']['list'] as $player): ?>
						<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
							<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/solo.png" alt="" /><?php echo $player['Login']; ?></td>
							<td class="checkbox"><input type="checkbox" name="ignorelist[]" value="<?php echo $player['Login']; ?>" /></td>
						</tr>
						<?php $i++; ?>
					<?php endforeach; ?>
				<?php else: ?>
					<tr class="no-line">
						<td class="center" colspan="2"><?php echo Utils::t('No player'); ?></td>
					</tr>
				<?php endif; ?>
			</tbody>
		</table>
	</div>
	
	<div class="options">
		<div class="fright">
			<div class="selected-files-label locked">
				<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
				<span class="selected-files-count">(0)</span>
				<div class="selected-files-option">
					<?php if (AdminServAdminLevel::hasPermission('guestban_addplayer')): ?>
						<input class="button dark" type="submit" name="blackListPlayer" id="blackListPlayer" value="<?php echo Utils::t('Blacklist'); ?>" />
					<?php endif; ?>
					<?php if (AdminServAdminLevel::hasPermission('guestban_removeplayer')): ?>
						<input class="button dark" type="submit" name="removeList" id="removeList" value="<?php echo Utils::t('Remove from the list'); ?>" />
					<?php endif; ?>
				</div>
			</div>
		</div>
	</div>
	</form>
</section>

<section class="cadre right">
	<?php if (AdminServAdminLevel::hasPermission('guestban_addplayer')): ?>
		<h1><?php echo Utils::t('Add'); ?></h1>
		<div class="content last addPlayer">
			<form method="post" action="?p=<?php echo USER_PAGE; ?>">
				<div>
					<select class="width2" name="addPlayerList" id="addPlayerList"<?php if ($data['players']['count'] == 0): echo ' hidden="hidden"'; endif; ?>>
						<option value="none"><?php echo Utils::t('Select a player'); ?></option>
						<?php echo $data['players']['listOptions']; ?>
						<option value="more"><?php echo Utils::t('Enter another login'); ?></option>
					</select>
					<input class="text width2" type="text" name="addPlayerLogin" id="addPlayerLogin" data-default-value="<?php echo Utils::t('Player login'); ?>" value="<?php echo Utils::t('Player login'); ?>"<?php if ($data['players']['count'] != 0): echo ' hidden="hidden"'; endif; ?> />
					<select class="addPlayerTypeList" name="addPlayerTypeList" id="addPlayerTypeList">
						<option value="none"><?php echo Utils::t('Add in the'); ?></option>
						<option value="guestlist">Guestlist</option>
						<option value="blacklist">Blacklist</option>
					</select>
					<input class="button light" type="submit" name="addPlayer" id="addPlayer" value="<?php echo Utils::t('Add'); ?>" />
				</div>
			</form>
		</div>
	<?php endif; ?>
	
	<?php if (isset($data['playlistDirectory']) && $data['playlistDirectory'] != 'Not directory'): ?>
		<div id="playlists">
			<form method="post" action="?p=<?php echo USER_PAGE; ?>">
				<h1>
					<?php echo Utils::t('Playlists'); ?>
					<?php if (AdminServAdminLevel::hasPermission('guestban_playlist_new')): ?>
						<span id="form-new-playlist" hidden="hidden">
							<select name="createPlaylistType" id="createPlaylistType">
								<option value="none"><?php echo Utils::t('Type'); ?></option>
								<option value="guestlist">Guestlist</option>
								<option value="blacklist">Blacklist</option>
							</select>
							<input class="text" type="text" name="createPlaylistName" id="createPlaylistName" data-playlistname="<?php echo Utils::t('Playlist name'); ?>" value="<?php echo Utils::t('Playlist name'); ?>" />
							<input class="button light" type="submit" name="createPlaylistValid" id="createPlaylistValid" value="<?php echo Utils::t('Create'); ?>" />
						</span>
					<?php endif; ?>
				</h1>
			</form>
			<div class="title-detail">
				<ul>
					<?php if (AdminServAdminLevel::hasPermission('guestban_playlist_new')): ?>
						<li><a id="clickNewPlaylist" href="" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-newplaylist="<?php echo Utils::t('New playlist'); ?>"><?php echo Utils::t('New playlist'); ?></a></li>
					<?php endif; ?>
					<li class="last"><input type="checkbox" name="checkAllPlaylists" id="checkAllPlaylists" value="" /></li>
				</ul>
			</div>
			
			<form method="post" action="?p=<?php echo USER_PAGE; ?>">
			<table>
				<thead>
					<tr>
						<th class="thleft"><?php echo Utils::t('Playlist'); ?></th>
						<th><?php echo Utils::t('Type'); ?></th>
						<th><?php echo Utils::t('Contains'); ?></th>
						<th><?php echo Utils::t('Modified'); ?></th>
						<th class="thright"></th>
					</tr>
				</thead>
				<tbody>
					<tr class="table-separation"><td colspan="5"></td></tr>
					<?php if (isset($data['playlistDirectory']['files']) && !empty($data['playlistDirectory']['files'])): ?>
						<?php
							$i = 0;
							$defaultFilename = array(
								'guestlist.txt',
								'blacklist.txt',
								'guestlist.xml',
								'blacklist.xml',
							);
						?>
						<?php foreach ($data['playlistDirectory']['files'] as $file): ?>
							<?php if (in_array($file['filename'], $defaultFilename) || ($isDoubleExt = in_array(File::getDoubleExtension($file['filename']), AdminServConfig::$PLAYLIST_EXTENSION))): ?>
								<?php
									// Playlist data
									$playlistData = AdminServ::getPlaylistData($data['gameDataDirectory'].'Config/'.$file['filename']);
									if( isset($playlistData['logins']) ){
										$countDataLogins = count($playlistData['logins']);
										$nbPlayers = ($countDataLogins > 1) ? $countDataLogins.' '.Utils::t('players') : '1 '.Utils::t('player');
									}
									else{
										$nbPlayers = '0 '.Utils::t('player');
									}
									
									// Filename
									$parseExtIndex = ($isDoubleExt) ? -13 : -4;
									$filename = substr($file['filename'], 0, $parseExtIndex);
								?>
								<tr class="<?php echo ($i%2) ? 'even' : 'odd'; ?>">
									<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/finishgrey.png" alt="" /><span title="<?php echo $file['filename']; ?>"><?php echo $filename; ?></span></td>
									<td class="center"><?php echo ucfirst($playlistData['type']); ?></td>
									<td class="center"><?php echo $nbPlayers; ?></td>
									<td class="center"><?php echo date('d-m-Y', $file['mtime']); ?></td>
									<td class="checkbox">
										<input type="checkbox" name="playlist[]" value="<?php echo $playlistData['type'].'|'.$file['filename']; ?>" />
									</td>
								</tr>
								<?php $i++; ?>
							<?php endif; ?>
						<?php endforeach; ?>
					<?php else: ?>
						<tr class="no-line">
							<td class="center" colspan="5"><?php echo Utils::t('No playlist'); ?></td>
						</tr>
					<?php endif; ?>
				</tbody>
			</table>
			
			<?php if (AdminServAdminLevel::hasPermission(array('guestban_playlist_save', 'guestban_playlist_load', 'guestban_playlist_delete'))): ?>
				<div class="options">
					<div class="fright">
						<div class="selected-files-label locked">
							<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
							<span class="selected-files-count">(0)</span>
							<div class="selected-files-option">
								<?php if (AdminServAdminLevel::hasPermission('guestban_playlist_delete')): ?>
									<input class="button dark" type="submit" name="deletePlaylist" id="deletePlaylist" value="<?php echo Utils::t('Delete'); ?>" />
								<?php endif; ?>
								<?php if (AdminServAdminLevel::hasPermission('guestban_playlist_load')): ?>
									<input class="button dark" type="submit" name="loadPlaylist" id="loadPlaylist" value="<?php echo Utils::t('Load'); ?>" />
								<?php endif; ?>
								<?php if (AdminServAdminLevel::hasPermission('guestban_playlist_save')): ?>
									<input class="button dark" type="submit" name="savePlaylist" id="savePlaylist" value="<?php echo Utils::t('Save '); ?>" />
								<?php endif; ?>
							</div>
						</div>
					</div>
				</div>
			<?php endif; ?>
			</form>
		</div>
	<?php endif; ?>
</section>
<!DOCTYPE html><html lang="<?php echo USER_LANG; ?>">	<head>		<meta charset="UTF-8" />		<meta name="robots" content="noindex, nofollow" />		<meta name="viewport" content="width=335, initial-scale=1.0">		<title><?php if (isset($GLOBALS['page_title'])): echo $GLOBALS['page_title'].' | '; endif; echo AdminServUI::getTitle(); ?></title>		<link type="image/png" rel="icon" href="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/32/favicon.png" sizes="32x32" />		<?php echo AdminServUI::getCss(); ?>		<?php echo AdminServUI::getJS(); ?>	</head>	<body<?php if( isset($GLOBALS['body_class']) ){ echo ' class="'.$GLOBALS['body_class'].'"'; } ?>>		<div id="page">			<div id="page-inner">				<header>					<div id="header-inner">						<div class="logo-title">							<a href="./">								<?php if (AdminServConfig::LOGO): ?>									<span id="logo">										<img src="<?php echo AdminServConfig::$PATH_RESOURCES .'images/'. AdminServConfig::LOGO; ?>" alt="" />									</span>								<?php endif; ?>																<span class="title-subtitle">									<span id="title">										#<?php echo AdminServUI::getTitle('html'); ?>									</span>																		<?php if (AdminServConfig::SUBTITLE): ?>										<span id="subtitle">											<?php echo AdminServConfig::SUBTITLE; ?>										</span>									<?php endif; ?>								</span>							</a>						</div>												<div class="theme-lang">							<?php if (!empty(ExtensionConfig::$THEMES)): ?>								<div id="theme">									<?php echo AdminServUI::getThemeList( (isset(ExtensionConfig::$THEMES[USER_THEME])) ? array(USER_THEME => ExtensionConfig::$THEMES[USER_THEME]) : array() ); ?>								</div>							<?php endif; ?>														<?php if (!empty(ExtensionConfig::$LANG)): ?>								<div id="lang">									<?php echo AdminServUI::getLangList( (isset(ExtensionConfig::$LANG[USER_LANG])) ? array(USER_LANG => ExtensionConfig::$LANG[USER_LANG]) : array() ); ?>								</div>							<?php endif; ?>						</div>												<?php if (AdminServEvent::isLoggedIn()): ?>							<?php if (AdminServAdminLevel::hasPermission('speed_admin')): ?>								<div class="speed-admin">									<ul>										<li><a tabindex="-1" class="prev" href=".">PrevMap</a></li>										<li><a tabindex="-1" class="restart" href=".">RestartMap</a></li>										<li><a tabindex="-1" class="next" href=".">NextMap</a></li>										<li><a tabindex="-1" class="endround" href=".">ForceEndRound</a></li>									</ul>								</div>							<?php endif; ?>														<?php if (AdminServAdminLevel::hasPermission('switch_server')): ?>								<div class="switch-server">									<select tabindex="1" id="switchServerList" name="switchServerList">										<?php echo AdminServUI::getServerList(); ?>									</select>								</div>							<?php endif; ?>						<?php endif; ?>												<div id="error"<?php if (!isset($_SESSION['error'])): echo ' hidden="hidden"'; endif; ?>><?php if (isset($_SESSION['error']) && $_SESSION['error'] != null): echo $_SESSION['error']; unset($_SESSION['error']); endif; ?></div>						<div id="info"<?php if (!isset($_SESSION['info'])): echo ' hidden="hidden"'; endif; ?>><?php if (isset($_SESSION['info']) && $_SESSION['info'] != null): echo $_SESSION['info']; unset($_SESSION['info']); endif; ?></div>					</div>					<div id="header-color-line"></div>				</header>								<?php if (AdminServEvent::isLoggedIn()): ?>					<nav class="horizontal-nav">						<div id="nav-inner" class="menu-principal">							<ul class="menu-left">								<li class="accessgeneral"><a tabindex="2" accesskey="1" class="button light<?php if (USER_PAGE == 'index'): echo ' active'; endif; ?>" href="./"><?php echo Utils::t('General'); ?></a></li>								<?php if (AdminServAdminLevel::hasAccess('server_options')): ?>									<li><a tabindex="3" class="button light<?php if (USER_PAGE == 'srvopts'): echo ' active'; endif; ?>" href="?p=srvopts"><?php echo Utils::t('Server options'); ?></a></li>								<?php endif; ?>								<?php if (AdminServAdminLevel::hasAccess('game_infos')): ?>									<li><a tabindex="4" class="button light<?php if (USER_PAGE == 'gameinfos'): echo ' active'; endif; ?>" href="?p=gameinfos"><?php echo Utils::t('Game infos'); ?></a></li>								<?php endif; ?>								<?php if (AdminServAdminLevel::hasAccess('chat')): ?>									<li><a tabindex="5" class="button light<?php if (USER_PAGE == 'chat'): echo ' active'; endif; ?>" href="?p=chat"><?php echo Utils::t('Chat'); ?></a></li>								<?php endif; ?>								<?php if (AdminServAdminLevel::hasAccess('maps_list')): ?>									<li><a tabindex="6" class="button light<?php if (AdminServUI::isPageType('maps')): echo ' active'; endif; ?>" href="?p=maps-list"><?php echo Utils::t('Maps'); ?></a></li>								<?php endif; ?>							</ul>														<ul class="menu-right">								<?php if (AdminServAdminLevel::hasAccess('link_access_server')): ?>									<?php if (defined('IS_RELAY') && IS_RELAY): ?>										<li class="accesslink"><a tabindex="7" class="button light" href="<?php echo AdminServ::getProtocolLink('#spectate='. SERVER_LOGIN); ?>"><?php echo Utils::t('Access relay'); ?></a></li>									<?php else: ?>										<li class="accesslink"><a tabindex="8" class="button light" href="<?php echo AdminServ::getProtocolLink('#join='. SERVER_LOGIN); ?>"><?php echo Utils::t('Access server'); ?></a></li>									<?php endif; ?>								<?php endif; ?>								<?php if (AdminServPlugin::hasPlugin() && AdminServAdminLevel::hasAccess('plugins_list')): ?>									<li><a tabindex="9" class="button light<?php if (USER_PAGE == 'plugins-list' || USER_PLUGIN): echo ' active'; endif; ?>" href="?p=plugins-list"><?php echo Utils::t('Plugins'); ?></a></li>								<?php endif; ?>								<?php if (AdminServAdminLevel::hasAccess('guest_ban')): ?>									<li><a tabindex="10" class="button light<?php if (USER_PAGE == 'guestban'): echo ' active'; endif; ?>" href="?p=guestban"><?php echo Utils::t('Guest-Ban'); ?></a></li>								<?php endif; ?>								<li><a tabindex="11" class="button light" href="?logout"><?php echo Utils::t('Disconnect'); ?></a></li>							</ul>						</div>					</nav>				<?php elseif (AdminServUI::isPageType('config')): ?>					<nav class="horizontal-nav">						<div id="nav-inner" class="menu-principal">							<ul class="menu-left">								<?php if (OnlineConfig::ADD_ONLY !== true): ?>									<li><a class="button light<?php if (USER_PAGE == 'config-servers'): echo ' active'; endif; ?>" href="?p=config-servers"><?php echo Utils::t('Servers'); ?></a></li>								<?php endif; ?>								<li><a class="button light<?php if (USER_PAGE == 'config-addserver'): echo ' active'; endif; ?>" href="?p=config-addserver<?php if (defined('IS_SERVER_EDITION')): echo '&id='.$args['id']; endif; ?>"><?php echo (defined('IS_SERVER_EDITION')) ? Utils::t('Edit server') : Utils::t('Add server'); ?></a></li>								<?php $hasServer = AdminServServerConfig::hasServer(); ?>								<?php if (OnlineConfig::ADD_ONLY !== true && $hasServer): ?>									<li><a class="button light<?php if (USER_PAGE == 'config-serversorder'): echo ' active'; endif; ?>" href="?p=config-serversorder"><?php echo Utils::t('Servers order'); ?></a></li>								<?php endif; ?>								<?php if (OnlineConfig::ADMINLEVEL): ?>									<li><a class="button light<?php if (USER_PAGE == 'config-adminlevel'): echo ' active'; endif; ?>" href="?p=config-adminlevel"><?php echo Utils::t('Admin levels'); ?></a></li>									<li><a class="button light<?php if (USER_PAGE == 'config-addlevel'): echo ' active'; endif; ?>" href="?p=config-addlevel<?php if (defined('IS_LEVEL_EDITION')): echo '&id='.$args['id']; endif; ?>"><?php echo (defined('IS_LEVEL_EDITION')) ? Utils::t('Edit level') : Utils::t('Add level'); ?></a></li>									<li><a class="button light<?php if (USER_PAGE == 'config-levelsorder'): echo ' active'; endif; ?>" href="?p=config-levelsorder"><?php echo Utils::t('Levels order'); ?></a></li>								<?php endif; ?>							</ul>							<ul class="menu-right">								<?php if (OnlineConfig::PASSWORD != null): ?>									<li><a class="button light<?php if (USER_PAGE == 'config-password'): echo ' active'; endif; ?>" href="?p=config-password"><?php echo Utils::t('Change password'); ?></a></li>								<?php endif; ?>								<?php if ($hasServer): ?>									<li><a class="button light" href="./?logout"><?php echo Utils::t('Back'); ?></a></li>								<?php endif; ?>							</ul>						</div>					</nav>				<?php elseif (!isset($_SESSION['adminserv']['check_password']) && !isset($_SESSION['adminserv']['get_password'])): ?>					<nav id="connection">						<div id="connection-inner">							<form method="post" action=".">								<div class="connection-label">									<label for="as_server"><?php echo Utils::t('Server'); ?> :</label>									<select tabindex="1" name="as_server" id="as_server">										<?php echo AdminServUI::getServerList(); ?>									</select>																		<label for="as_password"><?php echo Utils::t('Password'); ?> :</label>									<input tabindex="2" class="text" type="password" name="as_password" id="as_password" value="" />																		<label for="as_adminlevel"><?php echo Utils::t('Admin level'); ?> :</label>									<select tabindex="3" name="as_adminlevel" id="as_adminlevel" data-error="<?php echo Utils::t('No server admin levels configured.'); ?>"></select>								</div>								<div class="connection-login">									<input tabindex="4" class="button light" type="submit" name="as_login" id="as_login" value="<?php echo Utils::t('Connection'); ?>" />								</div>							</form>						</div>					</nav>				<?php endif; ?>								<div id="content">					<div id="content-inner">
<section class="maps hasMenu hasFolders">
	<section class="cadre left menu">
		<?php echo AdminServUI::getMapsMenuList(); ?>
	</section>
	
	<section class="cadre middle folders">
		<?php echo AdminServUI::getMapsDirectoryList($data['currentDir'], $args['directory']); ?>
	</section>
	
	<form method="post" action="?p=<?php echo USER_PAGE.$data['hasDirectory']; ?>">
	<section class="cadre right creatematchset">
		<h1><?php echo $data['pageTitle'].' '.Utils::t('a MatchSettings'); ?></h1>
		<div class="title-detail">
			<ul>
				<li class="last path"><?php echo $data['mapsDirectoryPath'].$args['directory']; ?></li>
			</ul>
		</div>
		
		<h2><?php echo Utils::t('MatchSettings name'); ?></h2>
		<input class="text" type="text" name="matchSettingName" id="matchSettingName" value="<?php echo $data['matchSettings']['name']; ?>" />
		<p class="ui-state-error" id="matchSettingNameExists" hidden="hidden"><span class="ui-icon ui-icon-alert"></span><?php echo Utils::t('The MatchSettings name already exist! It will be overwritten.'); ?></p>
		
		<h2><?php echo Utils::t('Maps'); ?></h2>
		<div class="content maps">
			<fieldset>
				<div class="mapsSelection">
					<select name="mapsDirectoryList" id="mapsDirectoryList">
						<option value="currentServerSelection"><?php echo Utils::t('Server selection'); ?></option>
						<option value="<?php echo $data['mapsDirectoryPath']; ?>"><?php echo Utils::t('Root'); ?></option>
						<?php if (!empty($data['directoryList'])): ?>
							<?php foreach ($data['directoryList'] as $dir): ?>
								<option value="<?php echo $dir['path']; ?>"><?php echo $dir['level'].$dir['name']; ?></option>
							<?php endforeach; ?>
						<?php endif; ?>
					</select>
					<input class="button light" type="button" name="mapImportSelection" id="mapImportSelection" value="<?php echo Utils::t('Make selection'); ?>" />
					<input class="button light" type="button" name="mapImport" id="mapImport" value="<?php echo Utils::t('Import all folder'); ?>" />
					<div id="mapImportSelectionDialog" data-title="<?php echo Utils::t('Make selection'); ?>" data-select="<?php echo Utils::t('Select'); ?>" hidden="hidden">
						<table>
							<thead>
								<tr>
									<th class="thleft"><?php echo Utils::t('Map'); ?></th>
									<th><?php echo Utils::t('Environment'); ?></th>
									<th><?php echo Utils::t('Type'); ?></th>
									<th><?php echo Utils::t('Author'); ?></th>
									<th class="thright"><input type="checkbox" name="checkAllMapImport" id="checkAllMapImport" value="" /></th>
								</tr>
							</thead>
							<tbody>
							</tbody>
						</table>
					</div>
				</div>
				
				<div class="mapsSelected">
					<p><?php echo Utils::t('MatchSettings selected maps:'); ?> <span id="nbMapSelected"><?php echo $data['matchSettings']['nbm']; ?></span></p>
					<input class="button light" type="button" name="mapSelection" id="mapSelection" value="<?php echo Utils::t('View the MatchSettings selection'); ?>" />
					<div id="mapSelectionDialog" data-title="<?php echo Utils::t('MatchSettings selection'); ?>" data-remove="<?php echo Utils::t('Remove map from the selection'); ?>" data-close="<?php echo Utils::t('Close'); ?>" hidden="hidden">
						<table>
							<thead>
								<tr>
									<th class="thleft"><?php echo Utils::t('Map'); ?></th>
									<th><?php echo Utils::t('Environment'); ?></th>
									<th><?php echo Utils::t('Type'); ?></th>
									<th><?php echo Utils::t('Author'); ?></th>
									<th class="thright"></th>
								</tr>
							</thead>
							<tbody>
							</tbody>
						</table>
					</div>
				</div>
			</fieldset>
		</div>
		
		<h2><?php echo Utils::t('Game information'); ?></h2>
		<div class="content gameinfos">
			<?php echo AdminServUI::getTemplate('gameinfos-general'); ?>
			<?php echo AdminServUI::getTemplate('gameinfos-gamemode'); ?>
		</div>
		
		<h2><?php echo Utils::t('HotSeat'); ?></h2>
		<div class="content">
			<fieldset>
				<table>
					<tr>
						<td class="key"><label for="hotSeatGameMode"><?php echo Utils::t('Game mode'); ?></label></td>
						<td class="value">
							<select class="width2" name="hotSeatGameMode" id="hotSeatGameMode">
								<?php echo AdminServUI::getGameModeList($data['matchSettings']['hotseat']['GameMode']); ?>
							</select>
						</td>
						<td class="preview"></td>
					</tr>
					<tr>
						<td class="key"><label for="hotSeatTimeLimit"><?php echo Utils::t('Time limit'); ?></label></td>
						<td class="value">
							<input class="text width2" type="number" min="0" name="hotSeatTimeLimit" id="hotSeatTimeLimit" value="<?php echo TimeDate::millisecToSec($data['matchSettings']['hotseat']['TimeLimit']); ?>" />
						</td>
						<td class="preview"></td>
					</tr>
					<tr>
						<td class="key"><label for="hotSeatCountRound"><?php echo Utils::t('Rounds count'); ?></label></td>
						<td class="value">
							<input class="text width2" type="number" min="0" name="hotSeatCountRound" id="hotSeatCountRound" value="<?php echo $data['matchSettings']['hotseat']['RoundsCount']; ?>" />
						</td>
						<td class="preview"></td>
					</tr>
				</table>
			</fieldset>
		</div>
		
		<h2><?php echo Utils::t('Filter'); ?></h2>
		<div class="content">
			<fieldset>
				<table>
					<tr>
						<td class="key"><label for="filterIsLan"><?php echo Utils::t('Lan'); ?></label></td>
						<td class="value">
							<input class="text" type="checkbox" name="filterIsLan" id="filterIsLan"<?php if ($data['matchSettings']['filter']['IsLan']): echo ' checked="checked"'; endif; ?> value="" />
						</td>
						<td class="preview"></td>
					</tr>
					<tr>
						<td class="key"><label for="filterIsInternet"><?php echo Utils::t('Internet'); ?></label></td>
						<td class="value">
							<input class="text" type="checkbox" name="filterIsInternet" id="filterIsInternet"<?php if ($data['matchSettings']['filter']['IsInternet']): echo ' checked="checked"'; endif; ?> value="" />
						</td>
						<td class="preview"></td>
					</tr>
					<tr>
						<td class="key"><label for="filterIsSolo"><?php echo Utils::t('Solo'); ?></label></td>
						<td class="value">
							<input class="text" type="checkbox" name="filterIsSolo" id="filterIsSolo"<?php if ($data['matchSettings']['filter']['IsSolo']): echo ' checked="checked"'; endif; ?> value="" />
						</td>
						<td class="preview"></td>
					</tr>
					<tr>
						<td class="key"><label for="filterIsHotSeat"><?php echo Utils::t('HotSeat'); ?></label></td>
						<td class="value">
							<input class="text" type="checkbox" name="filterIsHotSeat" id="filterIsHotSeat"<?php if ($data['matchSettings']['filter']['IsHotseat']): echo ' checked="checked"'; endif; ?> value="" />
						</td>
						<td class="preview"></td>
					</tr>
					<tr>
						<td class="key"><label for="filterSortIndex"><?php echo Utils::t('Sort index'); ?></label></td>
						<td class="value">
							<input class="text width2" type="number" min="0" name="filterSortIndex" id="filterSortIndex" value="<?php echo $data['matchSettings']['filter']['SortIndex']; ?>" />
						</td>
						<td class="preview"></td>
					</tr>
					<tr>
						<td class="key"><label for="filterRandomMaps"><?php echo Utils::t('Random map order'); ?></label></td>
						<td class="value">
							<input class="text" type="checkbox" name="filterRandomMaps" id="filterRandomMaps"<?php if ($data['matchSettings']['filter']['RandomMapOrder']): echo ' checked="checked"'; endif; ?> value="" />
						</td>
						<td class="preview"></td>
					</tr>
					<tr>
						<td class="key"><label for="filterDefaultGameMode"><?php echo Utils::t('Default game mode'); ?></label></td>
						<td class="value">
							<select class="width2" name="filterDefaultGameMode" id="filterDefaultGameMode">
								<?php echo AdminServUI::getGameModeList($data['matchSettings']['filter']['ForceDefaultGameMode']); ?>
							</select>
						</td>
						<td class="preview"></td>
					</tr>
				</table>
			</fieldset>
		</div>
		
		<div class="fright save">
			<input class="button light" type="submit" name="savematchsetting" id="savematchsetting" data-nomap="<?php echo Utils::t('No map selected for the MatchSettings.'); ?>" value="<?php echo Utils::t('Save'); ?>" />
		</div>
	</section>
	</form>
</section>
<!-- Titre + nouveau dossier -->
<form id="createFolderForm" method="post" action="?p=<?php echo USER_PAGE; ?>&amp;d=<?php echo $data['currentPath']; ?>">
	<h1>
		<?php echo Utils::t('Dossiers'); ?>
		<?php if ($data['showOptions'] && AdminServAdminLevel::hasPermission('folder_new')): ?>
			<span id="form-new-folder" hidden="hidden">
				<input class="text" type="text" name="newFolderName" id="newFolderName" value="" />
				<input class="button light" type="submit" name="newFolderValid" id="newFolderValid" value="ok" />
			</span>
		<?php endif; ?>
	</h1>
	<?php if ($data['showOptions'] && AdminServAdminLevel::hasPermission('folder_new')): ?>
		<div class="title-detail"><a href="." id="newfolder" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-new="<?php echo Utils::t('New'); ?>"><?php echo Utils::t('New'); ?></a></div>
	<?php endif; ?>
</form>

<!-- Liste des dossiers -->
<div class="folder-list">
	<ul>
		<!-- Dossier parent  -->
		<?php if ($data['currentPath']): ?>
			<li>
				<a href="./?p=<?php echo USER_PAGE.(($data['parentPath']) ? '&amp;d='.$data['parentPath'] : ''); ?>">
					<img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/back.png" alt="" />
					<span class="dir-name"><?php echo Utils::t('Parent folder'); ?></span>
				</a>
			</li>
		<?php endif; ?>
		
		<!-- Dossiers -->
		<?php if (!empty($data['folders'])): ?>
			<?php foreach ($data['folders'] as $dir => $values): ?>
				<li>
					<a href="./?p=<?php echo USER_PAGE; ?>&amp;d=<?php echo urlencode($data['currentPath'].$dir); ?>/">
						<span class="dir-name"><?php echo $dir; ?></span>
						<span class="dir-info"><?php echo $values['nb_file']; ?></span>
					</a>
				</li>
			<?php endforeach; ?>
		<?php else: ?>
			<li class="no-result"><?php echo Utils::t('No folder'); ?></li>
		<?php endif; ?>
	</ul>
</div>

<!-- Options de dossier -->
<?php if ($data['showOptions'] && $data['currentPath'] && AdminServAdminLevel::hasPermission(array('folder_new', 'folder_rename', 'folder_move', 'folder_delete'))): ?>
	<?php $currentDir = basename($data['currentPath']); ?>
	<form id="optionFolderForm" method="post" action="?p=<?php echo USER_PAGE; ?>&amp;d=<?php echo $data['currentPath']; ?>">
		<div class="option-folder-list">
			<h3><?php echo Utils::t('Folder options'); ?><span class="arrow-down">&nbsp;</span></h3>
			<ul hidden="hidden">
				<?php if (AdminServAdminLevel::hasPermission('folder_rename')): ?>
					<li><a class="button light rename" id="renameFolder" href="."><?php echo Utils::t('Rename'); ?></a></li>
				<?php endif; ?>
				<?php if (AdminServAdminLevel::hasPermission('folder_move')): ?>
					<li><a class="button light move" id="moveFolder" href="."><?php echo Utils::t('Move'); ?></a></li>
				<?php endif; ?>
				<?php if (AdminServAdminLevel::hasPermission('folder_delete')): ?>
					<li><a class="button light delete" id="deleteFolder" href="." data-confirm-text="<?php echo Utils::t('Do you really want to remove this folder !currentDir?', array('!currentDir' => $currentDir)); ?>>"><?php echo Utils::t('Delete'); ?></a></li>
				<?php endif; ?>
			</ul>
		</div>
		<input type="hidden" name="optionFolderHiddenFieldAction" id="optionFolderHiddenFieldAction" value="" />
		<input type="hidden" name="optionFolderHiddenFieldValue" id="optionFolderHiddenFieldValue" value="" />
		<div id="renameFolderForm" class="option-form" hidden="hidden" data-title="<?php echo Utils::t('Rename folder'); ?>" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-rename="<?php echo Utils::t('Rename'); ?>">
			<ul>
				<li>
					<span class="rename-map-name"><?php echo $currentDir; ?></span>
					<span class="rename-map-arrow">&nbsp;</span>
					<input class="text width2" type="text" name="renameFolderNewName" id="renameFolderNewName" value="<?php echo $currentDir; ?>" />
				</li>
			</ul>
		</div>
		<div id="moveFolderForm" class="option-form" hidden="hidden" data-title="<?php echo Utils::t('Move folder'); ?>" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-move="<?php echo Utils::t('Move'); ?>" data-root="<?php echo Utils::t('Root'); ?>" data-movethefolder="<?php echo Utils::t('Move folder <b>!currentDir</b> in:', array('!currentDir' => $currentDir)); ?>"></div>
	</form>
<?php endif; ?>
<section class="maps hasMenu">
	<section class="cadre left menu">
		<?php echo AdminServUI::getMapsMenuList(); ?>
	</section>
	
	<section class="cadre right list">
		<h1><?php echo Utils::t('List'); ?></h1>
		<div class="title-detail">
			<ul>
				<?php if ($data['maps']['nbm']['count'] > 25): ?>
					<li><a id="scrollToCurrentMap" href="#currentMap"><?php echo Utils::t('Go to the current map'); ?></a></li>
				<?php endif; ?>
				<li><a id="detailMode" href="." data-statusmode="<?php echo USER_MODE_MAPS; ?>" data-textdetail="<?php echo Utils::t('Detailed mode'); ?>" data-textsimple="<?php echo Utils::t('Simple mode'); ?>"><?php echo (USER_MODE_MAPS == 'detail') ? Utils::t('Simple mode') : Utils::t('Detailed mode'); ?></a></li>
				<li class="last"><input type="checkbox" name="checkAll" id="checkAll" value=""<?php if (!is_array($data['maps']['lst'])): echo ' disabled="disabled"'; endif; ?> /></li>
			</ul>
		</div>
		
		<form method="post" action="?p=<?php echo USER_PAGE; ?>">
		<div id="maplist">
			<table>
				<thead>
					<tr>
						<th class="thleft"><?php echo Utils::t('Map'); ?></th>
						<th><?php echo Utils::t('Environment'); ?></th>
						<th><?php echo Utils::t('Author'); ?></th>
						<th class="detailModeTh"<?php if (USER_MODE_MAPS == 'simple'): echo ' hidden="hidden"'; endif; ?>><?php echo Utils::t('Gold time'); ?></th>
						<th class="detailModeTh"<?php if (USER_MODE_MAPS == 'simple'): echo ' hidden="hidden"'; endif; ?>><?php echo Utils::t('Cost'); ?></th>
						<th class="thright"></th>
					</tr>
				</thead>
				<tbody>
					<tr class="table-separation"><td colspan="6"></td></tr>
					<?php if ($data['maps']['nbm']['count'] > 0 ): ?>
						<?php $i = 0;  ?>
						<?php foreach ($data['maps']['lst'] as $id => $map): ?>
							<tr<?php if ($id == $data['maps']['cid']): echo ' id="currentMap"'; endif; ?> class="<?php echo ($i%2) ? 'even' : 'odd'; if ($id == $data['maps']['cid']): echo ' current'; endif; ?>">
								<td class="imgleft">
									<img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/map.png" alt="" />
									<span title="<?php echo $map['FileName']; ?>"><?php echo $map['Name']; ?></span>
									<?php if (USER_MODE_MAPS == 'detail'): ?>
										<span class="detailModeTd"><?php echo $map['UId']; ?></span>
									<?php endif; ?>
								</td>
								<td class="imgcenter"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/env/<?php echo strtolower($map['Environment']); ?>.png" alt="" /><?php echo $map['Environment']; ?></td>
								<td><?php echo $map['Author']; ?></td>
								<td<?php if (USER_MODE_MAPS == 'simple'): echo ' hidden="hidden"'; endif; ?>><?php echo $map['GoldTime']; ?></td>
								<td<?php if (USER_MODE_MAPS == 'simple'): echo ' hidden="hidden"'; endif; ?>><?php echo $map['CopperPrice']; ?></td>
								<td class="checkbox">
									<?php if ($id != $data['maps']['cid']): ?>
										<input type="checkbox" name="map[]" value="<?php echo $map['FileName']; ?>" />
									<?php endif; ?>
								</td>
							</tr>
							<?php $i++; ?>
						<?php endforeach; ?>
					<?php else: ?>
						<tr class="no-line">
							<td class="center" colspan="6"><?php echo $data['maps']['lst']; ?></td>
						</tr>
					<?php endif; ?>
				</tbody>
			</table>
		</div>
		
		<div class="options">
			<div class="fleft">
				<span class="nb-line"><?php echo $data['maps']['nbm']['count'].' '.$data['maps']['nbm']['title']; ?></span>
			</div>
			<?php if (AdminServAdminLevel::hasPermission(array('maps_list_moveaftercurrent', 'maps_list_removetolist'))): ?>
				<div class="fright">
					<div class="selected-files-label locked">
						<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
						<span class="selected-files-count">(0)</span>
						<div class="selected-files-option">
							<?php if (AdminServAdminLevel::hasPermission('maps_list_removetolist')): ?>
								<input class="button dark" type="submit" name="removeMap" id="removeMap" value="<?php echo Utils::t('Delete'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_list_moveaftercurrent')): ?>
								<input class="button dark" type="submit" name="chooseNextMap" id="chooseNextMap" value="<?php echo Utils::t('Move after the current map'); ?>" />
							<?php endif; ?>
						</div>
					</div>
				</div>
			<?php endif; ?>
		</div>
		
		<input type="hidden" id="currentSort" name="currentSort" value="" />
		</form>
	</section>
</section>
<section class="maps hasMenu hasFolders">
	<section class="cadre left menu">
		<?php echo AdminServUI::getMapsMenuList(); ?>
	</section>
	
	<section class="cadre middle folders">
		<?php echo AdminServUI::getMapsDirectoryList($data['currentDir'], $args['directory']); ?>
	</section>
	
	<section class="cadre right local">
		<h1><?php echo Utils::t('Local'); ?></h1>
		<div class="title-detail">
			<ul>
				<li><div class="path"><?php echo $data['mapsDirectoryPath'].$args['directory']; ?></div></li>
				<li class="last"><input type="checkbox" name="checkAll" id="checkAll" value=""<?php if (!is_array($data['maps']['lst'])): echo ' disabled="disabled"'; endif; ?> /></li>
			</ul>
		</div>
		
		<form method="post" action="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>">
		<div id="maplist">
			<table>
				<thead>
					<tr>
						<th class="thleft"><a href="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>&amp;sort=name"><?php echo Utils::t('Map'); ?></a></th>
						<th><a href="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>&amp;sort=env"><?php echo Utils::t('Environment'); ?></a></th>
						<th><a href="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>&amp;sort=type"><?php echo Utils::t('Type'); ?></a></th>
						<th><a href="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>&amp;sort=author"><?php echo Utils::t('Author'); ?></a></th>
						<th class="thright"></th>
					</tr>
				</thead>
				<tbody>
					<tr class="table-separation"><td colspan="4"></td></tr>
					<?php if ($data['maps']['nbm']['count'] > 0): ?>
						<?php $i = 0; ?>
						<?php foreach ($data['maps']['lst'] as $id => $map): ?>
							<?php
								// Map sur le serveur
								if($map['OnServer']){
									$mapImg = 'loadmap';
									$mapClass = ' onserver';
								}
								else{
									$mapImg = 'map';
									$mapClass = null;
								}
								// Map récente
								if($map['Recent']){
									$mapClass .= ' recent';
								}
							?>
							<tr class="<?php echo ($i%2) ? 'even' : 'odd'; echo $mapClass; ?>">
								<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/<?php echo $mapImg; ?>.png" alt="" /><span title="<?php echo $map['FileName']; ?>"><?php echo $map['Name']; ?></span></td>
								<td class="imgcenter"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/env/<?php echo strtolower($map['Environment']); ?>.png" alt="" /><?php echo $map['Environment']; ?></td>
								<td><span title="<?php echo $map['Type']['FullName']; ?>"><?php echo $map['Type']['Name']; ?></span></td>
								<td><?php echo $map['Author']; ?></td>
								<td class="checkbox"><input type="checkbox" name="map[]" value="<?php echo $map['FileName']; ?>" /></td>
							</tr>
							<?php $i++; ?>
						<?php endforeach; ?>
					<?php else: ?>
						<tr class="no-line">
							<td class="center" colspan="4">
								<?php if (is_array($data['maps'])): ?>
									<?php echo $data['maps']['lst']; ?>
								<?php else: ?>
									<?php echo $data['maps']; ?>
								<?php endif; ?>
							</td>
						</tr>
					<?php endif; ?>
				</tbody>
			</table>
		</div>
		
		<div class="options" data-mapisused="<?php echo Utils::t('The map,is currently used by the server.'); ?>">
			<div class="fleft">
				<span class="nb-line"><?php if (is_array($data['maps'])): echo $data['maps']['nbm']['count'].' '.$data['maps']['nbm']['title']; endif; ?></span>
			</div>
			<?php if (AdminServAdminLevel::hasPermission(array('maps_local_add', 'maps_local_insert', 'maps_local_download', 'maps_local_rename', 'maps_local_move', 'maps_local_delete'))): ?>
				<div class="fright">
					<div class="selected-files-label locked">
						<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
						<span class="selected-files-count">(0)</span>
						<div class="selected-files-option">
							<?php if (AdminServAdminLevel::hasPermission('maps_local_delete')): ?>
								<input class="button dark" type="submit" name="deleteMap" id="deleteMap" value="<?php echo Utils::t('Delete'); ?>" data-confirm="<?php echo Utils::t('Do you really want to remove this selection?'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_local_move')): ?>
								<input class="button dark" type="button" name="moveMap" id="moveMap" value="<?php echo Utils::t('Move'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_local_rename')): ?>
								<input class="button dark" type="button" name="renameMap" id="renameMap" value="<?php echo Utils::t('Rename'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_local_download')): ?>
								<input class="button dark" type="submit" name="downloadMap" id="downloadMap" value="<?php echo Utils::t('Download'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_local_insert')): ?>
								<input class="button dark" type="submit" name="insertMap" id="insertMap" value="<?php echo Utils::t('Insert'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_local_add')): ?>
								<input class="button dark" type="submit" name="addMap" id="addMap" value="<?php echo Utils::t('Add'); ?>" />
							<?php endif; ?>
						</div>
					</div>
				</div>
			<?php endif; ?>
			<?php if (AdminServAdminLevel::hasPermission('maps_local_rename')): ?>
				<div id="form-rename-map" class="option-form" hidden="hidden" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-rename="<?php echo Utils::t('Rename'); ?>" data-autorename="<?php echo Utils::t('Replace the special characters'); ?>"></div>
			<?php endif; ?>
			<?php if (AdminServAdminLevel::hasPermission('maps_local_move')): ?>
				<div id="form-move-map" class="option-form" hidden="hidden" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-move="<?php echo Utils::t('Move'); ?>" data-inthefolder="<?php echo Utils::t('in the folder:'); ?>" data-root="<?php echo Utils::t('Root'); ?>"></div>
			<?php endif; ?>
		</div>
		<?php if (SERVER_MATCHSET && AdminServAdminLevel::hasPermission('maps_matchsettings_save')): ?>
			<div class="fleft options-checkbox">
				<input class="text inline" type="checkbox" name="SaveCurrentMatchSettings" id="SaveCurrentMatchSettings"<?php if (AdminServConfig::AUTOSAVE_MATCHSETTINGS === true): echo ' checked="checked"'; endif; ?> value="" /><label for="SaveCurrentMatchSettings" title="<?php echo SERVER_MATCHSET; ?>"><?php echo Utils::t('Save the current MatchSettings'); ?></label>
			</div>
		<?php endif; ?>
		</form>
	</section>
</section>
<section class="maps hasMenu hasFolders">
	<section class="cadre left menu">
		<?php echo AdminServUI::getMapsMenuList(); ?>
	</section>
	
	<section class="cadre middle folders">
		<?php echo AdminServUI::getMapsDirectoryList($data['currentDir'], $args['directory']); ?>
	</section>
	
	<section class="cadre right matchset">
		<h1><?php echo Utils::t('MatchSettings'); ?></h1>
		<div class="title-detail">
			<ul>
				<li class="path"><?php echo $data['mapsDirectoryPath'].$args['directory']; ?></li>
				<li class="last"><input type="checkbox" name="checkAll" id="checkAll" value="" /></li>
			</ul>
		</div>
		
		<form method="post" action="?p=<?php echo USER_PAGE; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>">
		<div id="matchsetlist">
			<table>
				<thead>
					<tr>
						<th class="thleft"><a href="?sort=name"><?php echo Utils::t('Name'); ?></a></th>
						<th><a href="?sort=nbm"><?php echo Utils::t('Contains'); ?></a></th>
						<th><a href="?sort=mtime"><?php echo Utils::t('Modified'); ?></a></th>
						<th class="thright"></th>
					</tr>
				</thead>
				<tbody>
					<tr class="table-separation"><td colspan="4"></td></tr>
					<?php if ($data['matchsettingsList']['nbm']['count'] > 0): ?>
						<?php $i = 0; ?>
						<?php foreach ($data['matchsettingsList']['lst'] as $id => $matchset): ?>
							<tr class="<?php echo ($i%2) ? 'even' : 'odd'; if ($matchset['Recent']): echo ' recent'; endif; ?>">
								<td class="imgleft"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/finishgrey.png" alt="" /><span title="<?php echo $matchset['FileName']; ?>"><?php echo $matchset['Name']; ?></span></td>
								<td><?php echo $matchset['Nbm']; ?></td>
								<td><?php echo date('d/m/Y', $matchset['Mtime']); ?></td>
								<td class="checkbox"><input type="checkbox" name="matchset[]" value="<?php echo $matchset['FileName']; ?>" /></td>
							</tr>
							<?php $i++; ?>
						<?php endforeach; ?>
					<?php else: ?>
						<tr class="no-line">
							<td class="center" colspan="4"><?php echo $data['matchsettingsList']['lst']; ?></td>
						</tr>
					<?php endif; ?>
				</tbody>
			</table>
		</div>
		
		<div class="options">
			<div class="fleft">
				<span class="nb-line"><?php if (is_array($data['matchsettingsList']['nbm'])): echo $data['matchsettingsList']['nbm']['count'].' '.$data['matchsettingsList']['nbm']['title']; endif; ?></span>
			</div>
			<?php if (AdminServAdminLevel::hasPermission(array('maps_matchsettings_save', 'maps_matchsettings_load', 'maps_matchsettings_add', 'maps_matchsettings_insert', 'maps_matchsettings_edit', 'maps_matchsettings_delete'))): ?>
				<div class="fright">
					<div class="selected-files-label locked">
						<span class="selected-files-title"><?php echo Utils::t('For the selection'); ?></span>
						<span class="selected-files-count">(0)</span>
						<div class="selected-files-option">
							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_delete')): ?>
								<input class="button dark" type="submit" name="deleteMatchset" id="deleteMatchset" value="<?php echo Utils::t('Delete'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_edit')): ?>
								<input class="button dark" type="submit" name="editMatchset" id="editMatchset" value="<?php echo Utils::t('Edit'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_insert')): ?>
								<input class="button dark" type="submit" name="insertMatchset" id="insertMatchset" value="<?php echo Utils::t('Insert'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_add')): ?>
								<input class="button dark" type="submit" name="addMatchset" id="addMatchset" value="<?php echo Utils::t('Add'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_load')): ?>
								<input class="button dark" type="submit" name="loadMatchset" id="loadMatchset" value="<?php echo Utils::t('Load'); ?>" />
							<?php endif; ?>
							<?php if (AdminServAdminLevel::hasPermission('maps_matchsettings_save')): ?>
								<input class="button dark" type="submit" name="saveMatchset" id="saveMatchset" value="<?php echo Utils::t('Save '); ?>" />
							<?php endif; ?>
						</div>
					</div>
				</div>
			<?php endif; ?>
		</div>
		</form>
	</section>
</section>
<?php if (!empty($data['menuList'])): ?>
	<nav class="vertical-nav">
		<ul>
			<?php foreach ($data['menuList'] as $page => $title): ?>
				<?php if (AdminServAdminLevel::hasAccess($page)): ?>
					<li><a <?php if (USER_PAGE == $page): echo 'class="active"'; endif; ?>href="?p=<?php echo $page; if ($args['directory']): echo '&amp;d='.$args['directory']; endif; ?>"><?php echo Utils::t($title); ?></a></li>
				<?php endif; ?>
			<?php endforeach; ?>
		</ul>
	</nav>
<?php endif; ?>
<section class="maps hasMenu">
	<section class="cadre left menu">
		<?php echo AdminServUI::getMapsMenuList(); ?>
	</section>
	
	<section class="cadre right order">
		<h1><?php echo Utils::t('Order'); ?></h1>
		<form method="post" action="?p=<?php echo USER_PAGE; ?>">
			<h2><?php echo Utils::t('Automatic sort'); ?></h2>
			<div class="autoSortMode options-radio-inline">
				<ul>
					<li class="ui-state-default">
						<input class="text" type="radio" name="sortMode" id="sortModeName" value="name" />
						<div class="name"><?php echo Utils::t('Name'); ?></div>
						<div class="icon">
							<span class="ui-icon ui-icon-arrowthick-1-n"></span>
							<span class="ui-icon ui-icon-arrowthick-1-s"></span>
						</div>
					</li>
					<li class="ui-state-default">
						<input class="text" type="radio" name="sortMode" id="sortModeEnv" value="env" />
						<div class="name"><?php echo Utils::t('Environment'); ?></div>
						<div class="icon">
							<span class="ui-icon ui-icon-arrowthick-1-n"></span>
							<span class="ui-icon ui-icon-arrowthick-1-s"></span>
						</div>
					</li>
					<li class="ui-state-default">
						<input class="text" type="radio" name="sortMode" id="sortModeAuthor" value="author" />
						<div class="name"><?php echo Utils::t('Author'); ?></div>
						<div class="icon">
							<span class="ui-icon ui-icon-arrowthick-1-n"></span>
							<span class="ui-icon ui-icon-arrowthick-1-s"></span>
						</div>
					</li>
					<li class="ui-state-default">
						<input class="text" type="radio" name="sortMode" id="sortModeRand" value="rand" />
						<div class="name"><?php echo Utils::t('Random'); ?></div>
					</li>
				</ul>
			</div>
			
			<h2><?php echo Utils::t('Manual sort'); ?></h2>
			<div class="content">
				<ul id="sortableMapList">
					<?php if (!empty($data['maps'])): ?>
						<?php foreach ($data['maps']['lst'] as $id => $map): ?>
							<li class="ui-state-default">
								<div class="ui-icon ui-icon-arrowthick-2-n-s"></div>
								<div class="order-map-name" title="<?php echo $map['FileName']; ?>"><?php echo $map['Name']; ?></div>
								<div class="order-map-env"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/env/<?php echo strtolower($map['Environment']); ?>.png" alt="" /><?php echo $map['Environment']; ?></div>
								<div class="order-map-author"><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/mapauthor.png" alt="" /><?php echo $map['Author']; ?></div>
							</li>
						<?php endforeach; ?>
					<?php endif; ?>
				</ul>
			</div>
			
			<?php if (SERVER_MATCHSET && AdminServAdminLevel::hasPermission('maps_matchsettings_save')): ?>
				<div class="fleft options-checkbox">
					<input class="text inline" type="checkbox" name="SaveCurrentMatchSettings" id="SaveCurrentMatchSettings"<?php if (AdminServConfig::AUTOSAVE_MATCHSETTINGS === true): echo ' checked="checked"'; endif; ?> value="" /><label for="SaveCurrentMatchSettings" title="<?php echo SERVER_MATCHSET; ?>"><?php echo Utils::t('Save the current MatchSettings'); ?></label>
				</div>
			<?php endif; ?>
			<div class="fright save">
				<input class="button light" type="button" id="reset" name="reset" value="<?php echo Utils::t('Reset'); ?>" />
				<input class="button light" type="submit" id="save" name="save" value="<?php echo Utils::t('Save'); ?>" />
				<input type="hidden" id="list" name="list" value="" />
				<input type="hidden" id="jsonlist" name="jsonlist" value="<?php echo htmlspecialchars( json_encode($data['maps']) ); ?>" />
			</div>
		</form>
	</section>
</section>
<section class="maps hasMenu<?php if (defined('IS_LOCAL') && IS_LOCAL): echo ' hasFolders'; endif; ?>">
	<section class="cadre left menu">
		<?php echo AdminServUI::getMapsMenuList(); ?>
	</section>
	
	<?php if (defined('IS_LOCAL') && IS_LOCAL): ?>
		<section class="cadre middle folders">
			<?php echo AdminServUI::getMapsDirectoryList($data['currentDir'], $args['directory']); ?>
		</section>
	<?php endif; ?>
	
	<section class="cadre right upload">
		<h1><?php echo Utils::t('Send'); ?></h1>
		<div class="title-detail path"><?php echo $data['mapsDirectoryPath'].$args['directory']; ?></div>
		
		<h2><?php echo Utils::t('Transfer mode'); ?></h2>
		<div class="transferMode options-radio-inline">
			<ul>
				<?php if (AdminServAdminLevel::hasPermission('maps_upload_add')): ?>
					<li class="selected">
						<input class="text" type="radio" name="transferMode" id="transferModeAdd" value="add" checked="checked" />
						<div class="name"><span><?php echo Utils::t('Add'); ?></span> <?php echo Utils::t('at the end of list'); ?></div>
					</li>
				<?php endif; ?>
				<?php if (AdminServAdminLevel::hasPermission('maps_upload_insert')): ?>
					<li>
						<input class="text" type="radio" name="transferMode" id="transferModeInsert" value="insert" />
						<div class="name"><span><?php echo Utils::t('Insert'); ?></span> <?php echo Utils::t('after current map'); ?></div>
					</li>
				<?php endif; ?>
				<?php if (AdminServAdminLevel::hasPermission('maps_upload_folder')): ?>
					<li>
						<input class="text" type="radio" name="transferMode" id="transferModeLocal" value="local" />
						<div class="name"><span><?php echo Utils::t('Send'); ?></span> <?php echo Utils::t('only in the folder'); ?></div>
					</li>
				<?php endif; ?>
			</ul>
		</div>
		
		<h2><?php echo Utils::t('Options'); ?></h2>
		<div class="options-checkbox">
			<ul>
				<?php if (SERVER_MATCHSET && AdminServAdminLevel::hasPermission('maps_matchsettings_save')): ?>
					<li>
						<input class="text inline" type="checkbox" name="SaveCurrentMatchSettings" id="SaveCurrentMatchSettings"<?php if (AdminServConfig::AUTOSAVE_MATCHSETTINGS === true): echo ' checked="checked"'; endif; ?> value="" />
						<label for="SaveCurrentMatchSettings" title="<?php echo SERVER_MATCHSET; ?>"><?php echo Utils::t('Save the current MatchSettings'); ?></label>
					</li>
				<?php endif; ?>
				<li>
					<input class="text inline" type="checkbox" name="GotoListMaps" id="GotoListMaps" value="maps" checked="checked" />
					<label for="GotoListMaps"><?php echo Utils::t('Go to the maps list when upload is complete'); ?></label>
				</li>
			</ul>
		</div>
		
		<h2><?php echo Utils::t('Upload'); ?></h2>
		<div id="formUpload" class="loader" data-mapspagename="maps-list" data-cancel="<?php echo Utils::t('Cancel'); ?>" data-failed="<?php echo Utils::t('Failed'); ?>" data-uploadfile="<?php echo Utils::t('Upload a file'); ?>" data-dropfiles="<?php echo Utils::t('Drop files here to upload'); ?>" data-uploadnotfinished="<?php echo Utils::t('Upload not finished'); ?>" data-from="<?php echo Utils::t('from'); ?>" data-kb="<?php echo Utils::t('Kb'); ?>" data-mb="<?php echo Utils::t('Mb'); ?>" data-type-error="<?php echo Utils::t('{file} has invalid extension. Only {extensions} are allowed.'); ?>" data-size-error="<?php echo Utils::t('{file} is too large, maximum file size is {sizeLimit}.'); ?>" data-minsize-error="<?php echo Utils::t('{file} is too small, minimum file size is {minSizeLimit}.'); ?>" data-empty-error="<?php echo Utils::t('{file} is empty, please select files again without it.'); ?>" data-onleave="<?php echo Utils::t('The file was not uploaded. Upload has been cancelled or a server error occurred.'); ?>"></div>
	</section>
</section>
<section class="cadre">
	<h1><?php echo $data['errorTitle']; ?></h1>
	
	<?php if ($data['errorMessage']): ?>
		<div class="content">
			<p><?php echo $data['errorMessage']; ?></p>
		</div>
	<?php endif; ?>
</section>
<section class="plugins hasMenu">
	<section class="cadre left menu">
		<?php echo AdminServPlugin::getMenuList(); ?>
	</section>
	
	<section class="cadre right">
		<h1><?php echo Utils::t('Plugins'); ?></h1>
		<div class="title-detail">
			<ul>
				<li class="last">
					<?php echo $data['nbplugins']['count'].' '.$data['nbplugins']['title']; ?>
				</li>
			</ul>
		</div>
		<div class="content">
			<p><?php echo Utils::t('Plugins are extensions to add features to Adminserv.'); ?></p>
		</div>
		
		<h2><?php echo Utils::t('Install a plugin'); ?></h2>
		<div class="content">
			<p><?php echo Utils::t('See all plugins:'); ?> <a href="http://dl.zone-kev717.info/adminserv/plugins"><?php echo Utils::t('Click here'); ?></a></p>
			<p>- <?php echo Utils::t('Unzip the plugin and place its contents into the &laquo; plugins &raquo; folder of Adminserv.'); ?><br />
			- <?php echo Utils::t('In the Configuration Extension, add the name of the plugin folder previously added.'); ?></p>
			<p>
				<code>
					public static $PLUGINS = array(<br />
					&nbsp;&nbsp;&nbsp;&nbsp;'PluginName',<br />
					);
				</code>
			</p>
		</div>
		
		<h2><?php echo Utils::t('Create a new plugin'); ?></h2>
		<div class="content">
			<?php echo Utils::t('<p>To create a plugin, go to the plugins folder and duplicate file _newplugin. Replace the values ​​in the config.ini file and folder name.<br />Then there are two PHP files:</p><ul><li>script.php : this file is executed before the header of the site. This is where all plugin script will be placed.</li><li>view.php : this file is the display of the plugin executed after the header. This is where everything will be placed the html code.</li></ul><p>You need to create resources (classes, js, css) then include these files.</p>'); ?>
		</div>
	</section>
</section>
<section class="cadre">
	<h1><?php echo Utils::t('Server options'); ?></h1>
	<form method="post" action="?p=<?php echo USER_PAGE; ?>">
		<div class="content">
			<?php if (AdminServAdminLevel::hasPermission(array('srvopts_general_name', 'srvopts_general_comment', 'srvopts_general_serverpassword', 'srvopts_general_spectatorpassword', 'srvopts_general_nbplayers', 'srvopts_general_nbspectators'))): ?>
				<fieldset class="srvopts_general">
					<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/servers.png" alt="" /><?php echo Utils::t('General'); ?></legend>
					<table>
						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_name')): ?>
							<tr class="serverName">
								<td class="key"><label for="ServerName"><?php echo Utils::t('Server name'); ?></label></td>
								<td class="value" colspan="3">
									<input class="text width3" type="text" name="Name" id="ServerName" maxlength="75" value="<?php echo $data['srvOpt']['Name']; ?>" />
								</td>
								<td class="preview">[<span id="serverNameHtml"><?php echo $data['srvOpt']['NameHtml']; ?></span>]</td>
							</tr>
						<?php endif; ?>
						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_comment')): ?>
							<tr class="serverComment">
								<td class="key"><label for="ServerComment"><?php echo Utils::t('Comment'); ?></label></td>
								<td class="value" colspan="3">
									<textarea class="width3" name="Comment" id="ServerComment" maxlength="255"><?php echo $data['srvOpt']['Comment']; ?></textarea>
								</td>
								<td class="preview">[<span id="serverCommentHtml"><?php echo $data['srvOpt']['CommentHtml']; ?></span>]</td>
							</tr>
						<?php endif; ?>
						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_playerpassword')): ?>
							<tr>
								<td class="key"><label for="ServerPassword"><?php echo Utils::t('Player password'); ?></label></td>
								<td class="value" colspan="3">
									<input class="text width3" type="text" name="Password" id="ServerPassword" value="<?php echo $data['srvOpt']['Password']; ?>" />
								</td>
								<td class="preview"></td>
							</tr>
						<?php endif; ?>
						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_spectatorpassword')): ?>
							<tr>
								<td class="key"><label for="SpectatorPassword"><?php echo Utils::t('Spectator password'); ?></label></td>
								<td class="value" colspan="3">
									<input class="text width3" type="text" name="PasswordForSpectator" id="SpectatorPassword" value="<?php echo $data['srvOpt']['PasswordForSpectator']; ?>" />
								</td>
								<td class="preview"></td>
							</tr>
						<?php endif; ?>
						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_nbplayers')): ?>
							<tr>
								<td class="key"><label for="NextMaxPlayers"><?php echo Utils::t('Nb max of players'); ?></label></td>
								<td class="value col2">
									<input class="text width1" type="text" name="CurrentMaxPlayers" id="CurrentMaxPlayers" readonly="readonly" value="<?php echo $data['srvOpt']['CurrentMaxPlayers']; ?>" />
								</td>
								<td class="key col3"><label for="NextMaxPlayers"><?php echo Utils::t('Next value'); ?></label></td>
								<td class="value">
									<input class="text width1" type="number" min="0" name="NextMaxPlayers" id="NextMaxPlayers" value="<?php echo $data['srvOpt']['NextMaxPlayers']; ?>" />
								</td>
								<td class="preview"></td>
							</tr>
						<?php endif; ?>
						<?php if (AdminServAdminLevel::hasPermission('srvopts_general_nbspectators')): ?>
							<tr>
								<td class="key"><label for="NextMaxSpectators"><?php echo Utils::t('Nb max of spectators'); ?></label></td>
								<td class="value col2">
									<input class="text width1" type="text" name="CurrentMaxSpectators" id="CurrentMaxSpectators" readonly="readonly" value="<?php echo $data['srvOpt']['CurrentMaxSpectators']; ?>" />
								</td>
								<td class="key col3"><label for="NextMaxSpectators"><?php echo Utils::t('Next value'); ?></label></td>
								<td class="value">
									<input class="text width1" type="number" min="0" name="NextMaxSpectators" id="NextMaxSpectators" value="<?php echo $data['srvOpt']['NextMaxSpectators']; ?>" />
								</td>
								<td class="preview"></td>
							</tr>
						<?php endif; ?>
					</table>
				</fieldset>
			<?php endif; ?>
			
			<?php if (AdminServAdminLevel::hasPermission('srvopts_advanced')): ?>
				<fieldset class="srvopts_advanced">
					<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/options.png" alt="" /><?php echo Utils::t('Advanced'); ?></legend>
					<table>
						<tr>
							<td class="key"><label for="IsP2PUpload"><?php echo Utils::t('P2P Upload'); ?></label></td>
							<td class="value col2">
								<input class="text" type="checkbox" name="IsP2PUpload" id="IsP2PUpload"<?php if ($data['srvOpt']['IsP2PUpload'] != 0): echo ' checked="checked"'; endif; ?> value="" />
							</td>
							<td class="key col3"><label for="IsP2PDownload"><?php echo Utils::t('P2P Download'); ?></label></td>
							<td class="value">
								<input class="text" type="checkbox" name="IsP2PDownload" id="IsP2PDownload"<?php if ($data['srvOpt']['IsP2PDownload'] != 0): echo ' checked="checked"'; endif; ?> value="" />
							</td>
							<td class="preview"></td>
						</tr>
						<tr>
							<td class="key"><label for="NextLadderMode"><?php echo Utils::t('Ladder mode'); ?></label></td>
							<td class="value col2">
								<input class="text width1" type="text" name="CurrentLadderMode" id="CurrentLadderMode" readonly="readonly" value="<?php echo $data['srvOpt']['CurrentLadderModeName']; ?>" />
							</td>
							<td class="key col3"><label for="NextLadderMode"><?php echo Utils::t('Next value'); ?></label></td>
							<td class="value">
								<select class="width1" name="NextLadderMode" id="NextLadderMode">
									<option value="0"<?php if ($data['srvOpt']['NextLadderMode'] == 0): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Inactive'); ?></option>
									<option value="1"<?php if ($data['srvOpt']['NextLadderMode'] == 1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Forced'); ?></option>
								</select>
							</td>
							<td class="preview"></td>
						</tr>
						<tr>
							<td class="key"><label for="NextVehicleNetQuality"><?php echo Utils::t('Vehicles quality'); ?></label></td>
							<td class="value col2">
								<input class="text width1" type="text" name="CurrentVehicleNetQuality" id="CurrentVehicleNetQuality" readonly="readonly" value="<?php echo $data['srvOpt']['CurrentVehicleNetQualityName']; ?>" />
							</td>
							<td class="key col3"><label for="NextVehicleNetQuality"><?php echo Utils::t('Next value'); ?></label></td>
							<td class="value">
								<select class="width1" name="NextVehicleNetQuality" id="NextVehicleNetQuality">
									<option value="0"<?php if ($data['srvOpt']['NextVehicleNetQuality'] == 0): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Fast'); ?></option>
									<option value="1"<?php if ($data['srvOpt']['NextVehicleNetQuality'] == 1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('High'); ?></option>
								</select>
							</td>
							<td class="preview"></td>
						</tr>
						<tr>
							<td class="key"><label for="NextCallVoteTimeOut"><?php echo Utils::t('Vote expiration'); ?> <span>(<?php echo Utils::t('sec'); ?>)</span></label></td>
							<td class="value col2">
								<input class="text width1" type="text" name="CurrentCallVoteTimeOut" id="CurrentCallVoteTimeOut" readonly="readonly" value="<?php echo TimeDate::millisecToSec($data['srvOpt']['CurrentCallVoteTimeOut']); ?>" />
							</td>
							<td class="key col3"><label for="NextCallVoteTimeOut"><?php echo Utils::t('Next value'); ?></label></td>
							<td class="value">
								<input class="text width1" type="number" min="0" name="NextCallVoteTimeOut" id="NextCallVoteTimeOut" value="<?php echo TimeDate::millisecToSec($data['srvOpt']['NextCallVoteTimeOut']); ?>" />
							</td>
							<td class="preview"></td>
						</tr>
						<tr>
							<td class="key"><label for="CallVoteRatio"><?php echo Utils::t('Vote ratio'); ?></label></td>
							<td class="value" colspan="4">
								<select name="callVoteRatioDisabled" id="callVoteRatioDisabled"<?php if ($data['srvOpt']['CallVoteRatio'] > -1): echo ' hidden="hidden"'; endif; ?>>
									<option value="-1"<?php if ($data['srvOpt']['CallVoteRatio'] == -1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Disable'); ?></option>
									<option value="0"<?php if ($data['srvOpt']['CallVoteRatio'] > -1): echo ' selected="selected"'; endif; ?>><?php echo Utils::t('Enable'); ?></option>
								</select>
								<input class="text" type="number" min="0" max="1" step=".1" name="CallVoteRatio" id="CallVoteRatio" value="<?php echo $data['srvOpt']['CallVoteRatio']; ?>"<?php if ($data['srvOpt']['CallVoteRatio'] == -1): echo ' hidden="hidden"'; endif; ?> />
								<a class="returnDefaultValue" id="resetCallVoteRatio" href="?p=<?php echo USER_PAGE; ?>"<?php if ($data['srvOpt']['CallVoteRatio'] == -1): echo ' hidden="hidden"'; endif; ?>><?php echo Utils::t('Disable vote ratio'); ?></a>
							</td>
						</tr>
						<?php if (SERVER_VERSION_NAME == 'ManiaPlanet'): ?>
							<tr>
								<td class="key"><label for="ClientInputsMaxLatency"><?php echo Utils::t('Client inputs max latency'); ?></label></td>
								<td class="value" colspan="4">
									<select name="ClientInputsMaxLatency" id="ClientInputsMaxLatency"<?php if ($data['srvOpt']['ClientInputsMaxLatency'] > 0): echo ' hidden="hidden"'; endif; ?>>
										<option value="0"><?php echo Utils::t('Automatic'); ?></option>
										<option value="more"><?php echo Utils::t('Choose number'); ?></option>
									</select>
									<input class="text" type="number" min="0" name="ClientInputsMaxLatencyValue" id="ClientInputsMaxLatencyValue" value="<?php echo $data['srvOpt']['ClientInputsMaxLatency']; ?>"<?php if ($data['srvOpt']['ClientInputsMaxLatency'] == 0): echo ' hidden="hidden"'; endif; ?> />
									<a class="returnDefaultValue" id="resetClientInputsMaxLarency" href="?p=<?php echo USER_PAGE; ?>"<?php if ($data['srvOpt']['ClientInputsMaxLatency'] == 0): echo ' hidden="hidden"'; endif; ?>><?php echo Utils::t('Return to the default value'); ?></a>
								</td>
							</tr>
						<?php endif; ?>
						<tr>
							<td class="key"><label for="HideServer"><?php echo Utils::t('Hidden server'); ?></label></td>
							<td class="value" colspan="4">
								<input class="text" type="checkbox" name="HideServer" id="HideServer"<?php if ($data['srvOpt']['HideServer'] != 0): echo ' checked="checked"'; endif; ?> value="" />
							</td>
						</tr>
						<tr>
							<td class="key"><label for="AllowMapDownload"><?php echo Utils::t('Map download'); ?></label></td>
							<td class="value" colspan="4">
								<input class="text" type="checkbox" name="AllowMapDownload" id="AllowMapDownload"<?php if (SERVER_VERSION_NAME == 'TmForever' && $data['srvOpt']['AllowChallengeDownload'] != 0): echo ' checked="checked"'; elseif (SERVER_VERSION_NAME == 'ManiaPlanet' && $data['srvOpt']['AllowMapDownload'] != 0): echo ' checked="checked"'; endif; ?> value="" />
							</td>
						</tr>
						<tr<?php if (AdminServAdminLevel::isType('Admin') && !AdminServAdminLevel::isType('SuperAdmin')): echo ' hidden="hidden"'; endif; ?>>
							<td class="key"><label for="AutoSaveReplays"><?php echo Utils::t('Replays auto save'); ?></label></td>
							<td class="value" colspan="4">
								<input class="text" type="checkbox" name="AutoSaveReplays" id="AutoSaveReplays"<?php if ($data['srvOpt']['AutoSaveReplays'] != 0): echo ' checked="checked"'; endif; ?> value="" />
							</td>
						</tr>
						<tr>
							<td class="key"><label for="BuddyNotification"><?php echo Utils::t('Buddy notification'); ?></label></td>
							<td class="value" colspan="4">
								<input class="text" type="checkbox" name="BuddyNotification" id="BuddyNotification"<?php if ($data['srvOpt']['BuddyNotification'] != 0): echo ' checked="checked"'; endif; ?> value="" />
							</td>
						</tr>
						<?php if (SERVER_VERSION_NAME == 'ManiaPlanet'): ?>
							<tr>
								<td class="key"><label for="DisableHorns"><?php echo Utils::t('Disable horns'); ?></label></td>
								<td class="value" colspan="4">
									<input class="text" type="checkbox" name="DisableHorns" id="DisableHorns"<?php if ($data['srvOpt']['DisableHorns'] != 0): echo ' checked="checked"'; endif; ?> value="" />
								</td>
							</tr>
						<?php endif; ?>
					</table>
				</fieldset>
			<?php endif; ?>
			
			<?php if (AdminServAdminLevel::hasPermission('srvopts_adminlevelpassword', USER_ADMINLEVEL, 'SuperAdmin')): ?>
				<fieldset class="srvopts_changeauthpassword">
					<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/players.png" alt="" /><?php echo Utils::t('Change authentication password'); ?></legend>
					<table>
						<tr>
							<td class="key"><label for="ChangeAuthLevel"><?php echo Utils::t('Admin level'); ?></label></td>
							<td class="value col2">
								<select name="ChangeAuthLevel" id="ChangeAuthLevel">
									<?php if (isset($data['adminLevels']['levels']) && !empty($data['adminLevels']['levels'])): ?>
										<?php foreach ($data['adminLevels']['levels'] as $levelId => $levelName): ?>
											<option value="<?php echo $levelName; ?>"><?php echo $levelName; ?></option>
										<?php endforeach; ?>
									<?php endif; ?>
								</select>
								<span class="changeauthpassword-arrow"> </span>
								<input class="text" type="password" name="ChangeAuthPassword" id="ChangeAuthPassword" value="" />
							</td>
						</tr>
					</table>
				</fieldset>
			<?php endif; ?>
			
			<?php if (defined('IS_LOCAL') && IS_LOCAL && AdminServAdminLevel::hasPermission('srvopts_importexport')): ?>
				<fieldset class="srvopts_importexport">
					<legend><img src="<?php echo AdminServConfig::$PATH_RESOURCES; ?>images/16/rt_team.png" alt="" /><?php echo Utils::t('Manage server options'); ?></legend>
					<table>
						<tr>
							<td class="key"><label for="srvoptsImport"><?php echo Utils::t('Import'); ?></label></td>
							<td class="value col2">
								<input class="text" type="radio" name="srvoptsImportExport" id="srvoptsImport" value="Import" />
								<select name="srvoptsImportName" id="srvoptsImportName" hidden="hidden">
									<?php if (isset($data['srvoptsConfigFiles']['files']) && !empty($data['srvoptsConfigFiles']['files'])): ?>
										<?php foreach ($data['srvoptsConfigFiles']['files'] as $file): ?>
											<option value="<?php echo $file['filename']; ?>"><?php echo substr($file['filename'], 0, -4); ?></option>
										<?php endforeach; ?>
									<?php else: ?>
										<option value="none"><?php echo Utils::t('No export available'); ?></option>
									<?php endif; ?>
								</select>
							</td>
						</tr>
						<tr>
							<td class="key"><label for="srvoptsExport"><?php echo Utils::t('Export'); ?></label></td>
							<td class="value col2">
								<input class="text" type="radio" name="srvoptsImportExport" id="srvoptsExport" value="Export" />
								<input class="text" hidden="hidden" type="text" name="srvoptsExportName" id="srvoptsExportName" value="<?php echo SERVER_LOGIN; ?>" />
							</td>
						</tr>
					</table>
				</fieldset>
			<?php endif; ?>
		</div>
		<div class="fright save">
			<input class="button light" type="submit" name="savesrvopts" id="savesrvopts" value="<?php echo Utils::t('Save'); ?>" />
		</div>
	</form>
</section>
User-agent: *
Disallow: /