diff --git a/ajax.php b/ajax.php
new file mode 100644
index 0000000..5804914
--- /dev/null
+++ b/ajax.php
@@ -0,0 +1,152 @@
+<?php
+
+if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
+
+	require_once('./classes/class.seagullgallery.php');
+	include_once($_SERVER['DOCUMENT_ROOT'].'/manager/includes/config.inc.php');
+
+	$connect = db_connect($database_server, $database_user, $database_password);
+	$db = str_replace('`', '', $dbase);
+	$db = db_select($db, $connect);
+
+	if (!$db) {
+		echo 'Невозможно установить соединение c базой данных "'.$dbase.'" на "'.$database_server.'"';
+		exit();
+	}
+
+	$sg = new CSeagullGallery($msg);
+	$response = array();
+
+	switch ($_REQUEST['cmd']) {
+		case 'addGallery':
+			if ($sg->saveGallery($_POST)) {
+				$msg->setReload();
+			}
+		break;
+
+		case 'saveGallery':
+			if (!$sg->saveGallery($_POST))
+				$msg->setError('Ошибка при сохранении настроек');
+		break;
+
+		case 'addimgs':
+			$rows = $sg->addImages($_POST['itemID'], $_FILES['imgs']);
+			if ($rows)
+				$response['rows'] = $rows;
+			else
+				$msg->setError('Сбой при загрузке, попробуйте еще раз');
+		break;
+
+		case 'saveimg':
+			if (isset($_POST['id'])) {
+				$r = $sg->updateImage($_POST, $_FILES['imgfile']);
+
+				if ($r) {
+//							$config->gallery_dir.'/thumb'.$this->path.'/'.$item['file_thumb']
+					$response['obj'] = $r;
+					$response['edit'] = true;
+					$msg->setOk('Изображение #'.$_POST['id'].' отредактированно');
+				}
+				elseif (!$msg->keep_error)
+					$msg->setError('Сбой при сохранении изображении');
+			}
+		break;
+
+		case 'getimg': {
+			$_POST['id'] = str_replace('img', '', $_POST['id']);
+			$r = $sg->getImage($_POST['id']);
+			
+			if ($r) {
+				$response['obj'] = $r;
+			}
+			else
+				$msg->setError('Сбой при получении данных о изображении');
+		} break;
+
+		case 'delImgs':
+			if ($_POST['imgs_select']) {
+				if ($sg->delImages($_POST['imgs_select'])) {
+					$c = count($sg->arr_del);
+					for ($i=0; $i<$c; $i++)
+						$response['remove_arr'][] = '#img'.$sg->arr_del[$i];
+					$response['remove_arr'] = implode(',', $response['remove_arr']);
+
+					$msg->setInfo('Изображение(я) удалено');
+				}
+				else
+					$msg->setError('Ошибка при удалении изображения(й)');
+			}
+			else {
+				$msg->setInfo('Выделите изображения для удаления');
+			}
+		break;
+
+		case 'delGallery':
+			if ($sg->delGallery($_POST['itemID'])) {
+				$msg->setInfo('Галерея удалена');
+				$msg->setReload();
+			}
+			else
+				$msg->setError('Ошибка при удалении изображения(й)');
+		break;
+
+		case 'imgs_sort':
+			if ($sg->sortImages($_POST['arr_sort']))
+				$msg->setOk('Изображения отсортированы');
+			else
+				$msg->setError('Ошибка при сортировке');
+		break;
+
+		case 'resizeThumbs':
+			if ($sg->resizeThumbs($_POST['itemID']))
+				$msg->setOk('Миниатюры пересчитаны');
+			else
+				$msg->setError('Ошибка при пересчете миниатюр');
+		break;
+
+		case 'ckeditorSelectGallery':
+			$r = $sg->renderTableCKEditor();
+
+			if ($r) {
+				$response['tbody'] = $r;
+			}
+			elseif (!$msg->keep_error)
+				$msg->setError('Сбой при сохранении изображении');
+		break;
+
+		case 'clearTables':
+			if ($sg->clearTables($_POST['itemID']))
+				$msg->setOk('Таблицы очищены');
+			else
+				$msg->setError('Ошибка при сохранении настроек');
+		break;
+
+		case 'saveConfig':
+			if ($sg->config->saveForm($_POST['config'], $sg->nameModule))
+				$msg->setOk('Глобальные настройки сохранены');
+			else
+				$msg->setError('Ошибка при сохранении');
+		break;
+
+		case 'setPublished':
+			$r = run_sql('UPDATE '.$sg->tables['galleries']->table.' SET `published`=\''.$_POST['val'].'\' WHERE `id`='.$_POST['itemID']);	// запись прочитана
+			$_POST['val'] ? $msg->setOk('Галерея №'.$_POST['itemID'].' опубликована') : $msg->setOk('Галерея №'.$_POST['itemID'].' скрыта');
+		break;
+
+		case 'getPaginatorPage':
+			if ($_REQUEST['param']==='gals') {
+				$response['tbody'] = $sg->tables['galleries']->renderTableBody($_REQUEST['pageID']);
+				$response['links'] = $sg->tables['galleries']->renderPaginatorLinks($_REQUEST['pageID']);
+			}
+			else {
+				$gid = str_replace('imgs', '', $_POST['param']);
+				$response['tbody'] = $sg->renderImages($gid, $_REQUEST['pageID'], TBODY);
+				$response['links'] = $sg->tables['images']->renderPaginatorLinks($_REQUEST['pageID'], array('param'=>'imgs', 'query'=>'SELECT COUNT(`id`) FROM '.$sg->tables['images']->table.' WHERE `gallery_id`='.$gid));
+			}
+			$msg->setInfo('Следующая страница');
+		break;
+	}
+	$response = array_merge($response, $msg->get());
+	echo json_encode($response);
+}
+?>
\ No newline at end of file
diff --git a/classes/class.seagullgallery.php b/classes/class.seagullgallery.php
new file mode 100644
index 0000000..f0d81df
--- /dev/null
+++ b/classes/class.seagullgallery.php
@@ -0,0 +1,1308 @@
+<?php
+/*	Class SeagullGallery 0.0.6
+	Date update 0.0.6: 2014-04-11
+	Date update 0.0.5: 2014-04-07
+	Date update 0.0.4: 2014-01-23
+	Date update 0.0.3: 2013-10-01
+	Date update 0.0.2: 2012-03-22
+*/
+
+//ini_set('display_errors',1);
+//error_reporting(E_ALL);
+define('FULL_TABLE', 1);
+define('TBODY', 2);
+
+require_once($_SERVER['DOCUMENT_ROOT'].'/assets/modules/seagulllibrary/class.seagullmodule.php');
+
+class CSeagullGallery extends CSeagullModule {
+	var $modx = null;
+	var $ph = array();
+	var $tables = array();
+	var $nameModule = 'seagullgallery';
+	const mailto = 'maxcpp@gmail.com';
+	
+	function __construct() { //--------------------------------
+		$args = func_get_args();
+		$this->msg = $args[0];
+		$modx = $args[1];
+
+		$this->config = new CConfig($this->msg);
+		$this->config->getVariables($this->nameModule);
+		$this->config->labelParam .= ' style="width:240px"';
+
+		if (isset($modx))
+			$this->modx = $modx;
+		$this->ph['title'] = 'Менеджер галерей';
+		$this->ph['nameModule'] = $this->nameModule;
+
+//------------------------------------------------
+		$columns = array();
+		$columns['id'] = array(
+					'title'=>'ID',
+					'form_hidden'=>true,
+					'form_dontEdit'=>true,
+					'table_theadParam'=>' style="width:30px;"'
+					);
+
+		$columns['published'] =	array(
+					'title'=>'Опубликован',
+					'form_fieldType'=>'checkbox',
+					'table_td_content'=>array('published'=>array(0=>'<div class="b-unpublished" title="Скрыт"></div>', 1=>'<div class="b-published" title="Опубликован"></div>')),
+					'table_theadParam'=>'style="width:20px"',
+					'table_title_hidden'=>true
+					);
+
+		$columns['title'] =	array(
+					'title'=>'Заголовок',
+					'form_fieldType'=>'input',
+					'form_fieldParam'=>'style="width:80%"'
+					);
+
+		$columns['description'] = array(
+					'title'=>'Подпись',
+					'form_fieldType'=>'textarea',
+					'form_fieldParam'=>'style="width:80%"',
+					'table_hidden'=>true
+					);
+
+		$columns['type_view'] =	array(
+					'title'=>'Внешний вид галереи',
+					'form_fieldType'=>'select',
+					'values'=>array('thumbs'=>'Миниатюры с увеличением', 'images'=>'Большие изображения', 'image_and_thumbs'=>'Большое изображение и прокручиваемый список миниатюр'),
+					'table_hidden'=>true
+					);
+
+		$columns['parent_id'] =	array(
+					'title'=>'Родительская галерея',
+					'form_fieldType'=>'number',
+					'form_fieldParam'=>'style="width:50px"',
+					'table_hidden'=>true
+					);
+
+		$columns['sort_id'] =	array(
+					'title'=>'Сортировка',
+					'form_fieldType'=>'number',
+					'form_fieldParam'=>'style="width:50px"',
+					'table_hidden'=>true
+					);
+
+		$columns['alias'] =	array(
+					'title'=>'Псевдоним',
+					'form_fieldType'=>'input',
+					'table_hidden'=>true
+					);
+
+		$columns['path'] =	array(
+					'title'=>'Путь',
+					'form_fieldType'=>'input',
+					'form_dontEdit'=>true,
+					'table_hidden'=>true,
+					'form_fieldParam'=>'disabled="disabled"'
+					);
+
+		$columns['count_img'] =	array(
+					'title'=>'Кол-во изображений',
+					'form_fieldType'=>'number',
+					'form_fieldParam'=>'style="width:50px" disabled="disabled"',
+					'table_theadParam'=>' style="width:130px;"'
+					);
+
+		$columns['default_img'] = array(
+					'title'=>'Изображение на обложку',
+					'form_fieldType'=>'number',
+					'form_fieldParam'=>'style="width:50px"',
+					'table_hidden'=>true
+					);
+
+		$columns['max_width'] =	array(
+					'title'=>'Ширина изображений',
+					'form_fieldType'=>'number',
+					'form_fieldParam'=>'style="width:50px"',
+					'table_hidden'=>true
+					);
+
+		$columns['max_height'] =	array(
+					'title'=>'Высота изображений',
+					'form_fieldType'=>'number',
+					'form_fieldParam'=>'style="width:50px"',
+					'table_hidden'=>true
+					);
+
+		$columns['max_priority_side'] =	array(
+					'title'=>'Приоритет стороны изображений',
+					'form_fieldType'=>'radio',
+					'values'=>array('w'=>'ширине', 'h'=>'высоте'),
+					'table_hidden'=>true
+					);
+
+		$columns['thumb_width'] = array(
+					'title'=>'Ширина миниатюр',
+					'form_fieldType'=>'number',
+					'form_fieldParam'=>'style="width:50px"',
+					'table_hidden'=>true
+					);
+
+		$columns['thumb_height'] = array(
+					'title'=>'Высота миниатюр',
+					'form_fieldType'=>'number',
+					'form_fieldParam'=>'style="width:50px"',
+					'table_hidden'=>true
+					);
+
+		$columns['thumb_priority_side'] = array(
+					'title'=>'Приоритет стороны миниатюры',
+					'form_fieldType'=>'radio',
+					'values'=>array('w'=>'ширине', 'h'=>'высоте'),
+					'table_hidden'=>true
+					);
+
+		$columns['description_active'] = array(
+					'title'=>'Подписи',
+					'form_fieldType'=>'select',
+					'values'=>array('0'=>'Отключить', '1'=>'Включить', 'global'=>'Как в глобальных настройках'),
+					'table_hidden'=>true
+					);
+
+		$columns['align'] = array(
+					'title'=>'Позиция подписи по горизонтале',
+					'form_fieldType'=>'select',
+					'values'=>array('left'=>'Слева', 'center'=>'В центре', 'right'=>'Справа', 'global'=>'Глобальные настройки'),
+					'table_hidden'=>true
+					);
+
+		$columns['valign'] = array(
+					'title'=>'Позиция подписи по вертикали',
+					'form_fieldType'=>'select',
+					'values'=>array('top'=>'Сверху', 'bottom'=>'Снизу', 'global'=>'Глобальные настройки'),
+					'table_hidden'=>true
+					);
+
+		$columns['watermark'] = array(
+					'title'=>'Водяной занк',
+					'form_fieldType'=>'input',
+					'table_hidden'=>true
+					);
+
+		$columns['watermark_type'] = array(
+					'title'=>'Тип водяного знака',
+					'form_fieldType'=>'radio',
+					'values'=>array('image'=>'изображение', 'text'=>'текст'),
+					'table_hidden'=>true
+					);
+
+		$columns['watermark_color'] = array(
+					'title'=>'Цвет водяного знака',
+					'form_fieldType'=>'input',
+					'form_fieldParam'=>'class="colorpicker"',
+					'table_hidden'=>true
+					);
+
+		$columns['html_param'] = array(
+					'title'=>'HTML-параметры',
+					'form_fieldType'=>'input',
+					'table_hidden'=>true
+					);
+
+		$columns['date_update'] = array(
+					'title'=>'Дата обновления',
+					'form_fieldType'=>'date',
+					'values'=>'unix_timestamp(now())',
+					'form_mysql_mask'=>'FROM_UNIXTIME(`date_update`, "%d.%m.%Y %h:%i") `date_update`',
+					'table_mysql_mask'=>'FROM_UNIXTIME(`date_update`, "%d.%m.%Y %h:%i") `date_update`',
+					'form_hidden'=>true,
+					'table_theadParam'=>' style="width:110px;"'
+					);
+
+		$this->tables['galleries'] = new CEditTable('seagull_galleries', $columns);
+		$this->tables['galleries']->config = &$this->config;
+		$this->tables['galleries']->setConfig('table_mysql_select', '`id`, `title`, `published`, `count_img`, FROM_UNIXTIME(`date_update`, "%d.%m.%Y %H:%i") `date_update`');
+		$this->tables['galleries']->setConfig('table_param', 'id="t-galleries" class="b-table tpaginator" cellpadding="0" cellspacing="0"');
+		$this->tables['galleries']->setConfig('tr_param', array('id'=>' id="row%id%" class="row-edit"'));
+		$this->tables['galleries']->setConfig('tag_begin', '<p style="overflow:hidden">');
+		$this->tables['galleries']->setConfig('label_begin', '<label style="width:200px; display:block; float:left">');
+		$this->tables['galleries']->setConfig('paginatorRowsByPage', $this->config->backend->paginatorGal->rowsByPage);
+		$this->tables['galleries']->setConfig('paginatorAdvLinks', $this->config->backend->paginatorGal->advLinks);
+
+//------------------------------------------------
+		$columns = array();
+		$columns['id'] = array(
+					'title'=>'ID',
+					'form_hidden'=>true,
+					'form_dontEdit'=>true,
+					'table_hidden'=>true
+					);
+
+		$columns['imgs_select'] = array(
+					'title'=>'',
+					'form_dontEdit'=>true,
+					'form_hidden'=>true,
+					'non-exist'=>true,
+					'table_td_content'=>array('id'=>'<input type="checkbox" name="imgs_select[]" value="%id%" />'),
+					'table_theadParam'=>' style="width:20px;"'
+					);
+
+		$columns['image'] = array(
+					'title'=>'Миниатюра',
+					'table_theadParam'=>' style="width:90px; text-align:center"',
+					'non-exist'=>true
+					);
+
+		$columns['gallery_id'] = array(
+					'title'=>'ID галереи',
+					'table_hidden'=>true
+					);
+
+		$columns['sort_id'] =	array(
+					'title'=>'Сортировка',
+					'table_theadParam'=>' style="width:10px"',
+					'table_title_hidden'=>true
+					);
+
+		$columns['published'] =	array(
+					'title'=>'Опубликован',
+					'form_fieldType'=>'checkbox',
+					'table_hidden'=>true
+					);
+
+		$columns['title'] =	array(
+					'title'=>'Название',
+					'form_fieldType'=>'input',
+					'form_fieldParam'=>'style="width:80%"',
+					'table_td_link2edit'=>true
+					);
+
+		$columns['description'] = array(
+					'title'=>'Описание',
+					'form_fieldType'=>'textarea',
+					'form_fieldParam'=>'style="width:80%"',
+					'table_hidden'=>true
+					);
+
+		$columns['alt'] = array(
+					'title'=>'Описание в alt',
+					'table_hidden'=>true
+					);
+
+		$columns['size'] =	array(
+					'title'=>'Размер',
+					'table_theadParam'=>' style="width:70px; text-align:right"'
+					);
+
+		$columns['file'] = array(
+					'title'=>'Файл изображения',
+					'form_dontEdit'=>true,
+					'table_hidden'=>true
+					);
+
+		$columns['file_thumb'] = array(
+					'title'=>'Файл миниатюры',
+					'form_dontEdit'=>true,
+					'table_hidden'=>true
+					);
+
+		$columns['thumb_width'] = array(
+					'title'=>'Ширина миниатюр',
+					'form_dontEdit'=>true,
+					'table_hidden'=>true
+					);
+
+		$columns['thumb_height'] = array(
+					'title'=>'Высота миниатюр',
+					'form_dontEdit'=>true,
+					'table_hidden'=>true
+					);
+
+		$columns['date_update'] = array(
+					'title'=>'Дата обновления',
+					'form_fieldType'=>'date',
+					'values'=>'unix_timestamp(now())',
+					'form_mysql_mask'=>'FROM_UNIXTIME(`date_update`, "%d.%m.%Y %H:%i") `date_update`',
+					'form_hidden'=>true,
+					'table_theadParam'=>' style="width:110px;"'
+					);
+
+		$this->tables['images'] = new CEditTable('seagull_images', $columns);
+		$this->tables['images']->config = &$this->config;
+		$this->tables['images']->setConfig('table_mysql_select', '`id`, `sort_id`, `published`, `size`, `title`, `description`, `file`, `file_thumb`, FROM_UNIXTIME(`date_update`, "%d.%m.%Y %H:%i") `date_update`');
+		$this->tables['images']->setConfig('table_param', 'id="t-imgs" class="b-table tsort tpaginator" cellpadding="0" cellspacing="0"');
+		$this->tables['images']->setConfig('tr_param', array('id'=>' id="img%id%" class="row-edit"'));
+		$this->tables['images']->setConfig('sort_col', 'sort_id');
+		$this->tables['images']->setConfig('group_id', 'gallery_id');
+		$this->tables['images']->setConfig('label_begin', '<label style="width:100px; display:block; float:left">');
+		$this->tables['images']->setConfig('paginatorRowsByPage', $this->config->backend->paginatorImg->rowsByPage);
+		$this->tables['images']->setConfig('paginatorAdvLinks', $this->config->backend->paginatorImg->advLinks);
+	}
+
+	function handlePost() { //------------------------------------------------
+
+		switch($_POST['cmd']) {
+			case 'install':
+				$this->install();
+				$this->ph['title'] = 'Установка модуля';
+				$this->file_tpl = 'install';
+				$this->ph['msg'] = $this->msg->renderAll();
+				return 1;
+			break;
+
+			case 'addGallery':
+				$this->ph['form_gallery'] = $this->tables['galleries']->renderForm($_POST['itemID']);
+				$this->ph['title'] = 'Добавление галереи';
+				$this->file_tpl = 'addgallery';
+			break;
+
+			case 'editGallery':
+				$this->ph['images_list'] = $this->renderImages($_POST['itemID']);
+				$this->ph['paginator_links'] = $this->tables['images']->renderPaginator(1, array('param'=>'imgs'.$_POST['itemID'], 'query'=>'SELECT COUNT(*) FROM '.$this->tables['images']->table.' WHERE `gallery_id`='.$_POST['itemID'], 'limit'=>$this->config->backend->paginatorImg->rowsByPage, 'advLinks'=>$this->config->backend->paginatorImg->advLinks));
+				$this->ph['gallery_id'] = $_POST['itemID'];
+				$this->file_tpl = 'editgallery';
+			break;
+
+			case 'configGallery':
+				$this->ph['form_gallery'] = $this->tables['galleries']->renderForm($_POST['itemID']);
+				$this->ph['gallery_id'] = $_POST['itemID'];
+				$this->file_tpl = 'configgallery';
+			break;
+
+			case 'config':
+				$this->ph['config'] = $this->config->renderForm($this->nameModule);
+				$this->file_tpl = 'config';
+			break;
+
+			default:
+				$this->ph['galleries_list'] = $this->tables['galleries']->renderTable(1, NULL, NULL, $this->config->backend->paginatorGal->rowsByPage);
+				$this->ph['paginator_links'] = $this->tables['galleries']->renderPaginator(1, array('param'=>'gals', 'limit'=>$this->config->backend->paginatorGal->rowsByPage, 'advLinks'=>$this->config->backend->paginatorGal->advLinks));
+				$this->file_tpl = 'main';
+			break;
+		}
+		$this->ph['msgType'] = 'msg_'.$this->msg->getType();
+		$this->ph['msg'] = $this->msg->render();
+	}
+
+	function init($gid) { //--------------------------------
+
+		if ($gid) {
+			$arr = retr_sql('SELECT * FROM '.$this->tables['galleries']->table." WHERE `id`='".$gid."'");
+
+			if ($arr) {
+				foreach ($arr as $key=>$item) {
+					$this->{$key} = $item;
+				}
+				return $arr;
+			}
+		}
+
+		return 0;
+	}
+
+	function getGalleryPath($gid) { //--------------------------------
+
+		if ($gid) {
+			$path = retr_sql('SELECT `path` FROM '.$this->tables['galleries']->table." WHERE `id`='".$gid."'");
+
+			if ($path)
+				return $path;
+		}
+
+		return 0;
+	}
+
+	function getImage($img_id, $where='') { //--------------------------------
+		global $tables, $site, $config;
+
+		$img = retr_sql('SELECT `id`, `gallery_id`, `title`, `description`, `alt`, `file`, `file_thumb`, `size`, FROM_UNIXTIME(`date_update`, "%d.%m.%Y %h:%i") `date_update` FROM '.$this->tables['images']->table.' WHERE `id`='.$img_id.' '.$where);
+
+		$img['path'] = $this->config->galleryDir.'/'.$img['gallery_id'].'/'.$img['file'];
+		$img['path_thumb'] = $this->config->galleryDir.'/thumb/'.$img['gallery_id'].'/'.$img['file_thumb'];
+		$img['size'] = round($img['size']/1024).' КБ';
+
+		if ($img)
+			return($img);
+		else
+			return 0;
+	}
+
+	function saveGallery($aData) { //--------------------------------
+		if (isset($aData['title']) and empty($aData['title']))
+			$this->msg->setError('Введите <strong>Заголовок</strong>');
+
+		$aData['sort_id'] = empty($aData['sort_id']) ? 1 : $aData['sort_id'];
+		$aData['alias'] = empty($aData['alias']) ? translit2URL($aData['title']) : $aData['alias'];
+		$aData['published'] = (isset($aData['published']) and $aData['published']==1) ? 1 : 0;
+		$aData['need_auth'] = (isset($aData['need_auth']) and $aData['need_auth']==1) ? 1 : 0;
+		$aData['max_width'] = empty($aData['max_width']) ? '0' : $aData['max_width'];
+		$aData['max_height'] = empty($aData['max_height']) ? '0' : $aData['max_height'];
+		$aData['max_priority_side'] = empty($aData['max_priority_side']) ? 'w' : $aData['max_priority_side'];
+		$aData['thumb_width'] = empty($aData['thumb_width']) ? 0 : $aData['thumb_width'];
+		$aData['thumb_height'] = empty($aData['thumb_height']) ? 0 : $aData['thumb_height'];
+		$aData['thumb_priority_side'] = empty($aData['thumb_priority_side']) ? 'w' : $aData['thumb_priority_side'];
+		$aData['count_img'] = 0;
+		$aData['date_update'] = 1;
+
+		if (!$this->msg->keep) {
+
+			if (isset($aData['itemID']) and !empty($aData['itemID']) and is_numeric($aData['itemID'])) {
+				$aData['path'] = $this->createPath($aData['itemID']);
+				$aData['count_img'] = retr_sql("SELECT count(`id`) FROM ".$this->tables['images']->table." WHERE `gallery_id`=".$aData['itemID']);
+
+				$r = $this->tables['galleries']->updateRow($aData['itemID'], $aData, DONT_UPDATE_ALL_FIELDS_OF_TABLE);
+
+				$this->check_dir($aData['path']);
+				$this->check_dir('/thumb'.$aData['path']);
+
+				if ($r)
+					$this->msg->setOk('Галерея сохранена');
+				else
+					$this->msg->setError('Ошибка сохранения галереи #'.$aData['itemID'].' в БД');
+				return $aData['itemID'];
+			}
+			else {
+				$tempname = $aData['title'];
+				$aData['title'] = md5(rand(0, 100));
+				$r = $this->tables['galleries']->insertRow($aData);
+
+				if ($r) {
+					$gallery_id = retr_sql('SELECT `id` FROM '.$this->tables['galleries']->table." WHERE `title`='".$aData['title']."'");
+					
+					$aData = array();
+					$aData['path'] = $this->createPath($gallery_id);
+					$aData['title'] = $tempname;
+					$r = $this->tables['galleries']->updateRow($gallery_id, $aData, DONT_UPDATE_ALL_FIELDS_OF_TABLE);
+
+					$this->check_dir($aData['path']);
+					$this->check_dir('/thumb'.$aData['path']);
+
+					if ($r) {
+						$this->msg->setOk('Галерея добавлена');
+					}
+					else
+						$this->msg->setError('Ошибка сохранения в БД');
+					return $gallery_id;
+				}
+				else {
+					$errno = mysql_errno();
+					if ($errno==1062)
+						$this->msg->setError('Галерея с таким псевдонимом уже существует');
+					else
+						$this->msg->setError('Ошибка ('.$errno.') сохранения в БД');
+				}
+			}
+		}
+		return 0;
+	}
+
+	function addImages($gid, $arrImgs) { //--------------------------------
+
+		$output = '';
+		$msgs = '';
+		$this->init($gid);
+
+		$c = count($arrImgs['name']);
+
+		for ($i=0; $i<$c; $i++) {
+			$img['name'] = $arrImgs['name'][$i];
+			$img['type'] = $arrImgs['type'][$i];
+			$img['tmp_name'] = $arrImgs['tmp_name'][$i];
+			$img['error'] = $arrImgs['error'][$i];
+			$img['size'] = $arrImgs['size'][$i];
+
+			$randname = md5(rand(0, 1000));
+			$r = run_sql('INSERT INTO '.$this->tables['images']->table." (`gallery_id`, `title`) VALUES (".$gid.", '".$randname."')");
+			if ($r) {
+				$img_id = retr_sql("SELECT `id` FROM ".$this->tables['images']->table." WHERE `gallery_id`=".$gid." AND `title`='".$randname."'");
+				if (!$img_id) {
+					$this->msg->setError('Ошибка при добавлении изображения в БД');
+					return 0;
+				}
+			}
+			else {
+				$this->msg->setError('Ошибка при добавлении изображения в БД');
+				return 0;
+			}
+
+			$imgData = $this->createImage($img_id, $img);
+			if ($imgData) {
+				$thumbData = $this->createThumb($img_id, array('name'=>$imgData['file']));
+
+				if ($thumbData)
+					$imgData = array_merge($imgData, $thumbData);
+				else
+					$this->msg->setError('Ошибка при создании миниатюры изображения #'.$aData['id']);
+			}
+			else
+				$this->msg->setError('Ошибка при обновлении изображения #'.$aData['id']);
+
+			$imgData['title'] = '';
+			$imgData['description'] = '';
+			$imgData['alt'] = '';
+			$imgData['date_update'] = mktime();
+			$r = $this->tables['images']->updateRow($img_id, $imgData, DONT_UPDATE_ALL_FIELDS_OF_TABLE);
+			
+			if ($r) {
+				$msgs .= $img['name'].'<br>';
+				$img = $this->getImage($img_id);
+				$output .= '<tr id="img'.$img['id'].'" class="b-row_green">
+					<td><input class="img_select" type="checkbox" name="imgs_select[]" value="'.$img['id'].'" /></td>
+					<td><img src="'.$img['path'].'" height="60" alt="image '.$img['id'].'" /></td>
+					<td class="tsort__dragHandle"></td>
+					<td class="col-edit"><span class="b-td__title">'.$img['title'].'</span><div class="b-td__desc">'.$img['description'].'</div></td>
+					<td class="tr">'.$img['size'].'</td>
+					<td>'.$img['date_update'].'</td>
+				</tr>';
+			}
+		}
+
+		if (!$this->msg->hold) {
+			$this->updateCountImages($gid);
+			if ($c)
+				$this->msg->setOk('Загруженные изображения:<br>'.$msgs);
+			else
+				$this->msg->setOk('Изображение "'.$msgs.'" загружено');
+
+			return $output;
+		}
+		return 0;
+	}
+
+	function updateImage($aData, $imgfile=NULL) { //--------------------------------
+
+		if (isset($aData['id']) and !empty($aData['id'])) {
+//			$aData['sort_id'] = 1;
+
+//			if (isset($aData['title']) and empty($aData['title']))
+//				$this->msg->setError('Введите "Название"');
+
+//			$aData['published'] = (isset($aData['published']) and $aData['published']==1) ? 1 : 0;
+			
+			if (!$this->msg->hold) {
+
+				if ($imgfile) {
+					$gid = retr_sql('SELECT `gallery_id` FROM '.$this->tables['images']->table.' WHERE `id`='.$aData['id']);
+					$this->init($gid);
+
+					if ($gid) {
+						$imgData = $this->createImage($aData['id'], $imgfile);
+
+						if ($imgData) {
+							$thumbData = $this->createThumb($aData['id'], array('name'=>$imgData['file']));
+							
+							if ($thumbData)
+								$imgData = array_merge($imgData, $thumbData);
+							else
+								$this->msg->setError('Ошибка при создании миниатюры изображения #'.$aData['id']);
+						}
+						else
+							$this->msg->setError('Ошибка при обновлении изображения #'.$aData['id']);
+					}
+				}
+
+//				add_log('$imgData:'.ea($imgData, 1), 'update_IMAGE.log');
+
+				$imgData['title'] = $aData['title'];
+				$imgData['description'] = $aData['description'];
+				$imgData['alt'] = $aData['alt'];
+				$imgData['date_update'] = mktime();
+				unset($imgData['sort_id']);
+				$r = $this->tables['images']->updateRow($aData['id'], $imgData, DONT_UPDATE_ALL_FIELDS_OF_TABLE);
+
+				if ($r) {
+					$img = $this->getImage($aData['id']);
+					$output = '<tr id="img'.$img['id'].'" class="b-row_green">
+						<td><input class="img_select" type="checkbox" name="imgs_select[]" value="'.$img['id'].'" /></td>
+						<td><img src="'.$img['path'].'" height="60" alt="image '.$img['id'].'" /></td>
+						<td class="tsort__dragHandle"></td>
+						<td class="col-edit"><span class="b-td__title">'.$img['title'].'</span><div class="b-td__desc">'.$img['description'].'</div></td>
+						<td class="tr">'.$img['size'].'</td>
+						<td>'.$img['date_update'].'</td>
+					</tr>';
+					return $output;
+				}
+				else
+					$this->msg->setError('MySQL: Ошибка (#'.mysql_errno().') при выполнении запроса');
+			}
+		}
+		else
+			$this->msg->setError('Отсутствует ID изображения');
+		return 0;
+	}
+
+	function resizeImage($image, $newpath, $newfilename, $newwidth=100, $newheight=100, $priority_side='w', $quality=93) { //--------------------------------
+
+//		add_log($image.'|'.$newpath.'|'.$newfilename.'|'.$newwidth.'|'.$newheight.'|'.$priority_side, 'update_IMAGE.log');
+
+		if ($image) {
+			$pathinfo = pathinfo($image['name']);
+			$ext = strtolower($pathinfo['extension']);
+//			add_log('$pathinfo:'.ea($pathinfo, 1), 'update_IMAGE.log');
+
+			if (empty($newfilename))
+				$newfilename = $image['name'];
+			else
+				$newfilename = $newfilename.'.'.$ext;
+			
+			list($width, $height) = getimagesize($image['tmp_name']);
+
+			if ($width > $newwidth) {
+				$ratio = $width/$height;
+
+				if ($newwidth==0 or $priority_side==='h') {
+					$newwidth = $newheight * $ratio;
+				}
+				elseif ($newheight==0 or $priority_side==='w') {
+					$newheight = $newwidth / $ratio;
+				}
+				$img_create= imagecreatetruecolor($newwidth, $newheight);
+//				imageantialias($img_create, true);
+
+				switch ($ext) {
+					case 'jpg': $img_source = imagecreatefromjpeg($image['tmp_name']);	break;
+					case 'gif': $img_source = imagecreatefromgif($image['tmp_name']);	break;
+					case 'png': $img_source = imagecreatefrompng($image['tmp_name']);	break;
+				}
+
+				if (!$img_source)
+					return 0;
+				imagecopyresampled($img_create, $img_source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
+
+/*$img_create = $this->create_watermark($img_create, 'www.natalia-fisher.ru', $_SERVER['DOCUMENT_ROOT'].'/assets/modules/seagullgallery/fonts/calibrib.ttf', 255, 255, 255, 20);
+
+				if ($this->config->watermark) {
+					add_log(ea($this->config->watermark, 1), 'watermark.log');
+//					$img_create = $this->createWatermark($img_create, $this->config->watermark);
+				}
+*/
+				$imgfile = $newpath.'/'.$newfilename;
+				switch ($ext) {
+					case 'jpg': $r = imagejpeg($img_create, $imgfile, $quality);	break;
+					case 'gif': $r = imagegif($img_create, $imgfile, $quality);		break;
+					case 'png': $r = imagepng($img_create, $imgfile, $quality);		break;
+				}
+
+				if ($r)
+					return $newfilename;
+			}
+			else {
+				$imgfile = $newpath.'/'.$newfilename;
+				if (copy($image['tmp_name'], $imgfile))
+					return $newfilename;
+			}
+		}//end if
+		return 0;
+	}
+
+	function createImage($img_id, $source_img) { //--------------------------------
+
+		if ($this->max_width==0)
+			$this->max_width = $this->config->image->maxWidth;
+
+		if ($this->max_height==0)
+			$this->max_height = $this->config->image->maxHeight;
+
+		$path = SITE_ROOT.$this->config->galleryDir.$this->path;
+		$this->check_dir($this->path);
+
+		$filename = $img_id;
+		$filename = $this->resizeImage($source_img, $path, $filename, $this->max_width, $this->max_height, $this->max_priority_side);
+
+		if ($filename) {
+			$imgData = array();
+			$imgData['sort_id'] = $this->count_img+1;
+			$imgData['title'] = '';
+			$imgData['size'] = filesize(SITE_ROOT.$this->config->galleryDir.$this->path.'/'.$filename);
+			$imgData['file'] = $filename;
+			$imgData['date_update'] = mktime();
+			return $imgData;
+//			$r = $this->tables['images']->updateRow($img_id, $update, DONT_UPDATE_ALL_FIELDS_OF_TABLE);
+
+			if ($r) {
+				return $imgData;
+			}
+			else
+				$this->msg->setError('Ошибка при обновлении данных изображения '.$filename.' в БД');
+		}
+		else
+			$this->msg->setError('Ошибка при копировании временного файла "'.$filename.'"');
+	}
+
+	function createThumb($img_id, $source_img=NULL) { //--------------------------------
+
+		if (!$source_img['name'])
+			$source_img['name'] = retr_sql('SELECT `file` FROM '.$this->tables['images']->table." WHERE `id`=".$img_id);
+
+		if ($this->thumb_width==0)
+			$this->thumb_width = $this->config->thumb->maxWidth;
+
+		if ($this->thumb_height==0)
+			$this->thumb_height = $this->config->thumb->maxHeight;
+
+		$path_thumb = SITE_ROOT.$this->config->galleryDir.'/thumb'.$this->path;
+
+		$this->check_dir('/thumb'.$this->path);
+
+		$source_img['tmp_name'] = SITE_ROOT.$this->config->galleryDir.$this->path.'/'.$source_img['name'];
+		$filename_thumb = $img_id.'_'.$this->thumb_width.'x'.$this->thumb_height;
+
+		$filename_thumb = $this->resizeImage($source_img, $path_thumb, $filename_thumb, $this->thumb_width, $this->thumb_height, $this->thumb_priority_side);
+
+		if ($filename_thumb) {
+			$thumbData = array();
+			$thumbData['file_thumb'] = $filename_thumb;
+			$thumbData['thumb_width'] = $this->thumb_width;
+			$thumbData['thumb_height'] = $this->thumb_height;
+			return $thumbData;
+		}
+		else
+			$this->msg->setError('Ошибка при создании миниатюры "'.$filename_thumb.'"');
+	}
+
+	function createWatermark($main_img_obj, $watermark) {
+		$width = imagesx($main_img_obj);
+		$height = imagesy($main_img_obj);
+		$rgba = hex2rgb($watermark->color);
+		$rgba[3] = 127-(($rgba[3]-1)/2);
+		$font = SITE_ROOT.$watermark->font;
+		add_log(ea($rgba, 1), 'watermark.log');
+		add_log($font, 'watermark.log');
+
+		if ($watermark->type === 'text') {
+			switch ($watermark->direction) {
+				case 'xy':
+					$angle =  -rad2deg(atan2((-$height),($width)));
+					$text = ' '.$watermark->text.' ';
+					$c = imagecolorallocatealpha($main_img_obj, 255, 255, 255, 80);
+					$size = (($width+$height)/2)*2/strlen($text);
+					$box  = imagettfbbox($size, $angle, $font, $text);
+					$x = $width/2 - abs($box[4] - $box[0])/2;
+					$y = $height/2 + abs($box[5] - $box[1])/2;
+
+					$r = imagettftext($main_img_obj, $size, $angle, $x, $y, $c, $font, $text);
+					add_log(ea($r, 1), 'watermark.log');
+				break;
+
+				case 'diagonal':
+					$angle =  -rad2deg(atan2((-$height),($width)));
+					$text = ' '.$watermark->text.' ';
+					$c = imagecolorallocatealpha($main_img_obj, $rgba[0], $rgba[1], $rgba[2], $rgba[3]);
+					$size = (($width+$height)/2)*2/strlen($text);
+					$box  = imagettfbbox($size, $angle, $font, $text);
+					$x = $width/2 - abs($box[4] - $box[0])/2;
+					$y = $height/2 + abs($box[5] - $box[1])/2;
+
+					imagettftext($main_img_obj, $size, $angle, $x, $y, $c, $font, $text);
+				break;
+			}
+		}
+
+		return $main_img_obj;
+	}
+
+/*function create_watermark( $main_img_obj, $text, $font, $r = 128, $g = 128, $b = 128, $alpha_level = 100 ) {
+	$width = imagesx($main_img_obj);
+	$height = imagesy($main_img_obj);
+	$angle =  -rad2deg(atan2((-$height),($width)));
+
+	$text = ' '.$text.' ';
+
+	$c = imagecolorallocatealpha($main_img_obj, $r, $g, $b, $alpha_level);
+	$size = (($width+$height)/2)*2/strlen($text);
+	$box  = imagettfbbox ( $size, $angle, $font, $text );
+	$x = $width/2 - abs($box[4] - $box[0])/2;
+	$y = $height/2 + abs($box[5] - $box[1])/2;
+
+	imagettftext($main_img_obj, $size, $angle, $x, $y, $c, $font, $text);
+	return $main_img_obj;
+}*/
+
+	function resizeThumbs($gid) {
+
+//		Получаю массив изображений
+		$aImages = sql2table('SELECT `id`, `file` FROM '.$this->tables['images']->table." WHERE `gallery_id`=".$gid);
+
+//		Беру новые значения для миниатюр
+		$aGallery = retr_sql("SELECT `thumb_width`, `thumb_height`, `thumb_priority_side`, `path` FROM ".$this->tables['galleries']->table." WHERE `id`=$gid");
+//		
+		if ($aGallery['thumb_width']==0)
+			$aGallery['thumb_width'] = $this->config->thumb->maxWidth;
+
+		if ($aGallery['thumb_height']==0)
+			$aGallery['thumb_height'] = $this->config->thumb->maxHeight;
+
+		$path_imgs = SITE_ROOT.$this->config->galleryDir.$aGallery['path'].'/';
+		$path_thumb = SITE_ROOT.$this->config->galleryDir.'/thumb'.$aGallery['path'];
+//		Удаляю все миниатюры
+		cleardir($path_thumb, CLEAR_FILES);
+//		$this->check_dir('/thumb'.$aGallery['path']);
+
+		foreach ($aImages as $img) {
+			$source_img['tmp_name'] = $path_imgs.$img['file'];
+			$source_img['name'] = $img['file'];
+
+			$filename_thumb = $img['id'].'_'.$aGallery['thumb_width'].'x'.$aGallery['thumb_height'];
+			$filename_thumb = $this->resizeImage($source_img, $path_thumb, $filename_thumb, $aGallery['thumb_width'], $aGallery['thumb_height'], $aGallery['thumb_priority_side']);
+//			$filename_thumb = $this->resizeImage($dir_imgs, $img['file'], $path_thumb, $filename_thumb, $aGallery['thumb_width'], $aGallery['thumb_height'], $aGallery['thumb_priority_side'], 70);
+
+			if ($filename_thumb) {
+				$update = array();
+				$update['file_thumb'] = $filename_thumb;
+				$update['thumb_width'] = $aGallery['thumb_width'];
+				$update['thumb_height'] = $aGallery['thumb_height'];
+				$update['date_update'] = 1;
+				if (!$this->tables['images']->updateRow($img['id'], $update, DONT_UPDATE_ALL_FIELDS_OF_TABLE))
+					$this->msg->setError('Ошибка при сохранении данных миниатюры "'.$filename_thumb.'"');
+			}
+			else {
+				$this->msg->setError('Ошибка при создании миниатюры изображения "'.$filename_thumb.'"');
+			}
+		}
+		if (!$this->msg->keep)
+			return 1;
+	
+		return 0;
+	}
+
+	function createPath($gallery_id) { //--------------------------------
+		global $tables, $config;
+
+		$path = $str = '';
+		if ($gallery_id) {
+			$parent = retr_sql("SELECT `parent_id`, `id` FROM ".$this->tables['galleries']->table." WHERE `id`=".$gallery_id);
+			if ($parent['parent_id']!==0)
+				$str = $this->createPath($parent['parent_id']);
+
+			$path = '/'.$str.$parent['id'];
+		}
+		return $path;
+	}
+
+	function check_dir($path, $make=1) { //--------------------------------
+		
+//	Проверка и создание папки галерей
+		$r = file_exists(SITE_ROOT.$this->config->galleryDir);
+		if (!$r)
+			$r = mkdir(SITE_ROOT.$this->config->galleryDir, 0777);
+
+		if ($r) {
+//	Проверка и создание папки миниатюр
+			$r = file_exists(SITE_ROOT.$this->config->galleryDir.'/thumb');
+			if (!$r)
+				$r = mkdir(SITE_ROOT.$this->config->galleryDir.'/thumb', 0777);
+
+//	Проверка и создание папки по пути
+			if ($r) {
+				$path = SITE_ROOT.$this->config->galleryDir.$path;
+				$r = file_exists($path);
+	//echo $path;
+				if ($make and !$r) {
+					$r = mkdir($path, 0777);
+					if (!$r)
+						echo 'Ошибка создания папки "'.SITE_ROOT.$this->config->galleryDir.$path.'"';
+				}
+			}
+		}
+
+		return $r;
+	}
+
+	function updateCountImages($gid) { //--------------------------------
+
+		$count = retr_sql("SELECT count(`id`) FROM ".$this->tables['images']->table." WHERE `gallery_id`=".$gid);
+		$r = run_sql("UPDATE ".$this->tables['galleries']->table." SET `count_img`='".$count."' WHERE `id`=".$gid);
+
+		if ($r)
+			return $count;
+		return -1;
+	}
+
+	function sortImages($str) { //--------------------------------
+
+		$str = str_replace('img', '', $str);
+		$arr = explode(',', $str);
+
+		$c = count($arr);
+		for ($i=0; $i<$c; $i++) {
+			$case .= ' WHEN `id`='.$arr[$i].' THEN '.$i;
+		}
+		$r = run_sql("UPDATE ".$this->tables['images']->table." SET `sort_id`=CASE $case END WHERE `id` IN ($str) ORDER BY `sort_id`");
+
+		if ($r)
+			return($r);
+		else
+			return 0;
+	}
+
+	function renderImages($gid, $pageID=NULL, $typeView=FULL_TABLE) { //--------------------------------
+		$path = $this->getGalleryPath($gid);
+
+		if (isset($this->config->backend->paginatorImg->rowsByPage)) {
+			$pageID = isset($pageID) ? $pageID : 1;
+			$limit = ($pageID-1) * $this->config->backend->paginatorImg->rowsByPage.','.$this->config->backend->paginatorImg->rowsByPage;
+		}
+
+		$arr = $this->tables['images']->getRows($this->tables['images']->table_mysql_select, '`gallery_id`='.$gid, NULL, $limit);
+		if ($arr) {
+//		ea($arr);
+			foreach ($arr as $colname=>$column) {
+				$gDir = $this->config->galleryDir.$path.'/'.$column['file'];
+				$output .= '<tr id="img'.$column['id'].'">
+								<td><input class="img_select" type="checkbox" name="imgs_select[]" value="'.$column['id'].'" /></td>
+								<td><a class="img-download" target="_blank" href="/assets/modules/seagullgallery/download.php?file='.$gDir.'"></a><img src="'.$this->config->galleryDir.'/thumb'.$path.'/'.$column['file_thumb'].'" height="60" title="'.$gDir.'" alt="image '.$column['id'].'" /></td>
+								<td class="tsort__dragHandle"></td>
+								<td class="col-edit"><span class="b-td__title">'.$column['title'].'</span><div class="b-td__desc">'.$column['description'].'</div></td>
+								<td class="tr">'.round($column['size']/1024).' КБ</td>
+								<td>'.$column['date_update'].'</td>
+							</tr>';
+			}
+
+			if ($typeView === FULL_TABLE)
+				$output = '<table '.$this->tables['images']->table_param.'>'.$this->tables['images']->renderTableHead().'<tbody>'.$output.'</tbody></table>';
+			return $output;
+		}
+		else {
+			return('<table '.$this->tables['images']->table_param.'>'.$this->tables['images']->renderTableHead().'<tbody><tr id="no-imgs"><td colspan="6" style="text-align:center">Нет изображений</td></tr></tbody></table>');
+		}
+
+
+		return 0;
+	}
+
+	function renderGallery($gid=NULL, $view=NULL) {
+
+		$output = '';
+
+		if (!isset($view)) {
+			$gal = retr_sql('SELECT `type_view`, `html_param`, `published`, `description_active`, `align`, `valign` FROM '.$this->tables['galleries']->table.' WHERE `id`='.$gid);
+		}
+
+		if ($gal['description_active'] === '1' or ($gal['description_active'] === 'global' and $this->config->description->active === '1')) {
+			$tpl = $this->getTpl('frontend/img_desc_'.(($gal['valign'] === 'global') ? $this->config->description->valign : $gal['valign']));
+		}
+		else {
+			$tpl = $this->getTpl('frontend/img');
+		}
+
+		if ($gal['published']) {
+			$arr = sql2table('SELECT `id`, `gallery_id`, `title`, `description`, `alt`, `file`, `file_thumb` FROM '.$this->tables['images']->table." WHERE `published`='1' AND `gallery_id`=$gid ORDER BY `sort_id`");
+
+		//	$arr = getImages();
+			switch ($gal['type_view']) {
+				case 'image_and_thumbs':
+	/*				$output = '<script src="assets/modules/seagullgallery/js/site/jquery.ad-gallery.pack.js" type="text/javascript"></script>
+								<script type="text/javascript">
+								$(function() {
+									var galleries = $(".ad-gallery").adGallery({slideshow:{enable: false}});
+								});
+								</script>';
+	*/
+					$output .= '<div id="gallery" class="ad-gallery">
+						<div class="ad-image-wrapper"></div>
+						<div class="ad-controls"></div>
+						<div class="ad-nav">
+							<div class="ad-thumbs">
+								<ul class="ad-thumb-list">';
+
+					foreach ($arr as $img) {
+						$img['path'] = $this->config->galleryDir.'/'.$img['gallery_id'].'/'.$img['file'];
+						$img['path_thumb'] = $this->config->galleryDir.'/thumb/'.$img['gallery_id'].'/'.$img['file_thumb'];
+						$output .= '<li><a href="'.$img['path'].'"><img src="'.$img['path_thumb'].'" title="'.htmlspecialchars($img['title']).'" longdesc="'.$img['file'].'" alt="'.htmlspecialchars($img['description']).'" class="image'.$img['id'].'"></a></li>';
+					}
+
+					$output .= '</ul>
+							</div>
+						</div>
+					</div>
+					<div id="descriptions"></div>';
+				break;
+
+				case 'thumbs':
+					foreach ($arr as $img) {
+						$img['path'] = $this->config->galleryDir.'/'.$img['gallery_id'].'/'.$img['file'];
+						$img['path_thumb'] = $this->config->galleryDir.'/thumb/'.$img['gallery_id'].'/'.$img['file_thumb'];
+						$img['title'] = htmlspecialchars($img['title']);
+						$img['description'] = htmlspecialchars($img['description']);
+						$img['html_param'] = $gal['html_param'];
+						$img['desc_align'] = ' thumb__desc_'.(($gal['align'] === 'global') ? $this->config->description->align : $gal['align']);
+						$output .= $this->parseContent($tpl, $img);
+					}
+					$output = '<div class="gallery">'.$output.'</div>';
+					
+				break;
+				
+				case 'images':
+					foreach ($arr as $img) {
+						$img['path'] = $this->config->galleryDir.'/'.$img['gallery_id'].'/'.$img['file'];
+						$img['path_thumb'] = $this->config->galleryDir.'/thumb/'.$img['gallery_id'].'/'.$img['file_thumb'];
+						$output .= '<div class="image"><img class="image__img" src="'.$img['path'].'" title="'.htmlspecialchars($img['title']).'" alt="'.htmlspecialchars($img['description']).'" class="image'.$img['id'].'" /><span class="b-image__title">'.$img['title'].'</span><span class="b-image__desc">'.$img['description'].'</span></div>';
+					}
+	//				$output = '<ul class="b-seagullGallery">'.$output.'</ul>';
+				break;
+			}
+		}
+		else {
+//			Галерея выключена
+		}
+		return $output;
+	}
+
+	function renderTableCKEditor() {
+		$output = '';
+		$arr = sql2table('SELECT `id`, `title` FROM '.$this->tables['galleries']->table.' ORDER BY `sort_id`');
+
+		if ($arr) {
+			foreach ($arr as $gal) {
+				$output .= '<tr class="row-edit"><td><input class="selectGallery" type="radio" name="selectGallery" value="'.$gal['id'].'"></td><td>'.$gal['id'].'</td><td>'.$gal['title'].'</td></tr>';
+			}
+
+			return $output;
+		}
+	}
+
+	function delGallery($gid) { //--------------------------------
+
+		if ($this->delImages($gid)) {
+			$path = $this->getGalleryPath($gid);
+			$dir = SITE_ROOT.$this->config->galleryDir;
+			cleardir($dir.$path, CLEAR_FILES);
+			cleardir($dir.'/thumb'.$path, CLEAR_FILES);
+
+			if (rmdir($dir.$path) and rmdir($dir.'/thumb'.$path))
+				$r = run_sql('DELETE FROM '.$this->tables['galleries']->table.' WHERE `id`='.$gid);
+			else
+				$this->msg->setError('Ошибка при удалении папок "'.$path.'" галереи');
+
+			if ($r)
+				return 1;
+		}
+		else
+			$this->msg->setError('Ошибка при удалении изображений');
+
+		return 0;
+	}
+
+//	Параметром может быть либо ID галереи, тогда удаляются все изображения в галереии, либо массив с ID-шниками тех изображений, которые надо удалить.
+	function delImages($param) { //--------------------------------
+		global $msg;
+
+		$dir = SITE_ROOT.$this->config->galleryDir;
+
+		if (is_array($param)) {
+			$str = implode(',', $param);
+
+			$arr = sql2table('SELECT `id`, `gallery_id`, `file`, `file_thumb` FROM '.$this->tables['images']->table.' WHERE `id` IN ('.$str.')');
+			if ($arr) {
+				$gid = $arr[0]['gallery_id'];
+				$arr_del = array();
+				foreach ($arr as $item) {
+					$del_file = $del_thumb = false;
+
+					if (empty($item['file'])) {
+						$del_file = true;
+					}
+					else {
+						if (file_exists($dir.'/'.$item['gallery_id'].'/'.$item['file'])) {
+							if (unlink($dir.'/'.$item['gallery_id'].'/'.$item['file']))
+								$del_file = true;
+							else
+								$this->msg->setError('Файл изображения #'.$item['id'].' не удален');
+						}
+						else
+							$del_file = true;
+					}
+
+					if (empty($item['file_thumb'])) {
+						$del_thumb = true;
+					}
+					else {
+						if (file_exists($dir.'/thumb/'.$item['gallery_id'].'/'.$item['file_thumb'])) {
+							if (unlink($dir.'/thumb/'.$item['gallery_id'].'/'.$item['file_thumb']))
+								$del_thumb = true;
+							else
+								$this->msg->setError('Файл изображения #'.$item['id'].' не удален');
+						}
+						else
+							$del_thumb = true;
+					}
+
+					if ($del_file and $del_thumb)
+						$arr_del[] = $item['id'];
+				}
+
+				if (count($arr_del)) {
+					$str = implode(',', $arr_del);
+					$r = run_sql("DELETE FROM ".$this->tables['images']->table." WHERE `id` IN (".$str.')');
+					if ($r) {
+						$this->updateCountImages($gid);
+						$this->arr_del = $arr_del;
+						return 1;
+					}
+				}
+			}
+		}
+		elseif (is_numeric($param)) {
+			$gid = $param;
+
+			$arr = sql2table("SELECT `id`, `gallery_id`, `file`, `file_thumb` FROM ".$this->tables['images']->table." WHERE `gallery_id`=".$gid);
+			foreach ($arr as $item) {
+				if (!(unlink($dir.'/'.$item['gallery_id'].'/'.$item['file']) and unlink($dir.'/thumb/'.$item['gallery_id'].'/'.$item['file_thumb']))) {
+					break;
+				}
+			}
+
+			$r = run_sql("DELETE FROM ".$this->tables['images']->table." WHERE `gallery_id`=".$param);
+		}
+		$this->updateCountImages($gid);
+
+		if ($r)
+			return 1;
+		return 0;
+	}
+
+	function clearTables() { //--------------------------------
+		$r = run_sql('TRUNCATE TABLE '.$this->tables['galleries']->table);
+		$r = run_sql('TRUNCATE TABLE '.$this->tables['images']->table);
+		cleardir(SITE_ROOT.$this->config->galleryDir, CLEAR_ALL);
+		if ($r)
+			return 1;
+		return 0;
+	}
+
+	function install() { //--------------------------------
+		global $dbase;
+
+		$r = true;
+		$this->config->install();
+		$groupID = $this->config->addModule($this->nameModule);
+
+		$arr = array(
+			array('name'=>'images','title'=>'Большие изображения','val'=>1),
+			array('name'=>'thumbs','title'=>'Миниатюры','val'=>0),
+			array('name'=>'image_and_thumbs','title'=>'Большое изображение и миниатюры','val'=>0)
+		);
+		$r &= (boolean)$this->config->setVariable('galleryViewDefault', $arr, $this->nameModule, NULL, 'S', 'Вид отображения галереи', '240px');
+		$r &= (boolean)$this->config->setVariable('galleryDir', '/assets/gallery', $this->nameModule, NULL, 'T', 'Папка для галерей', '240px');
+
+		$r &= (boolean)$this->config->setVariable('position', NULL, $this->nameModule, NULL, 'FIELDSET', 'Подписи к изображениям');
+		$r &= (boolean)$this->config->setVariable('active', 1, $this->nameModule, 'position', 'C', 'Включить подписи');
+		$arr = array(
+			array('name'=>'bottom','title'=>'Снизу','val'=>1),
+			array('name'=>'top','title'=>'Сверху','val'=>0)
+		);
+		$r &= (boolean)$this->config->setVariable('valign', $arr, $this->nameModule, 'position', 'R', 'Позиция по вертикале');
+		$arr = array(
+			array('name'=>'left','title'=>'Слева','val'=>0),
+			array('name'=>'center','title'=>'В центре','val'=>1),
+			array('name'=>'right','title'=>'Справа','val'=>0)
+		);
+		$r &= (boolean)$this->config->setVariable('align', $arr, $this->nameModule, 'position', 'R', 'Позиция по горизонтале');
+
+		$r &= (boolean)$this->config->setVariable('image', NULL, $this->nameModule, NULL, 'FIELDSET', 'Размеры изображений');
+		$r &= (boolean)$this->config->setVariable('maxWidth', 800, $this->nameModule, 'image', 'N', 'Максимальная ширина');
+		$r &= (boolean)$this->config->setVariable('maxHeight', 600, $this->nameModule, 'image', 'N', 'Максимальная высота');
+
+		$r &= (boolean)$this->config->setVariable('thumb', NULL, $this->nameModule, NULL, 'FIELDSET', 'Размеры миниатюр');
+		$r &= (boolean)$this->config->setVariable('maxWidth', 150, $this->nameModule, 'thumb', 'N', 'Максимальная ширина');
+		$r &= (boolean)$this->config->setVariable('maxHeight', 100, $this->nameModule, 'thumb', 'N', 'Максимальная высота');
+
+		$r &= (boolean)$this->config->setVariable('watermark', NULL, $this->nameModule, NULL, 'FIELDSET', 'Водяной знак');
+		$r &= (boolean)$this->config->setVariable('text', '', $this->nameModule, 'watermark', 'T', 'Текст или URL-изображения', '240px');
+		$r &= (boolean)$this->config->setVariable('font', '/assets/modules/seagullgallery/fonts/calibrib.ttf', $this->nameModule, 'watermark', 'T', 'URL к шрифту', '240px');
+		$arr = array(
+			array('name'=>'text','title'=>'Текстовая строка','val'=>1),
+			array('name'=>'image','title'=>'Изображение','val'=>0)
+		);
+		$r &= (boolean)$this->config->setVariable('type', $arr, $this->nameModule, 'watermark', 'S', 'Тип водяного знака');
+		$r &= (boolean)$this->config->setVariable('color', 'FFFFFFFF', $this->nameModule, 'watermark', 'T', 'Цвет водяного знака', '80px', NULL, 'colorpicker');
+		$arr = array(
+			array('name'=>'xy','title'=>'По координатам','val'=>1),
+			array('name'=>'diagonal','title'=>'По диагонале','val'=>0)
+		);
+		$r &= (boolean)$this->config->setVariable('direction', $arr, $this->nameModule, 'watermark', 'S', 'Направление');
+		$r &= (boolean)$this->config->setVariable('offsetX', '-3%', $this->nameModule, 'watermark', 'N', 'Сдвиг по X', '50px', 'Значение могут быть либо в "px" либо в "%". Если со знаком минус, то отсчет ведеться от правой стороны');
+		$r &= (boolean)$this->config->setVariable('offsetY', '-3%', $this->nameModule, 'watermark', 'N', 'Сдвиг по Y', '50px', 'Значение могут быть либо в "px" либо в "%". Если со знаком минус, то отсчет ведеться от нижней стороны');
+
+		$r &= (boolean)$this->config->setVariable('backend', NULL, $this->nameModule, NULL, 'FIELDSET', 'Административный сайт (то где ты сейчас находишься)');
+//		$r &= (boolean)$this->config->setVariable('active', 1, $this->nameModule, 'paginatorBackend', 'C', 'Включить');
+
+		$r &= (boolean)$this->config->setVariable('paginatorGal', NULL, $this->nameModule, 'backend', 'FIELDSET', 'Постраничная навигация галерей');
+		$r &= (boolean)$this->config->setVariable('rowsByPage', '15', $this->nameModule, 'paginatorGal', 'N', 'Кол-во галерей на странице', '50px');
+		$r &= (boolean)$this->config->setVariable('advLinks', '2', $this->nameModule, 'paginatorGal', 'N', 'Общее кол-во выводимых ссылок', '50px');
+
+		$r &= (boolean)$this->config->setVariable('paginatorImg', NULL, $this->nameModule, 'backend', 'FIELDSET', 'Постраничная навигация изображений');
+		$r &= (boolean)$this->config->setVariable('rowsByPage', '15', $this->nameModule, 'paginatorImg', 'N', 'Кол-во изображений на странице', '50px');
+		$r &= (boolean)$this->config->setVariable('advLinks', '2', $this->nameModule, 'paginatorImg', 'N', 'Общее кол-во выводимых ссылок', '50px');
+
+		$r &= (boolean)$this->config->setVariable('paginatorFrontend', NULL, $this->nameModule, NULL, 'FIELDSET', 'Постраничная навигация на сайте');
+		$r &= (boolean)$this->config->setVariable('active', 1, $this->nameModule, 'paginatorFrontend', 'C', 'Включить');
+		$r &= (boolean)$this->config->setVariable('rowsByPage', '15', $this->nameModule, 'paginatorFrontend', 'N', 'Кол-во записей на странице', '50px');
+		$r &= (boolean)$this->config->setVariable('advLinks', '2', $this->nameModule, 'paginatorFrontend', 'N', 'Кол-во ссылок на соседние страницы', '50px');
+
+
+		$r ? $this->msg->setOk('Переменные установлены') : $this->msg->setError('Ошибка при установки переменных');
+
+		$r = retr_sql("SHOW TABLE STATUS FROM ".$dbase." LIKE '".$this->tables['galleries']->tablename."'");
+		if (!$r) {
+			$r = run_sql("CREATE TABLE ".$this->tables['galleries']->table." (
+					`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+					`parent_id` int(10) unsigned DEFAULT NULL,
+					`sort_id` int(10) unsigned NOT NULL DEFAULT '1',
+					`alias` varchar(255) NOT NULL,
+					`path` varchar(255) NOT NULL,
+					`title` varchar(255) DEFAULT NULL,
+					`description` varchar(255) DEFAULT NULL,
+					`description_active` enum('0','1','global') NOT NULL DEFAULT 'global',
+					`align` enum('left','center','right','global') NOT NULL DEFAULT 'global',
+					`valign` enum('top','bottom','global') NOT NULL DEFAULT 'global',
+					`published` enum('0','1') NOT NULL DEFAULT '1',
+					`type_view` enum('images','thumbs','image_and_thumbs') NOT NULL DEFAULT 'thumbs',
+					`count_img` int(10) unsigned DEFAULT NULL,
+					`default_img` int(10) unsigned DEFAULT NULL,
+					`show_desc_img` enum('0','1') NOT NULL DEFAULT '1',
+					`max_width` int(4) unsigned NOT NULL DEFAULT '0',
+					`max_height` int(4) unsigned NOT NULL DEFAULT '0',
+					`max_priority_side` enum('w','h') NOT NULL DEFAULT 'w',
+					`thumb_width` int(4) unsigned NOT NULL DEFAULT '0',
+					`thumb_height` int(4) unsigned NOT NULL DEFAULT '0',
+					`thumb_priority_side` enum('w','h') NOT NULL DEFAULT 'w',
+					`watermark` varchar(255) DEFAULT NULL,
+					`watermark_type` enum('text','image') DEFAULT NULL,
+					`watermark_color` varchar(8) DEFAULT 'FFFFFFFF',
+					`watermark_x` int(5) DEFAULT NULL,
+					`watermark_y` int(5) DEFAULT NULL,
+					`html_param` varchar(255) DEFAULT NULL,
+					`date_update` int(10) unsigned NOT NULL,
+					PRIMARY KEY (`id`)
+				) ENGINE=MYISAM DEFAULT CHARSET=utf8");
+			if ($r)
+				$this->msg->setOk('Таблица "'.$this->tables['galleries']->tablename.'" создана');
+		} else
+			$this->msg->setWarning('Таблица "'.$this->tables['galleries']->tablename.'" уже создана');
+
+		$r = retr_sql("SHOW TABLE STATUS FROM ".$dbase." LIKE '".$this->tables['images']->tablename."'");
+		if (!$r) {
+			$r = run_sql("CREATE TABLE ".$this->tables['images']->table." (
+					`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+					`gallery_id` int(10) unsigned NOT NULL,
+					`sort_id` int(11) NOT NULL DEFAULT '1',
+					`published` enum('0','1') NOT NULL DEFAULT '1',
+					`size` int(10) unsigned DEFAULT NULL,
+					`title` varchar(255) NOT NULL,
+					`description` text,
+					`alt` varchar(255) DEFAULT NULL,
+					`file` varchar(128) NOT NULL,
+					`file_thumb` varchar(128) NOT NULL,
+					`thumb_width` int(4) unsigned NOT NULL DEFAULT '0',
+					`thumb_height` int(4) unsigned NOT NULL DEFAULT '0',
+					`watermarked` enum('0','1') NOT NULL DEFAULT '0',
+					`date_update` int(10) unsigned NOT NULL,
+					PRIMARY KEY (`id`)
+				) ENGINE=MYISAM DEFAULT CHARSET=utf8");
+			if ($r)
+				$this->msg->setOk('Таблица "'.$this->tables['images']->tablename.'" создана');
+		} else
+			$this->msg->setWarning('Таблица "'.$this->tables['images']->tablename.'" уже создана');
+
+		if (!$this->msg->keep) {
+			return 1;
+		}
+		return 0;
+	}
+}
+?>
\ No newline at end of file
diff --git a/download.php b/download.php
new file mode 100644
index 0000000..ac41fab
--- /dev/null
+++ b/download.php
@@ -0,0 +1,18 @@
+<?php
+$file = $_SERVER['DOCUMENT_ROOT'].'/'.$_GET['file'];
+
+if (file_exists($file)) {
+//	header('Content-Description: File Transfer');
+	header('Content-Type: application/octet-stream');
+	header('Content-Disposition: attachment; filename='.basename($file));
+	header('Content-Transfer-Encoding: binary');
+	header('Expires: 0');
+	header('Cache-Control: no-cache');
+	header('Pragma: no-cache');
+	header('Content-Length: ' . filesize($file));
+	ob_clean();
+	flush();
+	readfile($file);
+	exit;
+}
+?>
\ No newline at end of file
diff --git a/fonts/calibri.ttf b/fonts/calibri.ttf
new file mode 100644
index 0000000..8b6e3c9
Binary files /dev/null and b/fonts/calibri.ttf differ
diff --git a/fonts/calibrib.ttf b/fonts/calibrib.ttf
new file mode 100644
index 0000000..897d718
Binary files /dev/null and b/fonts/calibrib.ttf differ
diff --git a/js/jpicker-1.1.6.js b/js/jpicker-1.1.6.js
new file mode 100644
index 0000000..9e351d5
--- /dev/null
+++ b/js/jpicker-1.1.6.js
@@ -0,0 +1,2086 @@
+/*
+ * jPicker 1.1.6
+ *
+ * jQuery Plugin for Photoshop style color picker
+ *
+ * Copyright (c) 2010 Christopher T. Tillman
+ * Digital Magic Productions, Inc. (http://www.digitalmagicpro.com/)
+ * MIT style license, FREE to use, alter, copy, sell, and especially ENHANCE
+ *
+ * Painstakingly ported from John Dyers' excellent work on his own color picker based on the Prototype framework.
+ *
+ * John Dyers' website: (http://johndyer.name)
+ * Color Picker page:   (http://johndyer.name/post/2007/09/PhotoShop-like-JavaScript-Color-Picker.aspx)
+ *
+ */
+(function($, version)
+{
+  Math.precision = function(value, precision)
+    {
+      if (precision === undefined) precision = 0;
+      return Math.round(value * Math.pow(10, precision)) / Math.pow(10, precision);
+    };
+  var Slider = // encapsulate slider functionality for the ColorMap and ColorBar - could be useful to use a jQuery UI draggable for this with certain extensions
+      function(bar, options)
+      {
+        var $this = this, // private properties, methods, and events - keep these variables and classes invisible to outside code
+          arrow = bar.find('img:first'), // the arrow image to drag
+          minX = 0,
+          maxX = 100,
+          rangeX = 100,
+          minY = 0,
+          maxY = 100,
+          rangeY = 100,
+          x = 0,
+          y = 0,
+          offset,
+          timeout,
+          changeEvents = new Array(),
+          fireChangeEvents =
+            function(context)
+            {
+              for (var i = 0; i < changeEvents.length; i++) changeEvents[i].call($this, $this, context);
+            },
+          mouseDown = // bind the mousedown to the bar not the arrow for quick snapping to the clicked location
+            function(e)
+            {
+              var off = bar.offset();
+              offset = { l: off.left | 0, t: off.top | 0 };
+              clearTimeout(timeout);
+              timeout = setTimeout( // using setTimeout for visual updates - once the style is updated the browser will re-render internally allowing the next Javascript to run
+                function()
+                {
+                  setValuesFromMousePosition.call($this, e);
+                }, 0);
+              // Bind mousemove and mouseup event to the document so it responds when dragged of of the bar - we will unbind these when on mouseup to save processing
+              $(document).bind('mousemove', mouseMove).bind('mouseup', mouseUp);
+              e.preventDefault(); // don't try to select anything or drag the image to the desktop
+            },
+          mouseMove = // set the values as the mouse moves
+            function(e)
+            {
+              clearTimeout(timeout);
+              timeout = setTimeout(
+                function()
+                {
+                  setValuesFromMousePosition.call($this, e);
+                }, 0);
+              e.stopPropagation();
+              e.preventDefault();
+              return false;
+            },
+          mouseUp = // unbind the document events - they aren't needed when not dragging
+            function(e)
+            {
+              $(document).unbind('mouseup', mouseUp).unbind('mousemove', mouseMove);
+              e.stopPropagation();
+              e.preventDefault();
+              return false;
+            },
+          setValuesFromMousePosition = // calculate mouse position and set value within the current range
+            function(e)
+            {
+              var locX = e.pageX - offset.l,
+                  locY = e.pageY - offset.t,
+                  barW = bar.w, // local copies for YUI compressor
+                  barH = bar.h;
+              // keep the arrow within the bounds of the bar
+              if (locX < 0) locX = 0;
+              else if (locX > barW) locX = barW;
+              if (locY < 0) locY = 0;
+              else if (locY > barH) locY = barH;
+              val.call($this, 'xy', { x: ((locX / barW) * rangeX) + minX, y: ((locY / barH) * rangeY) + minY });
+            },
+          draw =
+            function()
+            {
+              var arrowOffsetX = 0,
+                arrowOffsetY = 0,
+                barW = bar.w,
+                barH = bar.h,
+                arrowW = arrow.w,
+                arrowH = arrow.h;
+              setTimeout(
+                function()
+                {
+                  if (rangeX > 0) // range is greater than zero
+                  {
+                    // constrain to bounds
+                    if (x == maxX) arrowOffsetX = barW;
+                    else arrowOffsetX = ((x / rangeX) * barW) | 0;
+                  }
+                  if (rangeY > 0) // range is greater than zero
+                  {
+                    // constrain to bounds
+                    if (y == maxY) arrowOffsetY = barH;
+                    else arrowOffsetY = ((y / rangeY) * barH) | 0;
+                  }
+                  // if arrow width is greater than bar width, center arrow and prevent horizontal dragging
+                  if (arrowW >= barW) arrowOffsetX = (barW >> 1) - (arrowW >> 1); // number >> 1 - superfast bitwise divide by two and truncate (move bits over one bit discarding lowest)
+                  else arrowOffsetX -= arrowW >> 1;
+                  // if arrow height is greater than bar height, center arrow and prevent vertical dragging
+                  if (arrowH >= barH) arrowOffsetY = (barH >> 1) - (arrowH >> 1);
+                  else arrowOffsetY -= arrowH >> 1;
+                  // set the arrow position based on these offsets
+                  arrow.css({ left: arrowOffsetX + 'px', top: arrowOffsetY + 'px' });
+                }, 0);
+            },
+          val =
+            function(name, value, context)
+            {
+              var set = value !== undefined;
+              if (!set)
+              {
+                if (name === undefined || name == null) name = 'xy';
+                switch (name.toLowerCase())
+                {
+                  case 'x': return x;
+                  case 'y': return y;
+                  case 'xy':
+                  default: return { x: x, y: y };
+                }
+              }
+              if (context != null && context == $this) return;
+              var changed = false,
+                  newX,
+                  newY;
+              if (name == null) name = 'xy';
+              switch (name.toLowerCase())
+              {
+                case 'x':
+                  newX = value && (value.x && value.x | 0 || value | 0) || 0;
+                  break;
+                case 'y':
+                  newY = value && (value.y && value.y | 0 || value | 0) || 0;
+                  break;
+                case 'xy':
+                default:
+                  newX = value && value.x && value.x | 0 || 0;
+                  newY = value && value.y && value.y | 0 || 0;
+                  break;
+              }
+              if (newX != null)
+              {
+                if (newX < minX) newX = minX;
+                else if (newX > maxX) newX = maxX;
+                if (x != newX)
+                {
+                  x = newX;
+                  changed = true;
+                }
+              }
+              if (newY != null)
+              {
+                if (newY < minY) newY = minY;
+                else if (newY > maxY) newY = maxY;
+                if (y != newY)
+                {
+                  y = newY;
+                  changed = true;
+                }
+              }
+              changed && fireChangeEvents.call($this, context || $this);
+            },
+          range =
+            function (name, value)
+            {
+              var set = value !== undefined;
+              if (!set)
+              {
+                if (name === undefined || name == null) name = 'all';
+                switch (name.toLowerCase())
+                {
+                  case 'minx': return minX;
+                  case 'maxx': return maxX;
+                  case 'rangex': return { minX: minX, maxX: maxX, rangeX: rangeX };
+                  case 'miny': return minY;
+                  case 'maxy': return maxY;
+                  case 'rangey': return { minY: minY, maxY: maxY, rangeY: rangeY };
+                  case 'all':
+                  default: return { minX: minX, maxX: maxX, rangeX: rangeX, minY: minY, maxY: maxY, rangeY: rangeY };
+                }
+              }
+              var changed = false,
+                  newMinX,
+                  newMaxX,
+                  newMinY,
+                  newMaxY;
+              if (name == null) name = 'all';
+              switch (name.toLowerCase())
+              {
+                case 'minx':
+                  newMinX = value && (value.minX && value.minX | 0 || value | 0) || 0;
+                  break;
+                case 'maxx':
+                  newMaxX = value && (value.maxX && value.maxX | 0 || value | 0) || 0;
+                  break;
+                case 'rangex':
+                  newMinX = value && value.minX && value.minX | 0 || 0;
+                  newMaxX = value && value.maxX && value.maxX | 0 || 0;
+                  break;
+                case 'miny':
+                  newMinY = value && (value.minY && value.minY | 0 || value | 0) || 0;
+                  break;
+                case 'maxy':
+                  newMaxY = value && (value.maxY && value.maxY | 0 || value | 0) || 0;
+                  break;
+                case 'rangey':
+                  newMinY = value && value.minY && value.minY | 0 || 0;
+                  newMaxY = value && value.maxY && value.maxY | 0 || 0;
+                  break;
+                case 'all':
+                default:
+                  newMinX = value && value.minX && value.minX | 0 || 0;
+                  newMaxX = value && value.maxX && value.maxX | 0 || 0;
+                  newMinY = value && value.minY && value.minY | 0 || 0;
+                  newMaxY = value && value.maxY && value.maxY | 0 || 0;
+                  break;
+              }
+              if (newMinX != null && minX != newMinX)
+              {
+                minX = newMinX;
+                rangeX = maxX - minX;
+              }
+              if (newMaxX != null && maxX != newMaxX)
+              {
+                maxX = newMaxX;
+                rangeX = maxX - minX;
+              }
+              if (newMinY != null && minY != newMinY)
+              {
+                minY = newMinY;
+                rangeY = maxY - minY;
+              }
+              if (newMaxY != null && maxY != newMaxY)
+              {
+                maxY = newMaxY;
+                rangeY = maxY - minY;
+              }
+            },
+          bind =
+            function (callback)
+            {
+              if ($.isFunction(callback)) changeEvents.push(callback);
+            },
+          unbind =
+            function (callback)
+            {
+              if (!$.isFunction(callback)) return;
+              var i;
+              while ((i = $.inArray(callback, changeEvents)) != -1) changeEvents.splice(i, 1);
+            },
+          destroy =
+            function()
+            {
+              // unbind all possible events and null objects
+              $(document).unbind('mouseup', mouseUp).unbind('mousemove', mouseMove);
+              bar.unbind('mousedown', mouseDown);
+              bar = null;
+              arrow = null;
+              changeEvents = null;
+            };
+        $.extend(true, $this, // public properties, methods, and event bindings - these we need to access from other controls
+          {
+            val: val,
+            range: range,
+            bind: bind,
+            unbind: unbind,
+            destroy: destroy
+          });
+        // initialize this control
+        arrow.src = options.arrow && options.arrow.image;
+        arrow.w = options.arrow && options.arrow.width || arrow.width();
+        arrow.h = options.arrow && options.arrow.height || arrow.height();
+        bar.w = options.map && options.map.width || bar.width();
+        bar.h = options.map && options.map.height || bar.height();
+        // bind mousedown event
+        bar.bind('mousedown', mouseDown);
+        bind.call($this, draw);
+      },
+    ColorValuePicker = // controls for all the input elements for the typing in color values
+      function(picker, color, bindedHex, alphaPrecision)
+      {
+        var $this = this, // private properties and methods
+          inputs = picker.find('td.Text input'),
+          red = inputs.eq(3),
+          green = inputs.eq(4),
+          blue = inputs.eq(5),
+          alpha = inputs.length > 7 ? inputs.eq(6) : null,
+          hue = inputs.eq(0),
+          saturation = inputs.eq(1),
+          value = inputs.eq(2),
+          hex = inputs.eq(inputs.length > 7 ? 7 : 6),
+          ahex = inputs.length > 7 ? inputs.eq(8) : null,
+          keyDown = // input box key down - use arrows to alter color
+            function(e)
+            {
+              if (e.target.value == '' && e.target != hex.get(0) && (bindedHex != null && e.target != bindedHex.get(0) || bindedHex == null)) return;
+              if (!validateKey(e)) return e;
+              switch (e.target)
+              {
+                case red.get(0):
+                  switch (e.keyCode)
+                  {
+                    case 38:
+                      red.val(setValueInRange.call($this, (red.val() << 0) + 1, 0, 255));
+                      color.val('r', red.val(), e.target);
+                      return false;
+                    case 40:
+                      red.val(setValueInRange.call($this, (red.val() << 0) - 1, 0, 255));
+                      color.val('r', red.val(), e.target);
+                      return false;
+                  }
+                  break;
+                case green.get(0):
+                  switch (e.keyCode)
+                  {
+                    case 38:
+                      green.val(setValueInRange.call($this, (green.val() << 0) + 1, 0, 255));
+                      color.val('g', green.val(), e.target);
+                      return false;
+                    case 40:
+                      green.val(setValueInRange.call($this, (green.val() << 0) - 1, 0, 255));
+                      color.val('g', green.val(), e.target);
+                      return false;
+                  }
+                  break;
+                case blue.get(0):
+                  switch (e.keyCode)
+                  {
+                    case 38:
+                      blue.val(setValueInRange.call($this, (blue.val() << 0) + 1, 0, 255));
+                      color.val('b', blue.val(), e.target);
+                      return false;
+                    case 40:
+                      blue.val(setValueInRange.call($this, (blue.val() << 0) - 1, 0, 255));
+                      color.val('b', blue.val(), e.target);
+                      return false;
+                  }
+                  break;
+                case alpha && alpha.get(0):
+                  switch (e.keyCode)
+                  {
+                    case 38:
+                      alpha.val(setValueInRange.call($this, parseFloat(alpha.val()) + 1, 0, 100));
+                      color.val('a', Math.precision((alpha.val() * 255) / 100, alphaPrecision), e.target);
+                      return false;
+                    case 40:
+                      alpha.val(setValueInRange.call($this, parseFloat(alpha.val()) - 1, 0, 100));
+                      color.val('a', Math.precision((alpha.val() * 255) / 100, alphaPrecision), e.target);
+                      return false;
+                  }
+                  break;
+                case hue.get(0):
+                  switch (e.keyCode)
+                  {
+                    case 38:
+                      hue.val(setValueInRange.call($this, (hue.val() << 0) + 1, 0, 360));
+                      color.val('h', hue.val(), e.target);
+                      return false;
+                    case 40:
+                      hue.val(setValueInRange.call($this, (hue.val() << 0) - 1, 0, 360));
+                      color.val('h', hue.val(), e.target);
+                      return false;
+                  }
+                  break;
+                case saturation.get(0):
+                  switch (e.keyCode)
+                  {
+                    case 38:
+                      saturation.val(setValueInRange.call($this, (saturation.val() << 0) + 1, 0, 100));
+                      color.val('s', saturation.val(), e.target);
+                      return false;
+                    case 40:
+                      saturation.val(setValueInRange.call($this, (saturation.val() << 0) - 1, 0, 100));
+                      color.val('s', saturation.val(), e.target);
+                      return false;
+                  }
+                  break;
+                case value.get(0):
+                  switch (e.keyCode)
+                  {
+                    case 38:
+                      value.val(setValueInRange.call($this, (value.val() << 0) + 1, 0, 100));
+                      color.val('v', value.val(), e.target);
+                      return false;
+                    case 40:
+                      value.val(setValueInRange.call($this, (value.val() << 0) - 1, 0, 100));
+                      color.val('v', value.val(), e.target);
+                      return false;
+                  }
+                  break;
+              }
+            },
+          keyUp = // input box key up - validate value and set color
+            function(e)
+            {
+              if (e.target.value == '' && e.target != hex.get(0) && (bindedHex != null && e.target != bindedHex.get(0) || bindedHex == null)) return;
+              if (!validateKey(e)) return e;
+              switch (e.target)
+              {
+                case red.get(0):
+                  red.val(setValueInRange.call($this, red.val(), 0, 255));
+                  color.val('r', red.val(), e.target);
+                  break;
+                case green.get(0):
+                  green.val(setValueInRange.call($this, green.val(), 0, 255));
+                  color.val('g', green.val(), e.target);
+                  break;
+                case blue.get(0):
+                  blue.val(setValueInRange.call($this, blue.val(), 0, 255));
+                  color.val('b', blue.val(), e.target);
+                  break;
+                case alpha && alpha.get(0):
+                  alpha.val(setValueInRange.call($this, alpha.val(), 0, 100));
+                  color.val('a', Math.precision((alpha.val() * 255) / 100, alphaPrecision), e.target);
+                  break;
+                case hue.get(0):
+                  hue.val(setValueInRange.call($this, hue.val(), 0, 360));
+                  color.val('h', hue.val(), e.target);
+                  break;
+                case saturation.get(0):
+                  saturation.val(setValueInRange.call($this, saturation.val(), 0, 100));
+                  color.val('s', saturation.val(), e.target);
+                  break;
+                case value.get(0):
+                  value.val(setValueInRange.call($this, value.val(), 0, 100));
+                  color.val('v', value.val(), e.target);
+                  break;
+                case hex.get(0):
+                  hex.val(hex.val().replace(/[^a-fA-F0-9]/g, '').toLowerCase().substring(0, 6));
+                  bindedHex && bindedHex.val(hex.val());
+                  color.val('hex', hex.val() != '' ? hex.val() : null, e.target);
+                  break;
+                case bindedHex && bindedHex.get(0):
+                  bindedHex.val(bindedHex.val().replace(/[^a-fA-F0-9]/g, '').toLowerCase().substring(0, 6));
+                  hex.val(bindedHex.val());
+                  color.val('hex', bindedHex.val() != '' ? bindedHex.val() : null, e.target);
+                  break;
+                case ahex && ahex.get(0):
+                  ahex.val(ahex.val().replace(/[^a-fA-F0-9]/g, '').toLowerCase().substring(0, 2));
+                  color.val('a', ahex.val() != null ? parseInt(ahex.val(), 16) : null, e.target);
+                  break;
+              }
+            },
+          blur = // input box blur - reset to original if value empty
+            function(e)
+            {
+              if (color.val() != null)
+              {
+                switch (e.target)
+                {
+                  case red.get(0): red.val(color.val('r')); break;
+                  case green.get(0): green.val(color.val('g')); break;
+                  case blue.get(0): blue.val(color.val('b')); break;
+                  case alpha && alpha.get(0): alpha.val(Math.precision((color.val('a') * 100) / 255, alphaPrecision)); break;
+                  case hue.get(0): hue.val(color.val('h')); break;
+                  case saturation.get(0): saturation.val(color.val('s')); break;
+                  case value.get(0): value.val(color.val('v')); break;
+                  case hex.get(0):
+                  case bindedHex && bindedHex.get(0):
+                    hex.val(color.val('hex'));
+                    bindedHex && bindedHex.val(color.val('hex'));
+                    break;
+                  case ahex && ahex.get(0): ahex.val(color.val('ahex').substring(6)); break;
+                }
+              }
+            },
+          validateKey = // validate key
+            function(e)
+            {
+              switch(e.keyCode)
+              {
+                case 9:
+                case 16:
+                case 29:
+                case 37:
+                case 39:
+                  return false;
+                case 'c'.charCodeAt():
+                case 'v'.charCodeAt():
+                  if (e.ctrlKey) return false;
+              }
+              return true;
+            },
+          setValueInRange = // constrain value within range
+            function(value, min, max)
+            {
+              if (value == '' || isNaN(value)) return min;
+              if (value > max) return max;
+              if (value < min) return min;
+              return value;
+            },
+          colorChanged =
+            function(ui, context)
+            {
+              var all = ui.val('all');
+              if (context != red.get(0)) red.val(all != null ? all.r : '');
+              if (context != green.get(0)) green.val(all != null ? all.g : '');
+              if (context != blue.get(0)) blue.val(all != null ? all.b : '');
+              if (alpha && context != alpha.get(0)) alpha.val(all != null ? Math.precision((all.a * 100) / 255, alphaPrecision) : '');
+              if (context != hue.get(0)) hue.val(all != null ? all.h : '');
+              if (context != saturation.get(0)) saturation.val(all != null ? all.s : '');
+              if (context != value.get(0)) value.val(all != null ? all.v : '');
+              if (context != hex.get(0) && (bindedHex && context != bindedHex.get(0) || !bindedHex)) hex.val(all != null ? all.hex : '');
+              if (bindedHex && context != bindedHex.get(0) && context != hex.get(0)) bindedHex.val(all != null ? all.hex : '');
+              if (ahex && context != ahex.get(0)) ahex.val(all != null ? all.ahex.substring(6) : '');
+            },
+          destroy =
+            function()
+            {
+              // unbind all events and null objects
+              red.add(green).add(blue).add(alpha).add(hue).add(saturation).add(value).add(hex).add(bindedHex).add(ahex).unbind('keyup', keyUp).unbind('blur', blur);
+              red.add(green).add(blue).add(alpha).add(hue).add(saturation).add(value).unbind('keydown', keyDown);
+              color.unbind(colorChanged);
+              red = null;
+              green = null;
+              blue = null;
+              alpha = null;
+              hue = null;
+              saturation = null;
+              value = null;
+              hex = null;
+              ahex = null;
+            };
+        $.extend(true, $this, // public properties and methods
+          {
+            destroy: destroy
+          });
+        red.add(green).add(blue).add(alpha).add(hue).add(saturation).add(value).add(hex).add(bindedHex).add(ahex).bind('keyup', keyUp).bind('blur', blur);
+        red.add(green).add(blue).add(alpha).add(hue).add(saturation).add(value).bind('keydown', keyDown);
+        color.bind(colorChanged);
+      };
+  $.jPicker =
+    {
+      List: [], // array holding references to each active instance of the control
+      Color: // color object - we will be able to assign by any color space type or retrieve any color space info
+             // we want this public so we can optionally assign new color objects to initial values using inputs other than a string hex value (also supported)
+        function(init)
+        {
+          var $this = this,
+            r,
+            g,
+            b,
+            a,
+            h,
+            s,
+            v,
+            changeEvents = new Array(),
+            fireChangeEvents = 
+              function(context)
+              {
+                for (var i = 0; i < changeEvents.length; i++) changeEvents[i].call($this, $this, context);
+              },
+            val =
+              function(name, value, context)
+              {
+                var set = value !== undefined;
+                if (!set)
+                {
+                  if (name === undefined || name == null || name == '') name = 'all';
+                  if (r == null) return null;
+                  switch (name.toLowerCase())
+                  {
+                    case 'ahex': return ColorMethods.rgbaToHex({ r: r, g: g, b: b, a: a });
+                    case 'hex': return val('ahex').substring(0, 6);
+                    case 'all': return { r: r, g: g, b: b, a: a, h: h, s: s, v: v, hex: val.call($this, 'hex'), ahex: val.call($this, 'ahex') };
+                    default:
+                      var ret={};
+                      for (var i = 0; i < name.length; i++)
+                      {
+                        switch (name.charAt(i))
+                        {
+                          case 'r':
+                            if (name.length == 1) ret = r;
+                            else ret.r = r;
+                            break;
+                          case 'g':
+                            if (name.length == 1) ret = g;
+                            else ret.g = g;
+                            break;
+                          case 'b':
+                            if (name.length == 1) ret = b;
+                            else ret.b = b;
+                            break;
+                          case 'a':
+                            if (name.length == 1) ret = a;
+                            else ret.a = a;
+                            break;
+                          case 'h':
+                            if (name.length == 1) ret = h;
+                            else ret.h = h;
+                            break;
+                          case 's':
+                            if (name.length == 1) ret = s;
+                            else ret.s = s;
+                            break;
+                          case 'v':
+                            if (name.length == 1) ret = v;
+                            else ret.v = v;
+                            break;
+                        }
+                      }
+                      return ret == {} ? val.call($this, 'all') : ret;
+                      break;
+                  }
+                }
+                if (context != null && context == $this) return;
+                var changed = false;
+                if (name == null) name = '';
+                if (value == null)
+                {
+                  if (r != null)
+                  {
+                    r = null;
+                    changed = true;
+                  }
+                  if (g != null)
+                  {
+                    g = null;
+                    changed = true;
+                  }
+                  if (b != null)
+                  {
+                    b = null;
+                    changed = true;
+                  }
+                  if (a != null)
+                  {
+                    a = null;
+                    changed = true;
+                  }
+                  if (h != null)
+                  {
+                    h = null;
+                    changed = true;
+                  }
+                  if (s != null)
+                  {
+                    s = null;
+                    changed = true;
+                  }
+                  if (v != null)
+                  {
+                    v = null;
+                    changed = true;
+                  }
+                  changed && fireChangeEvents.call($this, context || $this);
+                  return;
+                }
+                switch (name.toLowerCase())
+                {
+                  case 'ahex':
+                  case 'hex':
+                    var ret = ColorMethods.hexToRgba(value && (value.ahex || value.hex) || value || '00000000');
+                    val.call($this, 'rgba', { r: ret.r, g: ret.g, b: ret.b, a: name == 'ahex' ? ret.a : a != null ? a : 255 }, context);
+                    break;
+                  default:
+                    if (value && (value.ahex != null || value.hex != null))
+                    {
+                      val.call($this, 'ahex', value.ahex || value.hex || '00000000', context);
+                      return;
+                    }
+                    var newV = {}, rgb = false, hsv = false;
+                    if (value.r !== undefined && !name.indexOf('r') == -1) name += 'r';
+                    if (value.g !== undefined && !name.indexOf('g') == -1) name += 'g';
+                    if (value.b !== undefined && !name.indexOf('b') == -1) name += 'b';
+                    if (value.a !== undefined && !name.indexOf('a') == -1) name += 'a';
+                    if (value.h !== undefined && !name.indexOf('h') == -1) name += 'h';
+                    if (value.s !== undefined && !name.indexOf('s') == -1) name += 's';
+                    if (value.v !== undefined && !name.indexOf('v') == -1) name += 'v';
+                    for (var i = 0; i < name.length; i++)
+                    {
+                      switch (name.charAt(i))
+                      {
+                        case 'r':
+                          if (hsv) continue;
+                          rgb = true;
+                          newV.r = value && value.r && value.r | 0 || value && value | 0 || 0;
+                          if (newV.r < 0) newV.r = 0;
+                          else if (newV.r > 255) newV.r = 255;
+                          if (r != newV.r)
+                          {
+                            r = newV.r;
+                            changed = true;
+                          }
+                          break;
+                        case 'g':
+                          if (hsv) continue;
+                          rgb = true;
+                          newV.g = value && value.g && value.g | 0 || value && value | 0 || 0;
+                          if (newV.g < 0) newV.g = 0;
+                          else if (newV.g > 255) newV.g = 255;
+                          if (g != newV.g)
+                          {
+                            g = newV.g;
+                            changed = true;
+                          }
+                          break;
+                        case 'b':
+                          if (hsv) continue;
+                          rgb = true;
+                          newV.b = value && value.b && value.b | 0 || value && value | 0 || 0;
+                          if (newV.b < 0) newV.b = 0;
+                          else if (newV.b > 255) newV.b = 255;
+                          if (b != newV.b)
+                          {
+                            b = newV.b;
+                            changed = true;
+                          }
+                          break;
+                        case 'a':
+                          newV.a = value && value.a != null ? value.a | 0 : value != null ? value | 0 : 255;
+                          if (newV.a < 0) newV.a = 0;
+                          else if (newV.a > 255) newV.a = 255;
+                          if (a != newV.a)
+                          {
+                            a = newV.a;
+                            changed = true;
+                          }
+                          break;
+                        case 'h':
+                          if (rgb) continue;
+                          hsv = true;
+                          newV.h = value && value.h && value.h | 0 || value && value | 0 || 0;
+                          if (newV.h < 0) newV.h = 0;
+                          else if (newV.h > 360) newV.h = 360;
+                          if (h != newV.h)
+                          {
+                            h = newV.h;
+                            changed = true;
+                          }
+                          break;
+                        case 's':
+                          if (rgb) continue;
+                          hsv = true;
+                          newV.s = value && value.s != null ? value.s | 0 : value != null ? value | 0 : 100;
+                          if (newV.s < 0) newV.s = 0;
+                          else if (newV.s > 100) newV.s = 100;
+                          if (s != newV.s)
+                          {
+                            s = newV.s;
+                            changed = true;
+                          }
+                          break;
+                        case 'v':
+                          if (rgb) continue;
+                          hsv = true;
+                          newV.v = value && value.v != null ? value.v | 0 : value != null ? value | 0 : 100;
+                          if (newV.v < 0) newV.v = 0;
+                          else if (newV.v > 100) newV.v = 100;
+                          if (v != newV.v)
+                          {
+                            v = newV.v;
+                            changed = true;
+                          }
+                          break;
+                      }
+                    }
+                    if (changed)
+                    {
+                      if (rgb)
+                      {
+                        r = r || 0;
+                        g = g || 0;
+                        b = b || 0;
+                        var ret = ColorMethods.rgbToHsv({ r: r, g: g, b: b });
+                        h = ret.h;
+                        s = ret.s;
+                        v = ret.v;
+                      }
+                      else if (hsv)
+                      {
+                        h = h || 0;
+                        s = s != null ? s : 100;
+                        v = v != null ? v : 100;
+                        var ret = ColorMethods.hsvToRgb({ h: h, s: s, v: v });
+                        r = ret.r;
+                        g = ret.g;
+                        b = ret.b;
+                      }
+                      a = a != null ? a : 255;
+                      fireChangeEvents.call($this, context || $this);
+                    }
+                    break;
+                }
+              },
+            bind =
+              function(callback)
+              {
+                if ($.isFunction(callback)) changeEvents.push(callback);
+              },
+            unbind =
+              function(callback)
+              {
+                if (!$.isFunction(callback)) return;
+                var i;
+                while ((i = $.inArray(callback, changeEvents)) != -1) changeEvents.splice(i, 1);
+              },
+            destroy =
+              function()
+              {
+                changeEvents = null;
+              }
+          $.extend(true, $this, // public properties and methods
+            {
+              val: val,
+              bind: bind,
+              unbind: unbind,
+              destroy: destroy
+            });
+          if (init)
+          {
+            if (init.ahex != null) val('ahex', init);
+            else if (init.hex != null) val((init.a != null ? 'a' : '') + 'hex', init.a != null ? { ahex: init.hex + ColorMethods.intToHex(init.a) } : init);
+            else if (init.r != null && init.g != null && init.b != null) val('rgb' + (init.a != null ? 'a' : ''), init);
+            else if (init.h != null && init.s != null && init.v != null) val('hsv' + (init.a != null ? 'a' : ''), init);
+          }
+        },
+      ColorMethods: // color conversion methods  - make public to give use to external scripts
+        {
+          hexToRgba:
+            function(hex)
+            {
+              hex = this.validateHex(hex);
+              if (hex == '') return { r: null, g: null, b: null, a: null };
+              var r = '00', g = '00', b = '00', a = '255';
+              if (hex.length == 6) hex += 'ff';
+              if (hex.length > 6)
+              {
+                r = hex.substring(0, 2);
+                g = hex.substring(2, 4);
+                b = hex.substring(4, 6);
+                a = hex.substring(6, hex.length);
+              }
+              else
+              {
+                if (hex.length > 4)
+                {
+                  r = hex.substring(4, hex.length);
+                  hex = hex.substring(0, 4);
+                }
+                if (hex.length > 2)
+                {
+                  g = hex.substring(2, hex.length);
+                  hex = hex.substring(0, 2);
+                }
+                if (hex.length > 0) b = hex.substring(0, hex.length);
+              }
+              return { r: this.hexToInt(r), g: this.hexToInt(g), b: this.hexToInt(b), a: this.hexToInt(a) };
+            },
+          validateHex:
+            function(hex)
+            {
+              hex = hex.toLowerCase().replace(/[^a-f0-9]/g, '');
+              if (hex.length > 8) hex = hex.substring(0, 8);
+              return hex;
+            },
+          rgbaToHex:
+            function(rgba)
+            {
+              return this.intToHex(rgba.r) + this.intToHex(rgba.g) + this.intToHex(rgba.b) + this.intToHex(rgba.a);
+            },
+          intToHex:
+            function(dec)
+            {
+              var result = (dec | 0).toString(16);
+              if (result.length == 1) result = ('0' + result);
+              return result.toLowerCase();
+            },
+          hexToInt:
+            function(hex)
+            {
+              return parseInt(hex, 16);
+            },
+          rgbToHsv:
+            function(rgb)
+            {
+              var r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255, hsv = { h: 0, s: 0, v: 0 }, min = 0, max = 0, delta;
+              if (r >= g && r >= b)
+              {
+                max = r;
+                min = g > b ? b : g;
+              }
+              else if (g >= b && g >= r)
+              {
+                max = g;
+                min = r > b ? b : r;
+              }
+              else
+              {
+                max = b;
+                min = g > r ? r : g;
+              }
+              hsv.v = max;
+              hsv.s = max ? (max - min) / max : 0;
+              if (!hsv.s) hsv.h = 0;
+              else
+              {
+                delta = max - min;
+                if (r == max) hsv.h = (g - b) / delta;
+                else if (g == max) hsv.h = 2 + (b - r) / delta;
+                else hsv.h = 4 + (r - g) / delta;
+                hsv.h = parseInt(hsv.h * 60);
+                if (hsv.h < 0) hsv.h += 360;
+              }
+              hsv.s = (hsv.s * 100) | 0;
+              hsv.v = (hsv.v * 100) | 0;
+              return hsv;
+            },
+          hsvToRgb:
+            function(hsv)
+            {
+              var rgb = { r: 0, g: 0, b: 0, a: 100 }, h = hsv.h, s = hsv.s, v = hsv.v;
+              if (s == 0)
+              {
+                if (v == 0) rgb.r = rgb.g = rgb.b = 0;
+                else rgb.r = rgb.g = rgb.b = (v * 255 / 100) | 0;
+              }
+              else
+              {
+                if (h == 360) h = 0;
+                h /= 60;
+                s = s / 100;
+                v = v / 100;
+                var i = h | 0,
+                    f = h - i,
+                    p = v * (1 - s),
+                    q = v * (1 - (s * f)),
+                    t = v * (1 - (s * (1 - f)));
+                switch (i)
+                {
+                  case 0:
+                    rgb.r = v;
+                    rgb.g = t;
+                    rgb.b = p;
+                    break;
+                  case 1:
+                    rgb.r = q;
+                    rgb.g = v;
+                    rgb.b = p;
+                    break;
+                  case 2:
+                    rgb.r = p;
+                    rgb.g = v;
+                    rgb.b = t;
+                    break;
+                  case 3:
+                    rgb.r = p;
+                    rgb.g = q;
+                    rgb.b = v;
+                    break;
+                  case 4:
+                    rgb.r = t;
+                    rgb.g = p;
+                    rgb.b = v;
+                    break;
+                  case 5:
+                    rgb.r = v;
+                    rgb.g = p;
+                    rgb.b = q;
+                    break;
+                }
+                rgb.r = (rgb.r * 255) | 0;
+                rgb.g = (rgb.g * 255) | 0;
+                rgb.b = (rgb.b * 255) | 0;
+              }
+              return rgb;
+            }
+        }
+    };
+  var Color = $.jPicker.Color, List = $.jPicker.List, ColorMethods = $.jPicker.ColorMethods; // local copies for YUI compressor
+  $.fn.jPicker =
+    function(options)
+    {
+      var $arguments = arguments;
+      return this.each(
+        function()
+        {
+          var $this = this, settings = $.extend(true, {}, $.fn.jPicker.defaults, options); // local copies for YUI compressor
+          if ($($this).get(0).nodeName.toLowerCase() == 'input') // Add color picker icon if binding to an input element and bind the events to the input
+          {
+            $.extend(true, settings,
+              {
+                window:
+                {
+                  bindToInput: true,
+                  expandable: true,
+                  input: $($this)
+                }
+              });
+            if($($this).val()=='')
+            {
+              settings.color.active = new Color({ hex: null });
+              settings.color.current = new Color({ hex: null });
+            }
+            else if (ColorMethods.validateHex($($this).val()))
+            {
+              settings.color.active = new Color({ hex: $($this).val(), a: settings.color.active.val('a') });
+              settings.color.current = new Color({ hex: $($this).val(), a: settings.color.active.val('a') });
+            }
+          }
+          if (settings.window.expandable)
+            $($this).after('<span class="jPicker"><span class="Icon"><span class="Color">&nbsp;</span><span class="Alpha">&nbsp;</span><span class="Image" title="Click To Open Color Picker">&nbsp;</span><span class="Container">&nbsp;</span></span></span>');
+          else settings.window.liveUpdate = false; // Basic control binding for inline use - You will need to override the liveCallback or commitCallback function to retrieve results
+          var isLessThanIE7 = parseFloat(navigator.appVersion.split('MSIE')[1]) < 7 && document.body.filters, // needed to run the AlphaImageLoader function for IE6
+            container = null,
+            colorMapDiv = null,
+            colorBarDiv = null,
+            colorMapL1 = null, // different layers of colorMap and colorBar
+            colorMapL2 = null,
+            colorMapL3 = null,
+            colorBarL1 = null,
+            colorBarL2 = null,
+            colorBarL3 = null,
+            colorBarL4 = null,
+            colorBarL5 = null,
+            colorBarL6 = null,
+            colorMap = null, // color maps
+            colorBar = null,
+            colorPicker = null,
+            elementStartX = null, // Used to record the starting css positions for dragging the control
+            elementStartY = null,
+            pageStartX = null, // Used to record the mousedown coordinates for dragging the control
+            pageStartY = null,
+            activePreview = null, // color boxes above the radio buttons
+            currentPreview = null,
+            okButton = null,
+            cancelButton = null,
+            grid = null, // preset colors grid
+            iconColor = null, // iconColor for popup icon
+            iconAlpha = null, // iconAlpha for popup icon
+            iconImage = null, // iconImage popup icon
+            moveBar = null, // drag bar
+            setColorMode = // set color mode and update visuals for the new color mode
+              function(colorMode)
+              {
+                var active = color.active, // local copies for YUI compressor
+                  clientPath = images.clientPath,
+                  hex = active.val('hex'),
+                  rgbMap,
+                  rgbBar;
+                settings.color.mode = colorMode;
+                switch (colorMode)
+                {
+                  case 'h':
+                    setTimeout(
+                      function()
+                      {
+                        setBG.call($this, colorMapDiv, 'transparent');
+                        setImgLoc.call($this, colorMapL1, 0);
+                        setAlpha.call($this, colorMapL1, 100);
+                        setImgLoc.call($this, colorMapL2, 260);
+                        setAlpha.call($this, colorMapL2, 100);
+                        setBG.call($this, colorBarDiv, 'transparent');
+                        setImgLoc.call($this, colorBarL1, 0);
+                        setAlpha.call($this, colorBarL1, 100);
+                        setImgLoc.call($this, colorBarL2, 260);
+                        setAlpha.call($this, colorBarL2, 100);
+                        setImgLoc.call($this, colorBarL3, 260);
+                        setAlpha.call($this, colorBarL3, 100);
+                        setImgLoc.call($this, colorBarL4, 260);
+                        setAlpha.call($this, colorBarL4, 100);
+                        setImgLoc.call($this, colorBarL6, 260);
+                        setAlpha.call($this, colorBarL6, 100);
+                      }, 0);
+                    colorMap.range('all', { minX: 0, maxX: 100, minY: 0, maxY: 100 });
+                    colorBar.range('rangeY', { minY: 0, maxY: 360 });
+                    if (active.val('ahex') == null) break;
+                    colorMap.val('xy', { x: active.val('s'), y: 100 - active.val('v') }, colorMap);
+                    colorBar.val('y', 360 - active.val('h'), colorBar);
+                    break;
+                  case 's':
+                    setTimeout(
+                      function()
+                      {
+                        setBG.call($this, colorMapDiv, 'transparent');
+                        setImgLoc.call($this, colorMapL1, -260);
+                        setImgLoc.call($this, colorMapL2, -520);
+                        setImgLoc.call($this, colorBarL1, -260);
+                        setImgLoc.call($this, colorBarL2, -520);
+                        setImgLoc.call($this, colorBarL6, 260);
+                        setAlpha.call($this, colorBarL6, 100);
+                      }, 0);
+                    colorMap.range('all', { minX: 0, maxX: 360, minY: 0, maxY: 100 });
+                    colorBar.range('rangeY', { minY: 0, maxY: 100 });
+                    if (active.val('ahex') == null) break;
+                    colorMap.val('xy', { x: active.val('h'), y: 100 - active.val('v') }, colorMap);
+                    colorBar.val('y', 100 - active.val('s'), colorBar);
+                    break;
+                  case 'v':
+                    setTimeout(
+                      function()
+                      {
+                        setBG.call($this, colorMapDiv, '000000');
+                        setImgLoc.call($this, colorMapL1, -780);
+                        setImgLoc.call($this, colorMapL2, 260);
+                        setBG.call($this, colorBarDiv, hex);
+                        setImgLoc.call($this, colorBarL1, -520);
+                        setImgLoc.call($this, colorBarL2, 260);
+                        setAlpha.call($this, colorBarL2, 100);
+                        setImgLoc.call($this, colorBarL6, 260);
+                        setAlpha.call($this, colorBarL6, 100);
+                      }, 0);
+                    colorMap.range('all', { minX: 0, maxX: 360, minY: 0, maxY: 100 });
+                    colorBar.range('rangeY', { minY: 0, maxY: 100 });
+                    if (active.val('ahex') == null) break;
+                    colorMap.val('xy', { x: active.val('h'), y: 100 - active.val('s') }, colorMap);
+                    colorBar.val('y', 100 - active.val('v'), colorBar);
+                    break;
+                  case 'r':
+                    rgbMap = -1040;
+                    rgbBar = -780;
+                    colorMap.range('all', { minX: 0, maxX: 255, minY: 0, maxY: 255 });
+                    colorBar.range('rangeY', { minY: 0, maxY: 255 });
+                    if (active.val('ahex') == null) break;
+                    colorMap.val('xy', { x: active.val('b'), y: 255 - active.val('g') }, colorMap);
+                    colorBar.val('y', 255 - active.val('r'), colorBar);
+                    break;
+                  case 'g':
+                    rgbMap = -1560;
+                    rgbBar = -1820;
+                    colorMap.range('all', { minX: 0, maxX: 255, minY: 0, maxY: 255 });
+                    colorBar.range('rangeY', { minY: 0, maxY: 255 });
+                    if (active.val('ahex') == null) break;
+                    colorMap.val('xy', { x: active.val('b'), y: 255 - active.val('r') }, colorMap);
+                    colorBar.val('y', 255 - active.val('g'), colorBar);
+                    break;
+                  case 'b':
+                    rgbMap = -2080;
+                    rgbBar = -2860;
+                    colorMap.range('all', { minX: 0, maxX: 255, minY: 0, maxY: 255 });
+                    colorBar.range('rangeY', { minY: 0, maxY: 255 });
+                    if (active.val('ahex') == null) break;
+                    colorMap.val('xy', { x: active.val('r'), y: 255 - active.val('g') }, colorMap);
+                    colorBar.val('y', 255 - active.val('b'), colorBar);
+                    break;
+                  case 'a':
+                    setTimeout(
+                      function()
+                      {
+                        setBG.call($this, colorMapDiv, 'transparent');
+                        setImgLoc.call($this, colorMapL1, -260);
+                        setImgLoc.call($this, colorMapL2, -520);
+                        setImgLoc.call($this, colorBarL1, 260);
+                        setImgLoc.call($this, colorBarL2, 260);
+                        setAlpha.call($this, colorBarL2, 100);
+                        setImgLoc.call($this, colorBarL6, 0);
+                        setAlpha.call($this, colorBarL6, 100);
+                      }, 0);
+                    colorMap.range('all', { minX: 0, maxX: 360, minY: 0, maxY: 100 });
+                    colorBar.range('rangeY', { minY: 0, maxY: 255 });
+                    if (active.val('ahex') == null) break;
+                    colorMap.val('xy', { x: active.val('h'), y: 100 - active.val('v') }, colorMap);
+                    colorBar.val('y', 255 - active.val('a'), colorBar);
+                    break;
+                  default:
+                    throw ('Invalid Mode');
+                    break;
+                }
+                switch (colorMode)
+                {
+                  case 'h':
+                    break;
+                  case 's':
+                  case 'v':
+                  case 'a':
+                    setTimeout(
+                      function()
+                      {
+                        setAlpha.call($this, colorMapL1, 100);
+                        setAlpha.call($this, colorBarL1, 100);
+                        setImgLoc.call($this, colorBarL3, 260);
+                        setAlpha.call($this, colorBarL3, 100);
+                        setImgLoc.call($this, colorBarL4, 260);
+                        setAlpha.call($this, colorBarL4, 100);
+                      }, 0);
+                    break;
+                  case 'r':
+                  case 'g':
+                  case 'b':
+                    setTimeout(
+                      function()
+                      {
+                        setBG.call($this, colorMapDiv, 'transparent');
+                        setBG.call($this, colorBarDiv, 'transparent');
+                        setAlpha.call($this, colorBarL1, 100);
+                        setAlpha.call($this, colorMapL1, 100);
+                        setImgLoc.call($this, colorMapL1, rgbMap);
+                        setImgLoc.call($this, colorMapL2, rgbMap - 260);
+                        setImgLoc.call($this, colorBarL1, rgbBar - 780);
+                        setImgLoc.call($this, colorBarL2, rgbBar - 520);
+                        setImgLoc.call($this, colorBarL3, rgbBar);
+                        setImgLoc.call($this, colorBarL4, rgbBar - 260);
+                        setImgLoc.call($this, colorBarL6, 260);
+                        setAlpha.call($this, colorBarL6, 100);
+                      }, 0);
+                    break;
+                }
+                if (active.val('ahex') == null) return;
+                activeColorChanged.call($this, active);
+              },
+            activeColorChanged = // Update color when user changes text values
+              function(ui, context)
+              {
+                if (context == null || (context != colorBar && context != colorMap)) positionMapAndBarArrows.call($this, ui, context);
+                setTimeout(
+                  function()
+                  {
+                    updatePreview.call($this, ui);
+                    updateMapVisuals.call($this, ui);
+                    updateBarVisuals.call($this, ui);
+                  }, 0);
+              },
+            mapValueChanged = // user has dragged the ColorMap pointer
+              function(ui, context)
+              {
+                var active = color.active;
+                if (context != colorMap && active.val() == null) return;
+                var xy = ui.val('all');
+                switch (settings.color.mode)
+                {
+                  case 'h':
+                    active.val('sv', { s: xy.x, v: 100 - xy.y }, context);
+                    break;
+                  case 's':
+                  case 'a':
+                    active.val('hv', { h: xy.x, v: 100 - xy.y }, context);
+                    break;
+                  case 'v':
+                    active.val('hs', { h: xy.x, s: 100 - xy.y }, context);
+                    break;
+                  case 'r':
+                    active.val('gb', { g: 255 - xy.y, b: xy.x }, context);
+                    break;
+                  case 'g':
+                    active.val('rb', { r: 255 - xy.y, b: xy.x }, context);
+                    break;
+                  case 'b':
+                    active.val('rg', { r: xy.x, g: 255 - xy.y }, context);
+                    break;
+                }
+              },
+            colorBarValueChanged = // user has dragged the ColorBar slider
+              function(ui, context)
+              {
+                var active = color.active;
+                if (context != colorBar && active.val() == null) return;
+                switch (settings.color.mode)
+                {
+                  case 'h':
+                    active.val('h', { h: 360 - ui.val('y') }, context);
+                    break;
+                  case 's':
+                    active.val('s', { s: 100 - ui.val('y') }, context);
+                    break;
+                  case 'v':
+                    active.val('v', { v: 100 - ui.val('y') }, context);
+                    break;
+                  case 'r':
+                    active.val('r', { r: 255 - ui.val('y') }, context);
+                    break;
+                  case 'g':
+                    active.val('g', { g: 255 - ui.val('y') }, context);
+                    break;
+                  case 'b':
+                    active.val('b', { b: 255 - ui.val('y') }, context);
+                    break;
+                  case 'a':
+                    active.val('a', 255 - ui.val('y'), context);
+                    break;
+                }
+              },
+            positionMapAndBarArrows = // position map and bar arrows to match current color
+              function(ui, context)
+              {
+                if (context != colorMap)
+                {
+                  switch (settings.color.mode)
+                  {
+                    case 'h':
+                      var sv = ui.val('sv');
+                      colorMap.val('xy', { x: sv != null ? sv.s : 100, y: 100 - (sv != null ? sv.v : 100) }, context);
+                      break;
+                    case 's':
+                    case 'a':
+                      var hv = ui.val('hv');
+                      colorMap.val('xy', { x: hv && hv.h || 0, y: 100 - (hv != null ? hv.v : 100) }, context);
+                      break;
+                    case 'v':
+                      var hs = ui.val('hs');
+                      colorMap.val('xy', { x: hs && hs.h || 0, y: 100 - (hs != null ? hs.s : 100) }, context);
+                      break;
+                    case 'r':
+                      var bg = ui.val('bg');
+                      colorMap.val('xy', { x: bg && bg.b || 0, y: 255 - (bg && bg.g || 0) }, context);
+                      break;
+                    case 'g':
+                      var br = ui.val('br');
+                      colorMap.val('xy', { x: br && br.b || 0, y: 255 - (br && br.r || 0) }, context);
+                      break;
+                    case 'b':
+                      var rg = ui.val('rg');
+                      colorMap.val('xy', { x: rg && rg.r || 0, y: 255 - (rg && rg.g || 0) }, context);
+                      break;
+                  }
+                }
+                if (context != colorBar)
+                {
+                  switch (settings.color.mode)
+                  {
+                    case 'h':
+                      colorBar.val('y', 360 - (ui.val('h') || 0), context);
+                      break;
+                    case 's':
+                      var s = ui.val('s');
+                      colorBar.val('y', 100 - (s != null ? s : 100), context);
+                      break;
+                    case 'v':
+                      var v = ui.val('v');
+                      colorBar.val('y', 100 - (v != null ? v : 100), context);
+                      break;
+                    case 'r':
+                      colorBar.val('y', 255 - (ui.val('r') || 0), context);
+                      break;
+                    case 'g':
+                      colorBar.val('y', 255 - (ui.val('g') || 0), context);
+                      break;
+                    case 'b':
+                      colorBar.val('y', 255 - (ui.val('b') || 0), context);
+                      break;
+                    case 'a':
+                      var a = ui.val('a');
+                      colorBar.val('y', 255 - (a != null ? a : 255), context);
+                      break;
+                  }
+                }
+              },
+            updatePreview =
+              function(ui)
+              {
+                try
+                {
+                  var all = ui.val('all');
+                  activePreview.css({ backgroundColor: all && '#' + all.hex || 'transparent' });
+                  setAlpha.call($this, activePreview, all && Math.precision((all.a * 100) / 255, 4) || 0);
+                }
+                catch (e) { }
+              },
+            updateMapVisuals =
+              function(ui)
+              {
+                switch (settings.color.mode)
+                {
+                  case 'h':
+                    setBG.call($this, colorMapDiv, new Color({ h: ui.val('h') || 0, s: 100, v: 100 }).val('hex'));
+                    break;
+                  case 's':
+                  case 'a':
+                    var s = ui.val('s');
+                    setAlpha.call($this, colorMapL2, 100 - (s != null ? s : 100));
+                    break;
+                  case 'v':
+                    var v = ui.val('v');
+                    setAlpha.call($this, colorMapL1, v != null ? v : 100);
+                    break;
+                  case 'r':
+                    setAlpha.call($this, colorMapL2, Math.precision((ui.val('r') || 0) / 255 * 100, 4));
+                    break;
+                  case 'g':
+                    setAlpha.call($this, colorMapL2, Math.precision((ui.val('g') || 0) / 255 * 100, 4));
+                    break;
+                  case 'b':
+                    setAlpha.call($this, colorMapL2, Math.precision((ui.val('b') || 0) / 255 * 100));
+                    break;
+                }
+                var a = ui.val('a');
+                setAlpha.call($this, colorMapL3, Math.precision(((255 - (a || 0)) * 100) / 255, 4));
+              },
+            updateBarVisuals =
+              function(ui)
+              {
+                switch (settings.color.mode)
+                {
+                  case 'h':
+                    var a = ui.val('a');
+                    setAlpha.call($this, colorBarL5, Math.precision(((255 - (a || 0)) * 100) / 255, 4));
+                    break;
+                  case 's':
+                    var hva = ui.val('hva'),
+                        saturatedColor = new Color({ h: hva && hva.h || 0, s: 100, v: hva != null ? hva.v : 100 });
+                    setBG.call($this, colorBarDiv, saturatedColor.val('hex'));
+                    setAlpha.call($this, colorBarL2, 100 - (hva != null ? hva.v : 100));
+                    setAlpha.call($this, colorBarL5, Math.precision(((255 - (hva && hva.a || 0)) * 100) / 255, 4));
+                    break;
+                  case 'v':
+                    var hsa = ui.val('hsa'),
+                        valueColor = new Color({ h: hsa && hsa.h || 0, s: hsa != null ? hsa.s : 100, v: 100 });
+                    setBG.call($this, colorBarDiv, valueColor.val('hex'));
+                    setAlpha.call($this, colorBarL5, Math.precision(((255 - (hsa && hsa.a || 0)) * 100) / 255, 4));
+                    break;
+                  case 'r':
+                  case 'g':
+                  case 'b':
+                    var hValue = 0, vValue = 0, rgba = ui.val('rgba');
+                    if (settings.color.mode == 'r')
+                    {
+                      hValue = rgba && rgba.b || 0;
+                      vValue = rgba && rgba.g || 0;
+                    }
+                    else if (settings.color.mode == 'g')
+                    {
+                      hValue = rgba && rgba.b || 0;
+                      vValue = rgba && rgba.r || 0;
+                    }
+                    else if (settings.color.mode == 'b')
+                    {
+                      hValue = rgba && rgba.r || 0;
+                      vValue = rgba && rgba.g || 0;
+                    }
+                    var middle = vValue > hValue ? hValue : vValue;
+                    setAlpha.call($this, colorBarL2, hValue > vValue ? Math.precision(((hValue - vValue) / (255 - vValue)) * 100, 4) : 0);
+                    setAlpha.call($this, colorBarL3, vValue > hValue ? Math.precision(((vValue - hValue) / (255 - hValue)) * 100, 4) : 0);
+                    setAlpha.call($this, colorBarL4, Math.precision((middle / 255) * 100, 4));
+                    setAlpha.call($this, colorBarL5, Math.precision(((255 - (rgba && rgba.a || 0)) * 100) / 255, 4));
+                    break;
+                  case 'a':
+                    var a = ui.val('a');
+                    setBG.call($this, colorBarDiv, ui.val('hex') || '000000');
+                    setAlpha.call($this, colorBarL5, a != null ? 0 : 100);
+                    setAlpha.call($this, colorBarL6, a != null ? 100 : 0);
+                    break;
+                }
+              },
+            setBG =
+              function(el, c)
+              {
+                el.css({ backgroundColor: c && c.length == 6 && '#' + c || 'transparent' });
+              },
+            setImg =
+              function(img, src)
+              {
+                if (isLessThanIE7 && (src.indexOf('AlphaBar.png') != -1 || src.indexOf('Bars.png') != -1 || src.indexOf('Maps.png') != -1))
+                {
+                  img.attr('pngSrc', src);
+                  img.css({ backgroundImage: 'none', filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + src + '\', sizingMethod=\'scale\')' });
+                }
+                else img.css({ backgroundImage: 'url(\'' + src + '\')' });
+              },
+            setImgLoc =
+              function(img, y)
+              {
+                img.css({ top: y + 'px' });
+              },
+            setAlpha =
+              function(obj, alpha)
+              {
+                obj.css({ visibility: alpha > 0 ? 'visible' : 'hidden' });
+                if (alpha > 0 && alpha < 100)
+                {
+                  if (isLessThanIE7)
+                  {
+                    var src = obj.attr('pngSrc');
+                    if (src != null && (src.indexOf('AlphaBar.png') != -1 || src.indexOf('Bars.png') != -1 || src.indexOf('Maps.png') != -1))
+                      obj.css({ filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + src + '\', sizingMethod=\'scale\') progid:DXImageTransform.Microsoft.Alpha(opacity=' + alpha + ')' });
+                    else obj.css({ opacity: Math.precision(alpha / 100, 4) });
+                  }
+                  else obj.css({ opacity: Math.precision(alpha / 100, 4) });
+                }
+                else if (alpha == 0 || alpha == 100)
+                {
+                  if (isLessThanIE7)
+                  {
+                    var src = obj.attr('pngSrc');
+                    if (src != null && (src.indexOf('AlphaBar.png') != -1 || src.indexOf('Bars.png') != -1 || src.indexOf('Maps.png') != -1))
+                      obj.css({ filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + src + '\', sizingMethod=\'scale\')' });
+                    else obj.css({ opacity: '' });
+                  }
+                  else obj.css({ opacity: '' });
+                }
+              },
+            revertColor = // revert color to original color when opened
+              function()
+              {
+                color.active.val('ahex', color.current.val('ahex'));
+              },
+            commitColor = // commit the color changes
+              function()
+              {
+                color.current.val('ahex', color.active.val('ahex'));
+              },
+            radioClicked =
+              function(e)
+              {
+                $(this).parents('tbody:first').find('input:radio[value!="'+e.target.value+'"]').removeAttr('checked');
+                setColorMode.call($this, e.target.value);
+              },
+            currentClicked =
+              function()
+              {
+                revertColor.call($this);
+              },
+            cancelClicked =
+              function()
+              {
+                revertColor.call($this);
+                settings.window.expandable && hide.call($this);
+                $.isFunction(cancelCallback) && cancelCallback.call($this, color.active, cancelButton);
+              },
+            okClicked =
+              function()
+              {
+                commitColor.call($this);
+                settings.window.expandable && hide.call($this);
+                $.isFunction(commitCallback) && commitCallback.call($this, color.active, okButton);
+              },
+            iconImageClicked =
+              function()
+              {
+                show.call($this);
+              },
+            currentColorChanged =
+              function(ui, context)
+              {
+                var hex = ui.val('hex');
+                currentPreview.css({ backgroundColor: hex && '#' + hex || 'transparent' });
+                setAlpha.call($this, currentPreview, Math.precision(((ui.val('a') || 0) * 100) / 255, 4));
+              },
+            expandableColorChanged =
+              function(ui, context)
+              {
+                var hex = ui.val('hex');
+                var va = ui.val('va');
+                iconColor.css({ backgroundColor: hex && '#' + hex || 'transparent' });
+                setAlpha.call($this, iconAlpha, Math.precision(((255 - (va && va.a || 0)) * 100) / 255, 4));
+                if (settings.window.bindToInput&&settings.window.updateInputColor)
+                  settings.window.input.css(
+                    {
+                      backgroundColor: hex && '#' + hex || 'transparent',
+                      color: va == null || va.v > 75 ? '#000000' : '#ffffff'
+                    });
+              },
+            moveBarMouseDown =
+              function(e)
+              {
+                var element = settings.window.element, // local copies for YUI compressor
+                  page = settings.window.page;
+                elementStartX = parseInt(container.css('left'));
+                elementStartY = parseInt(container.css('top'));
+                pageStartX = e.pageX;
+                pageStartY = e.pageY;
+                // bind events to document to move window - we will unbind these on mouseup
+                $(document).bind('mousemove', documentMouseMove).bind('mouseup', documentMouseUp);
+                e.preventDefault(); // prevent attempted dragging of the column
+              },
+            documentMouseMove =
+              function(e)
+              {
+                container.css({ left: elementStartX - (pageStartX - e.pageX) + 'px', top: elementStartY - (pageStartY - e.pageY) + 'px' });
+                if (settings.window.expandable && !$.support.boxModel) container.prev().css({ left: container.css("left"), top: container.css("top") });
+                e.stopPropagation();
+                e.preventDefault();
+                return false;
+              },
+            documentMouseUp =
+              function(e)
+              {
+                $(document).unbind('mousemove', documentMouseMove).unbind('mouseup', documentMouseUp);
+                e.stopPropagation();
+                e.preventDefault();
+                return false;
+              },
+            quickPickClicked =
+              function(e)
+              {
+                e.preventDefault();
+                e.stopPropagation();
+                color.active.val('ahex', $(this).attr('title') || null, e.target);
+                return false;
+              },
+            commitCallback = $.isFunction($arguments[1]) && $arguments[1] || null,
+            liveCallback = $.isFunction($arguments[2]) && $arguments[2] || null,
+            cancelCallback = $.isFunction($arguments[3]) && $arguments[3] || null,
+            show =
+              function()
+              {
+                color.current.val('ahex', color.active.val('ahex'));
+                var attachIFrame = function()
+                  {
+                    if (!settings.window.expandable || $.support.boxModel) return;
+                    var table = container.find('table:first');
+                    container.before('<iframe/>');
+                    container.prev().css({ width: table.width(), height: container.height(), opacity: 0, position: 'absolute', left: container.css("left"), top: container.css("top") });
+                  };
+                if (settings.window.expandable)
+                {
+                  $(document.body).children('div.jPicker.Container').css({zIndex:10});
+                  container.css({zIndex:20});
+                }
+                switch (settings.window.effects.type)
+                {
+                  case 'fade':
+                    container.fadeIn(settings.window.effects.speed.show, attachIFrame);
+                    break;
+                  case 'slide':
+                    container.slideDown(settings.window.effects.speed.show, attachIFrame);
+                    break;
+                  case 'show':
+                  default:
+                    container.show(settings.window.effects.speed.show, attachIFrame);
+                    break;
+                }
+              },
+            hide =
+              function()
+              {
+                var removeIFrame = function()
+                  {
+                    if (settings.window.expandable) container.css({ zIndex: 10 });
+                    if (!settings.window.expandable || $.support.boxModel) return;
+                    container.prev().remove();
+                  };
+                switch (settings.window.effects.type)
+                {
+                  case 'fade':
+                    container.fadeOut(settings.window.effects.speed.hide, removeIFrame);
+                    break;
+                  case 'slide':
+                    container.slideUp(settings.window.effects.speed.hide, removeIFrame);
+                    break;
+                  case 'show':
+                  default:
+                    container.hide(settings.window.effects.speed.hide, removeIFrame);
+                    break;
+                }
+              },
+            initialize =
+              function()
+              {
+                var win = settings.window,
+                    popup = win.expandable ? $($this).next().find('.Container:first') : null;
+                container = win.expandable ? $('<div/>') : $($this);
+                container.addClass('jPicker Container');
+                if (win.expandable) container.hide();
+                container.get(0).onselectstart = function(event){ if (event.target.nodeName.toLowerCase() !== 'input') return false; };
+                // inject html source code - we are using a single table for this control - I know tables are considered bad, but it takes care of equal height columns and
+                // this control really is tabular data, so I believe it is the right move
+                var all = color.active.val('all');
+                if (win.alphaPrecision < 0) win.alphaPrecision = 0;
+                else if (win.alphaPrecision > 2) win.alphaPrecision = 2;
+                var controlHtml='<table class="jPicker" cellpadding="0" cellspacing="0"><tbody>' + (win.expandable ? '<tr><td class="Move" colspan="5">&nbsp;</td></tr>' : '') + '<tr><td rowspan="9"><h2 class="Title">' + (win.title || localization.text.title) + '</h2><div class="Map"><span class="Map1">&nbsp;</span><span class="Map2">&nbsp;</span><span class="Map3">&nbsp;</span><img src="' + images.clientPath + images.colorMap.arrow.file + '" class="Arrow"/></div></td><td rowspan="9"><div class="Bar"><span class="Map1">&nbsp;</span><span class="Map2">&nbsp;</span><span class="Map3">&nbsp;</span><span class="Map4">&nbsp;</span><span class="Map5">&nbsp;</span><span class="Map6">&nbsp;</span><img src="' + images.clientPath + images.colorBar.arrow.file + '" class="Arrow"/></div></td><td colspan="2" class="Preview">' + localization.text.newColor + '<div><span class="Active" title="' + localization.tooltips.colors.newColor + '">&nbsp;</span><span class="Current" title="' + localization.tooltips.colors.currentColor + '">&nbsp;</span></div>' + localization.text.currentColor + '</td><td rowspan="9" class="Button"><input type="button" class="Ok" value="' + localization.text.ok + '" title="' + localization.tooltips.buttons.ok + '"/><input type="button" class="Cancel" value="' + localization.text.cancel + '" title="' + localization.tooltips.buttons.cancel + '"/><hr/><div class="Grid">&nbsp;</div></td></tr><tr class="Hue"><td class="Radio"><label title="' + localization.tooltips.hue.radio + '"><input type="radio" value="h"' + (settings.color.mode == 'h' ? ' checked="checked"' : '') + '/>H:</label></td><td class="Text"><input type="text" maxlength="3" value="' + (all != null ? all.h : '') + '" title="' + localization.tooltips.hue.textbox + '"/>&nbsp;&deg;</td></tr><tr class="Saturation"><td class="Radio"><label title="' + localization.tooltips.saturation.radio + '"><input type="radio" value="s"' + (settings.color.mode == 's' ? ' checked="checked"' : '') + '/>S:</label></td><td class="Text"><input type="text" maxlength="3" value="' + (all != null ? all.s : '') + '" title="' + localization.tooltips.saturation.textbox + '"/>&nbsp;%</td></tr><tr class="Value"><td class="Radio"><label title="' + localization.tooltips.value.radio + '"><input type="radio" value="v"' + (settings.color.mode == 'v' ? ' checked="checked"' : '') + '/>V:</label><br/><br/></td><td class="Text"><input type="text" maxlength="3" value="' + (all != null ? all.v : '') + '" title="' + localization.tooltips.value.textbox + '"/>&nbsp;%<br/><br/></td></tr><tr class="Red"><td class="Radio"><label title="' + localization.tooltips.red.radio + '"><input type="radio" value="r"' + (settings.color.mode == 'r' ? ' checked="checked"' : '') + '/>R:</label></td><td class="Text"><input type="text" maxlength="3" value="' + (all != null ? all.r : '') + '" title="' + localization.tooltips.red.textbox + '"/></td></tr><tr class="Green"><td class="Radio"><label title="' + localization.tooltips.green.radio + '"><input type="radio" value="g"' + (settings.color.mode == 'g' ? ' checked="checked"' : '') + '/>G:</label></td><td class="Text"><input type="text" maxlength="3" value="' + (all != null ? all.g : '') + '" title="' + localization.tooltips.green.textbox + '"/></td></tr><tr class="Blue"><td class="Radio"><label title="' + localization.tooltips.blue.radio + '"><input type="radio" value="b"' + (settings.color.mode == 'b' ? ' checked="checked"' : '') + '/>B:</label></td><td class="Text"><input type="text" maxlength="3" value="' + (all != null ? all.b : '') + '" title="' + localization.tooltips.blue.textbox + '"/></td></tr><tr class="Alpha"><td class="Radio">' + (win.alphaSupport ? '<label title="' + localization.tooltips.alpha.radio + '"><input type="radio" value="a"' + (settings.color.mode == 'a' ? ' checked="checked"' : '') + '/>A:</label>' : '&nbsp;') + '</td><td class="Text">' + (win.alphaSupport ? '<input type="text" maxlength="' + (3 + win.alphaPrecision) + '" value="' + (all != null ? Math.precision((all.a * 100) / 255, win.alphaPrecision) : '') + '" title="' + localization.tooltips.alpha.textbox + '"/>&nbsp;%' : '&nbsp;') + '</td></tr><tr class="Hex"><td colspan="2" class="Text"><label title="' + localization.tooltips.hex.textbox + '">#:<input type="text" maxlength="6" class="Hex" value="' + (all != null ? all.hex : '') + '"/></label>' + (win.alphaSupport ? '<input type="text" maxlength="2" class="AHex" value="' + (all != null ? all.ahex.substring(6) : '') + '" title="' + localization.tooltips.hex.alpha + '"/></td>' : '&nbsp;') + '</tr></tbody></table>';
+                if (win.expandable)
+                {
+                  container.html(controlHtml);
+                  if($(document.body).children('div.jPicker.Container').length==0)$(document.body).prepend(container);
+                  else $(document.body).children('div.jPicker.Container:last').after(container);
+                  container.mousedown(
+                    function()
+                    {
+                      $(document.body).children('div.jPicker.Container').css({zIndex:10});
+                      container.css({zIndex:20});
+                    });
+                  container.css( // positions must be set and display set to absolute before source code injection or IE will size the container to fit the window
+                    {
+                      left:
+                        win.position.x == 'left' ? (popup.offset().left - 530 - (win.position.y == 'center' ? 25 : 0)) + 'px' :
+                        win.position.x == 'center' ? (popup.offset().left - 260) + 'px' :
+                        win.position.x == 'right' ? (popup.offset().left - 10 + (win.position.y == 'center' ? 25 : 0)) + 'px' :
+                        win.position.x == 'screenCenter' ? (($(document).width() >> 1) - 260) + 'px' : (popup.offset().left + parseInt(win.position.x)) + 'px',
+                      position: 'absolute',
+                      top: win.position.y == 'top' ? (popup.offset().top - 312) + 'px' :
+                           win.position.y == 'center' ? (popup.offset().top - 156) + 'px' :
+                           win.position.y == 'bottom' ? (popup.offset().top + 25) + 'px' : (popup.offset().top + parseInt(win.position.y)) + 'px'
+                    });
+                }
+                else
+                {
+                  container = $($this);
+                  container.html(controlHtml);
+                }
+                // initialize the objects to the source code just injected
+                var tbody = container.find('tbody:first');
+                colorMapDiv = tbody.find('div.Map:first');
+                colorBarDiv = tbody.find('div.Bar:first');
+                var MapMaps = colorMapDiv.find('span'),
+                    BarMaps = colorBarDiv.find('span');
+                colorMapL1 = MapMaps.filter('.Map1:first');
+                colorMapL2 = MapMaps.filter('.Map2:first');
+                colorMapL3 = MapMaps.filter('.Map3:first');
+                colorBarL1 = BarMaps.filter('.Map1:first');
+                colorBarL2 = BarMaps.filter('.Map2:first');
+                colorBarL3 = BarMaps.filter('.Map3:first');
+                colorBarL4 = BarMaps.filter('.Map4:first');
+                colorBarL5 = BarMaps.filter('.Map5:first');
+                colorBarL6 = BarMaps.filter('.Map6:first');
+                // create color pickers and maps
+                colorMap = new Slider(colorMapDiv,
+                  {
+                    map:
+                    {
+                      width: images.colorMap.width,
+                      height: images.colorMap.height
+                    },
+                    arrow:
+                    {
+                      image: images.clientPath + images.colorMap.arrow.file,
+                      width: images.colorMap.arrow.width,
+                      height: images.colorMap.arrow.height
+                    }
+                  });
+                colorMap.bind(mapValueChanged);
+                colorBar = new Slider(colorBarDiv,
+                  {
+                    map:
+                    {
+                      width: images.colorBar.width,
+                      height: images.colorBar.height
+                    },
+                    arrow:
+                    {
+                      image: images.clientPath + images.colorBar.arrow.file,
+                      width: images.colorBar.arrow.width,
+                      height: images.colorBar.arrow.height
+                    }
+                  });
+                colorBar.bind(colorBarValueChanged);
+                colorPicker = new ColorValuePicker(tbody, color.active, win.expandable && win.bindToInput ? win.input : null, win.alphaPrecision);
+                var hex = all != null ? all.hex : null,
+                    preview = tbody.find('.Preview'),
+                    button = tbody.find('.Button');
+                activePreview = preview.find('.Active:first').css({ backgroundColor: hex && '#' + hex || 'transparent' });
+                currentPreview = preview.find('.Current:first').css({ backgroundColor: hex && '#' + hex || 'transparent' }).bind('click', currentClicked);
+                setAlpha.call($this, currentPreview, Math.precision(color.current.val('a') * 100) / 255, 4);
+                okButton = button.find('.Ok:first').bind('click', okClicked);
+                cancelButton = button.find('.Cancel:first').bind('click', cancelClicked);
+                grid = button.find('.Grid:first');
+                setTimeout(
+                  function()
+                  {
+                    setImg.call($this, colorMapL1, images.clientPath + 'Maps.png');
+                    setImg.call($this, colorMapL2, images.clientPath + 'Maps.png');
+                    setImg.call($this, colorMapL3, images.clientPath + 'map-opacity.png');
+                    setImg.call($this, colorBarL1, images.clientPath + 'Bars.png');
+                    setImg.call($this, colorBarL2, images.clientPath + 'Bars.png');
+                    setImg.call($this, colorBarL3, images.clientPath + 'Bars.png');
+                    setImg.call($this, colorBarL4, images.clientPath + 'Bars.png');
+                    setImg.call($this, colorBarL5, images.clientPath + 'bar-opacity.png');
+                    setImg.call($this, colorBarL6, images.clientPath + 'AlphaBar.png');
+                    setImg.call($this, preview.find('div:first'), images.clientPath + 'preview-opacity.png');
+                  }, 0);
+                tbody.find('td.Radio input').bind('click', radioClicked);
+                // initialize quick list
+                if (color.quickList && color.quickList.length > 0)
+                {
+                  var html = '';
+                  for (i = 0; i < color.quickList.length; i++)
+                  {
+                    /* if default colors are hex strings, change them to color objects */
+                    if ((typeof (color.quickList[i])).toString().toLowerCase() == 'string') color.quickList[i] = new Color({ hex: color.quickList[i] });
+                    var alpha = color.quickList[i].val('a');
+                    var ahex = color.quickList[i].val('ahex');
+                    if (!win.alphaSupport && ahex) ahex = ahex.substring(0, 6) + 'ff';
+                    var quickHex = color.quickList[i].val('hex');
+                    html+='<span class="QuickColor"' + (ahex && ' title="#' + ahex + '"' || '') + ' style="background-color:' + (quickHex && '#' + quickHex || '') + ';' + (quickHex ? '' : 'background-image:url(' + images.clientPath + 'NoColor.png)') + (win.alphaSupport && alpha && alpha < 255 ? ';opacity:' + Math.precision(alpha / 255, 4) + ';filter:Alpha(opacity=' + Math.precision(alpha / 2.55, 4) + ')' : '') + '">&nbsp;</span>';
+                  }
+                  setImg.call($this, grid, images.clientPath + 'bar-opacity.png');
+                  grid.html(html);
+                  grid.find('.QuickColor').click(quickPickClicked);
+                }
+                setColorMode.call($this, settings.color.mode);
+                color.active.bind(activeColorChanged);
+                $.isFunction(liveCallback) && color.active.bind(liveCallback);
+                color.current.bind(currentColorChanged);
+                // bind to input
+                if (win.expandable)
+                {
+                  $this.icon = popup.parents('.Icon:first');
+                  iconColor = $this.icon.find('.Color:first').css({ backgroundColor: hex && '#' + hex || 'transparent' });
+                  iconAlpha = $this.icon.find('.Alpha:first');
+                  setImg.call($this, iconAlpha, images.clientPath + 'bar-opacity.png');
+                  setAlpha.call($this, iconAlpha, Math.precision(((255 - (all != null ? all.a : 0)) * 100) / 255, 4));
+                  iconImage = $this.icon.find('.Image:first').css(
+                    {
+                      backgroundImage: 'url(\'' + images.clientPath + images.picker.file + '\')'
+                    }).bind('click', iconImageClicked);
+                  if (win.bindToInput&&win.updateInputColor)
+                    win.input.css(
+                      {
+                        backgroundColor: hex && '#' + hex || 'transparent',
+                        color: all == null || all.v > 75 ? '#000000' : '#ffffff'
+                      });
+                  moveBar = tbody.find('.Move:first').bind('mousedown', moveBarMouseDown);
+                  color.active.bind(expandableColorChanged);
+                }
+                else show.call($this);
+              },
+            destroy =
+              function()
+              {
+                container.find('td.Radio input').unbind('click', radioClicked);
+                currentPreview.unbind('click', currentClicked);
+                cancelButton.unbind('click', cancelClicked);
+                okButton.unbind('click', okClicked);
+                if (settings.window.expandable)
+                {
+                  iconImage.unbind('click', iconImageClicked);
+                  moveBar.unbind('mousedown', moveBarMouseDown);
+                  $this.icon = null;
+                }
+                container.find('.QuickColor').unbind('click', quickPickClicked);
+                colorMapDiv = null;
+                colorBarDiv = null;
+                colorMapL1 = null;
+                colorMapL2 = null;
+                colorMapL3 = null;
+                colorBarL1 = null;
+                colorBarL2 = null;
+                colorBarL3 = null;
+                colorBarL4 = null;
+                colorBarL5 = null;
+                colorBarL6 = null;
+                colorMap.destroy();
+                colorMap = null;
+                colorBar.destroy();
+                colorBar = null;
+                colorPicker.destroy();
+                colorPicker = null;
+                activePreview = null;
+                currentPreview = null;
+                okButton = null;
+                cancelButton = null;
+                grid = null;
+                commitCallback = null;
+                cancelCallback = null;
+                liveCallback = null;
+                container.html('');
+                for (i = 0; i < List.length; i++) if (List[i] == $this) List.splice(i, 1);
+              },
+            images = settings.images, // local copies for YUI compressor
+            localization = settings.localization,
+            color =
+              {
+                active: (typeof(settings.color.active)).toString().toLowerCase() == 'string' ? new Color({ ahex: !settings.window.alphaSupport && settings.color.active ? settings.color.active.substring(0, 6) + 'ff' : settings.color.active }) : new Color({ ahex: !settings.window.alphaSupport && settings.color.active.val('ahex') ? settings.color.active.val('ahex').substring(0, 6) + 'ff' : settings.color.active.val('ahex') }),
+                current: (typeof(settings.color.active)).toString().toLowerCase() == 'string' ? new Color({ ahex: !settings.window.alphaSupport && settings.color.active ? settings.color.active.substring(0, 6) + 'ff' : settings.color.active }) : new Color({ ahex: !settings.window.alphaSupport && settings.color.active.val('ahex') ? settings.color.active.val('ahex').substring(0, 6) + 'ff' : settings.color.active.val('ahex') }),
+                quickList: settings.color.quickList
+              };
+          $.extend(true, $this, // public properties, methods, and callbacks
+            {
+              commitCallback: commitCallback, // commitCallback function can be overridden to return the selected color to a method you specify when the user clicks "OK"
+              liveCallback: liveCallback, // liveCallback function can be overridden to return the selected color to a method you specify in live mode (continuous update)
+              cancelCallback: cancelCallback, // cancelCallback function can be overridden to a method you specify when the user clicks "Cancel"
+              color: color,
+              show: show,
+              hide: hide,
+              destroy: destroy // destroys this control entirely, removing all events and objects, and removing itself from the List
+            });
+          List.push($this);
+          setTimeout(
+            function()
+            {
+              initialize.call($this);
+            }, 0);
+        });
+    };
+  $.fn.jPicker.defaults = /* jPicker defaults - you can change anything in this section (such as the clientPath to your images) without fear of breaking the program */
+      {
+      window:
+        {
+          title: null, /* any title for the jPicker window itself - displays "Drag Markers To Pick A Color" if left null */
+          effects:
+          {
+            type: 'slide', /* effect used to show/hide an expandable picker. Acceptable values "slide", "show", "fade" */
+            speed:
+            {
+              show: 'slow', /* duration of "show" effect. Acceptable values are "fast", "slow", or time in ms */
+              hide: 'fast' /* duration of "hide" effect. Acceptable values are "fast", "slow", or time in ms */
+            }
+          },
+          position:
+          {
+            x: 'screenCenter', /* acceptable values "left", "center", "right", "screenCenter", or relative px value */
+            y: 'top' /* acceptable values "top", "bottom", "center", or relative px value */
+          },
+          expandable: false, /* default to large static picker - set to true to make an expandable picker (small icon with popup) - set automatically when binded to input element */
+          liveUpdate: true, /* set false if you want the user to have to click "OK" before the binded input box updates values (always "true" for expandable picker) */
+          alphaSupport: false, /* set to true to enable alpha picking */
+          alphaPrecision: 0, /* set decimal precision for alpha percentage display - hex codes do not map directly to percentage integers - range 0-2 */
+          updateInputColor: true /* set to false to prevent binded input colors from changing */
+        },
+      color:
+        {
+          mode: 'h', /* acceptabled values "h" (hue), "s" (saturation), "v" (value), "r" (red), "g" (green), "b" (blue), "a" (alpha) */
+          active: new Color({ ahex: '#ffcc00ff' }), /* acceptable values are any declared $.jPicker.Color object or string HEX value (e.g. #ffc000) WITH OR WITHOUT the "#" prefix */
+          quickList: /* the quick pick color list */
+            [
+              new Color({ h: 360, s: 33, v: 100 }), /* acceptable values are any declared $.jPicker.Color object or string HEX value (e.g. #ffc000) WITH OR WITHOUT the "#" prefix */
+              new Color({ h: 360, s: 66, v: 100 }),
+              new Color({ h: 360, s: 100, v: 100 }),
+              new Color({ h: 360, s: 100, v: 75 }),
+              new Color({ h: 360, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 100 }),
+              new Color({ h: 30, s: 33, v: 100 }),
+              new Color({ h: 30, s: 66, v: 100 }),
+              new Color({ h: 30, s: 100, v: 100 }),
+              new Color({ h: 30, s: 100, v: 75 }),
+              new Color({ h: 30, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 90 }),
+              new Color({ h: 60, s: 33, v: 100 }),
+              new Color({ h: 60, s: 66, v: 100 }),
+              new Color({ h: 60, s: 100, v: 100 }),
+              new Color({ h: 60, s: 100, v: 75 }),
+              new Color({ h: 60, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 80 }),
+              new Color({ h: 90, s: 33, v: 100 }),
+              new Color({ h: 90, s: 66, v: 100 }),
+              new Color({ h: 90, s: 100, v: 100 }),
+              new Color({ h: 90, s: 100, v: 75 }),
+              new Color({ h: 90, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 70 }),
+              new Color({ h: 120, s: 33, v: 100 }),
+              new Color({ h: 120, s: 66, v: 100 }),
+              new Color({ h: 120, s: 100, v: 100 }),
+              new Color({ h: 120, s: 100, v: 75 }),
+              new Color({ h: 120, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 60 }),
+              new Color({ h: 150, s: 33, v: 100 }),
+              new Color({ h: 150, s: 66, v: 100 }),
+              new Color({ h: 150, s: 100, v: 100 }),
+              new Color({ h: 150, s: 100, v: 75 }),
+              new Color({ h: 150, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 50 }),
+              new Color({ h: 180, s: 33, v: 100 }),
+              new Color({ h: 180, s: 66, v: 100 }),
+              new Color({ h: 180, s: 100, v: 100 }),
+              new Color({ h: 180, s: 100, v: 75 }),
+              new Color({ h: 180, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 40 }),
+              new Color({ h: 210, s: 33, v: 100 }),
+              new Color({ h: 210, s: 66, v: 100 }),
+              new Color({ h: 210, s: 100, v: 100 }),
+              new Color({ h: 210, s: 100, v: 75 }),
+              new Color({ h: 210, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 30 }),
+              new Color({ h: 240, s: 33, v: 100 }),
+              new Color({ h: 240, s: 66, v: 100 }),
+              new Color({ h: 240, s: 100, v: 100 }),
+              new Color({ h: 240, s: 100, v: 75 }),
+              new Color({ h: 240, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 20 }),
+              new Color({ h: 270, s: 33, v: 100 }),
+              new Color({ h: 270, s: 66, v: 100 }),
+              new Color({ h: 270, s: 100, v: 100 }),
+              new Color({ h: 270, s: 100, v: 75 }),
+              new Color({ h: 270, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 10 }),
+              new Color({ h: 300, s: 33, v: 100 }),
+              new Color({ h: 300, s: 66, v: 100 }),
+              new Color({ h: 300, s: 100, v: 100 }),
+              new Color({ h: 300, s: 100, v: 75 }),
+              new Color({ h: 300, s: 100, v: 50 }),
+              new Color({ h: 180, s: 0, v: 0 }),
+              new Color({ h: 330, s: 33, v: 100 }),
+              new Color({ h: 330, s: 66, v: 100 }),
+              new Color({ h: 330, s: 100, v: 100 }),
+              new Color({ h: 330, s: 100, v: 75 }),
+              new Color({ h: 330, s: 100, v: 50 }),
+              new Color()
+            ]
+        },
+      images:
+        {
+          clientPath: '/jPicker/images/', /* Path to image files */
+          colorMap:
+          {
+            width: 256,
+            height: 256,
+            arrow:
+            {
+              file: 'mappoint.gif', /* ColorMap arrow icon */
+              width: 15,
+              height: 15
+            }
+          },
+          colorBar:
+          {
+            width: 20,
+            height: 256,
+            arrow:
+            {
+              file: 'rangearrows.gif', /* ColorBar arrow icon */
+              width: 20,
+              height: 7
+            }
+          },
+          picker:
+          {
+            file: 'picker.gif', /* Color Picker icon */
+            width: 25,
+            height: 24
+          }
+        },
+      localization: /* alter these to change the text presented by the picker (e.g. different language) */
+        {
+          text:
+          {
+            title: 'Drag Markers To Pick A Color',
+            newColor: 'new',
+            currentColor: 'current',
+            ok: 'OK',
+            cancel: 'Cancel'
+          },
+          tooltips:
+          {
+            colors:
+            {
+              newColor: 'New Color - Press &ldquo;OK&rdquo; To Commit',
+              currentColor: 'Click To Revert To Original Color'
+            },
+            buttons:
+            {
+              ok: 'Commit To This Color Selection',
+              cancel: 'Cancel And Revert To Original Color'
+            },
+            hue:
+            {
+              radio: 'Set To &ldquo;Hue&rdquo; Color Mode',
+              textbox: 'Enter A &ldquo;Hue&rdquo; Value (0-360&deg;)'
+            },
+            saturation:
+            {
+              radio: 'Set To &ldquo;Saturation&rdquo; Color Mode',
+              textbox: 'Enter A &ldquo;Saturation&rdquo; Value (0-100%)'
+            },
+            value:
+            {
+              radio: 'Set To &ldquo;Value&rdquo; Color Mode',
+              textbox: 'Enter A &ldquo;Value&rdquo; Value (0-100%)'
+            },
+            red:
+            {
+              radio: 'Set To &ldquo;Red&rdquo; Color Mode',
+              textbox: 'Enter A &ldquo;Red&rdquo; Value (0-255)'
+            },
+            green:
+            {
+              radio: 'Set To &ldquo;Green&rdquo; Color Mode',
+              textbox: 'Enter A &ldquo;Green&rdquo; Value (0-255)'
+            },
+            blue:
+            {
+              radio: 'Set To &ldquo;Blue&rdquo; Color Mode',
+              textbox: 'Enter A &ldquo;Blue&rdquo; Value (0-255)'
+            },
+            alpha:
+            {
+              radio: 'Set To &ldquo;Alpha&rdquo; Color Mode',
+              textbox: 'Enter A &ldquo;Alpha&rdquo; Value (0-100)'
+            },
+            hex:
+            {
+              textbox: 'Enter A &ldquo;Hex&rdquo; Color Value (#000000-#ffffff)',
+              alpha: 'Enter A &ldquo;Alpha&rdquo; Value (#00-#ff)'
+            }
+          }
+        }
+    };
+})(jQuery, '1.1.6');
\ No newline at end of file
diff --git a/js/jquery-ui-timepicker-addon.js b/js/jquery-ui-timepicker-addon.js
new file mode 100644
index 0000000..ce9436c
--- /dev/null
+++ b/js/jquery-ui-timepicker-addon.js
@@ -0,0 +1,1299 @@
+/*
+* jQuery timepicker addon
+* By: Trent Richardson [http://trentrichardson.com]
+* Version 0.9.8
+* Last Modified: 12/03/2011
+* 
+* Copyright 2011 Trent Richardson
+* Dual licensed under the MIT and GPL licenses.
+* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt
+* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt
+* 
+* HERES THE CSS:
+* .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
+* .ui-timepicker-div dl { text-align: left; }
+* .ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }
+* .ui-timepicker-div dl dd { margin: 0 10px 10px 65px; }
+* .ui-timepicker-div td { font-size: 90%; }
+* .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
+*/
+
+(function($) {
+
+$.extend($.ui, { timepicker: { version: "0.9.8" } });
+
+/* Time picker manager.
+   Use the singleton instance of this class, $.timepicker, to interact with the time picker.
+   Settings for (groups of) time pickers are maintained in an instance object,
+   allowing multiple different settings on the same page. */
+
+function Timepicker() {
+	this.regional = []; // Available regional settings, indexed by language code
+	this.regional[''] = { // Default regional settings
+		currentText: 'Now',
+		closeText: 'Done',
+		ampm: false,
+		amNames: ['AM', 'A'],
+		pmNames: ['PM', 'P'],
+		timeFormat: 'hh:mm tt',
+		timeSuffix: '',
+		timeOnlyTitle: 'Choose Time',
+		timeText: 'Time',
+		hourText: 'Hour',
+		minuteText: 'Minute',
+		secondText: 'Second',
+		millisecText: 'Millisecond',
+		timezoneText: 'Time Zone'
+	};
+	this._defaults = { // Global defaults for all the datetime picker instances
+		showButtonPanel: true,
+		timeOnly: false,
+		showHour: true,
+		showMinute: true,
+		showSecond: false,
+		showMillisec: false,
+		showTimezone: false,
+		showTime: true,
+		stepHour: 1,
+		stepMinute: 1,
+		stepSecond: 1,
+		stepMillisec: 1,
+		hour: 0,
+		minute: 0,
+		second: 0,
+		millisec: 0,
+		timezone: '+0000',
+		hourMin: 0,
+		minuteMin: 0,
+		secondMin: 0,
+		millisecMin: 0,
+		hourMax: 23,
+		minuteMax: 59,
+		secondMax: 59,
+		millisecMax: 999,
+		minDateTime: null,
+		maxDateTime: null,
+		onSelect: null,
+		hourGrid: 0,
+		minuteGrid: 0,
+		secondGrid: 0,
+		millisecGrid: 0,
+		alwaysSetTime: true,
+		separator: ' ',
+		altFieldTimeOnly: true,
+		showTimepicker: true,
+		timezoneIso8609: false,
+		timezoneList: null,
+		addSliderAccess: false,
+		sliderAccessArgs: null
+	};
+	$.extend(this._defaults, this.regional['']);
+}
+
+$.extend(Timepicker.prototype, {
+	$input: null,
+	$altInput: null,
+	$timeObj: null,
+	inst: null,
+	hour_slider: null,
+	minute_slider: null,
+	second_slider: null,
+	millisec_slider: null,
+	timezone_select: null,
+	hour: 0,
+	minute: 0,
+	second: 0,
+	millisec: 0,
+	timezone: '+0000',
+	hourMinOriginal: null,
+	minuteMinOriginal: null,
+	secondMinOriginal: null,
+	millisecMinOriginal: null,
+	hourMaxOriginal: null,
+	minuteMaxOriginal: null,
+	secondMaxOriginal: null,
+	millisecMaxOriginal: null,
+	ampm: '',
+	formattedDate: '',
+	formattedTime: '',
+	formattedDateTime: '',
+	timezoneList: null,
+
+	/* Override the default settings for all instances of the time picker.
+	   @param  settings  object - the new settings to use as defaults (anonymous object)
+	   @return the manager object */
+	setDefaults: function(settings) {
+		extendRemove(this._defaults, settings || {});
+		return this;
+	},
+
+	//########################################################################
+	// Create a new Timepicker instance
+	//########################################################################
+	_newInst: function($input, o) {
+		var tp_inst = new Timepicker(),
+			inlineSettings = {};
+			
+		for (var attrName in this._defaults) {
+			var attrValue = $input.attr('time:' + attrName);
+			if (attrValue) {
+				try {
+					inlineSettings[attrName] = eval(attrValue);
+				} catch (err) {
+					inlineSettings[attrName] = attrValue;
+				}
+			}
+		}
+		tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, {
+			beforeShow: function(input, dp_inst) {
+				if ($.isFunction(o.beforeShow))
+					o.beforeShow(input, dp_inst, tp_inst);
+			},
+			onChangeMonthYear: function(year, month, dp_inst) {
+				// Update the time as well : this prevents the time from disappearing from the $input field.
+				tp_inst._updateDateTime(dp_inst);
+				if ($.isFunction(o.onChangeMonthYear))
+					o.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);
+			},
+			onClose: function(dateText, dp_inst) {
+				if (tp_inst.timeDefined === true && $input.val() != '')
+					tp_inst._updateDateTime(dp_inst);
+				if ($.isFunction(o.onClose))
+					o.onClose.call($input[0], dateText, dp_inst, tp_inst);
+			},
+			timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');
+		});
+		tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { return val.toUpperCase() });
+		tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { return val.toUpperCase() });
+
+		if (tp_inst._defaults.timezoneList === null) {
+			var timezoneList = [];
+			for (var i = -11; i <= 12; i++)
+				timezoneList.push((i >= 0 ? '+' : '-') + ('0' + Math.abs(i).toString()).slice(-2) + '00');
+			if (tp_inst._defaults.timezoneIso8609)
+				timezoneList = $.map(timezoneList, function(val) {
+					return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3));
+				});
+			tp_inst._defaults.timezoneList = timezoneList;
+		}
+
+		tp_inst.hour = tp_inst._defaults.hour;
+		tp_inst.minute = tp_inst._defaults.minute;
+		tp_inst.second = tp_inst._defaults.second;
+		tp_inst.millisec = tp_inst._defaults.millisec;
+		tp_inst.ampm = '';
+		tp_inst.$input = $input;
+
+		if (o.altField)
+			tp_inst.$altInput = $(o.altField)
+				.css({ cursor: 'pointer' })
+				.focus(function(){ $input.trigger("focus"); });
+		
+		if(tp_inst._defaults.minDate==0 || tp_inst._defaults.minDateTime==0)
+		{
+			tp_inst._defaults.minDate=new Date();
+		}
+		if(tp_inst._defaults.maxDate==0 || tp_inst._defaults.maxDateTime==0)
+		{
+			tp_inst._defaults.maxDate=new Date();
+		}
+		
+		// datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..
+		if(tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date)
+			tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());
+		if(tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date)
+			tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());
+		if(tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date)
+			tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());
+		if(tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date)
+			tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());
+		return tp_inst;
+	},
+
+	//########################################################################
+	// add our sliders to the calendar
+	//########################################################################
+	_addTimePicker: function(dp_inst) {
+		var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ?
+				this.$input.val() + ' ' + this.$altInput.val() : 
+				this.$input.val();
+
+		this.timeDefined = this._parseTime(currDT);
+		this._limitMinMaxDateTime(dp_inst, false);
+		this._injectTimePicker();
+	},
+
+	//########################################################################
+	// parse the time string from input value or _setTime
+	//########################################################################
+	_parseTime: function(timeString, withDate) {
+		var regstr = this._defaults.timeFormat.toString()
+				.replace(/h{1,2}/ig, '(\\d?\\d)')
+				.replace(/m{1,2}/ig, '(\\d?\\d)')
+				.replace(/s{1,2}/ig, '(\\d?\\d)')
+				.replace(/l{1}/ig, '(\\d?\\d?\\d)')
+				.replace(/t{1,2}/ig, this._getPatternAmpm())
+				.replace(/z{1}/ig, '(z|[-+]\\d\\d:?\\d\\d)?')
+				.replace(/\s/g, '\\s?') + this._defaults.timeSuffix + '$',
+			order = this._getFormatPositions(),
+			ampm = '',
+			treg;
+
+		if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);
+
+		if (withDate || !this._defaults.timeOnly) {
+			// the time should come after x number of characters and a space.
+			// x = at least the length of text specified by the date format
+			var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');
+			// escape special regex characters in the seperator
+			var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g");
+			regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator.replace(specials, "\\$&") + regstr;
+		}
+		
+		treg = timeString.match(new RegExp(regstr, 'i'));
+
+		if (treg) {
+			if (order.t !== -1) {
+				if (treg[order.t] === undefined || treg[order.t].length === 0) {
+					ampm = '';
+					this.ampm = '';
+				} else {
+					ampm = $.inArray(treg[order.t].toUpperCase(), this.amNames) !== -1 ? 'AM' : 'PM';
+					this.ampm = this._defaults[ampm == 'AM' ? 'amNames' : 'pmNames'][0];
+				}
+			}
+
+			if (order.h !== -1) {
+				if (ampm == 'AM' && treg[order.h] == '12')
+					this.hour = 0; // 12am = 0 hour
+				else if (ampm == 'PM' && treg[order.h] != '12')
+					this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12
+				else this.hour = Number(treg[order.h]);
+			}
+
+			if (order.m !== -1) this.minute = Number(treg[order.m]);
+			if (order.s !== -1) this.second = Number(treg[order.s]);
+			if (order.l !== -1) this.millisec = Number(treg[order.l]);
+			if (order.z !== -1 && treg[order.z] !== undefined) {
+				var tz = treg[order.z].toUpperCase();
+				switch (tz.length) {
+				case 1:	// Z
+					tz = this._defaults.timezoneIso8609 ? 'Z' : '+0000';
+					break;
+				case 5:	// +hhmm
+					if (this._defaults.timezoneIso8609)
+						tz = tz.substring(1) == '0000'
+						   ? 'Z'
+						   : tz.substring(0, 3) + ':' + tz.substring(3);
+					break;
+				case 6:	// +hh:mm
+					if (!this._defaults.timezoneIso8609)
+						tz = tz == 'Z' || tz.substring(1) == '00:00'
+						   ? '+0000'
+						   : tz.replace(/:/, '');
+					else if (tz.substring(1) == '00:00')
+						tz = 'Z';
+					break;
+				}
+				this.timezone = tz;
+			}
+			
+			return true;
+
+		}
+		return false;
+	},
+
+	//########################################################################
+	// pattern for standard and localized AM/PM markers
+	//########################################################################
+	_getPatternAmpm: function() {
+		var markers = [];
+			o = this._defaults;
+		if (o.amNames)
+			$.merge(markers, o.amNames);
+		if (o.pmNames)
+			$.merge(markers, o.pmNames);
+		markers = $.map(markers, function(val) { return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&') });
+		return '(' + markers.join('|') + ')?';
+	},
+
+	//########################################################################
+	// figure out position of time elements.. cause js cant do named captures
+	//########################################################################
+	_getFormatPositions: function() {
+		var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|t{1,2}|z)/g),
+			orders = { h: -1, m: -1, s: -1, l: -1, t: -1, z: -1 };
+
+		if (finds)
+			for (var i = 0; i < finds.length; i++)
+				if (orders[finds[i].toString().charAt(0)] == -1)
+					orders[finds[i].toString().charAt(0)] = i + 1;
+
+		return orders;
+	},
+
+	//########################################################################
+	// generate and inject html for timepicker into ui datepicker
+	//########################################################################
+	_injectTimePicker: function() {
+		var $dp = this.inst.dpDiv,
+			o = this._defaults,
+			tp_inst = this,
+			// Added by Peter Medeiros:
+			// - Figure out what the hour/minute/second max should be based on the step values.
+			// - Example: if stepMinute is 15, then minMax is 45.
+			hourMax = parseInt((o.hourMax - ((o.hourMax - o.hourMin) % o.stepHour)) ,10),
+			minMax  = parseInt((o.minuteMax - ((o.minuteMax - o.minuteMin) % o.stepMinute)) ,10),
+			secMax  = parseInt((o.secondMax - ((o.secondMax - o.secondMin) % o.stepSecond)) ,10),
+			millisecMax  = parseInt((o.millisecMax - ((o.millisecMax - o.millisecMin) % o.stepMillisec)) ,10),
+			dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, '');
+
+		// Prevent displaying twice
+		//if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0) {
+		if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0 && o.showTimepicker) {
+			var noDisplay = ' style="display:none;"',
+				html =	'<div class="ui-timepicker-div" id="ui-timepicker-div-' + dp_id + '"><dl>' +
+						'<dt class="ui_tpicker_time_label" id="ui_tpicker_time_label_' + dp_id + '"' +
+						((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' +
+						'<dd class="ui_tpicker_time" id="ui_tpicker_time_' + dp_id + '"' +
+						((o.showTime) ? '' : noDisplay) + '></dd>' +
+						'<dt class="ui_tpicker_hour_label" id="ui_tpicker_hour_label_' + dp_id + '"' +
+						((o.showHour) ? '' : noDisplay) + '>' + o.hourText + '</dt>',
+				hourGridSize = 0,
+				minuteGridSize = 0,
+				secondGridSize = 0,
+				millisecGridSize = 0,
+				size;
+
+ 			// Hours
+			html += '<dd class="ui_tpicker_hour"><div id="ui_tpicker_hour_' + dp_id + '"' +
+						((o.showHour) ? '' : noDisplay) + '></div>';
+			if (o.showHour && o.hourGrid > 0) {
+				html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';
+
+				for (var h = o.hourMin; h <= hourMax; h += parseInt(o.hourGrid,10)) {
+					hourGridSize++;
+					var tmph = (o.ampm && h > 12) ? h-12 : h;
+					if (tmph < 10) tmph = '0' + tmph;
+					if (o.ampm) {
+						if (h == 0) tmph = 12 +'a';
+						else if (h < 12) tmph += 'a';
+						else tmph += 'p';
+					}
+					html += '<td>' + tmph + '</td>';
+				}
+
+				html += '</tr></table></div>';
+			}
+			html += '</dd>';
+
+			// Minutes
+			html += '<dt class="ui_tpicker_minute_label" id="ui_tpicker_minute_label_' + dp_id + '"' +
+					((o.showMinute) ? '' : noDisplay) + '>' + o.minuteText + '</dt>'+
+					'<dd class="ui_tpicker_minute"><div id="ui_tpicker_minute_' + dp_id + '"' +
+							((o.showMinute) ? '' : noDisplay) + '></div>';
+
+			if (o.showMinute && o.minuteGrid > 0) {
+				html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';
+
+				for (var m = o.minuteMin; m <= minMax; m += parseInt(o.minuteGrid,10)) {
+					minuteGridSize++;
+					html += '<td>' + ((m < 10) ? '0' : '') + m + '</td>';
+				}
+
+				html += '</tr></table></div>';
+			}
+			html += '</dd>';
+
+			// Seconds
+			html += '<dt class="ui_tpicker_second_label" id="ui_tpicker_second_label_' + dp_id + '"' +
+					((o.showSecond) ? '' : noDisplay) + '>' + o.secondText + '</dt>'+
+					'<dd class="ui_tpicker_second"><div id="ui_tpicker_second_' + dp_id + '"'+
+							((o.showSecond) ? '' : noDisplay) + '></div>';
+
+			if (o.showSecond && o.secondGrid > 0) {
+				html += '<div style="padding-left: 1px"><table><tr>';
+
+				for (var s = o.secondMin; s <= secMax; s += parseInt(o.secondGrid,10)) {
+					secondGridSize++;
+					html += '<td>' + ((s < 10) ? '0' : '') + s + '</td>';
+				}
+
+				html += '</tr></table></div>';
+			}
+			html += '</dd>';
+
+			// Milliseconds
+			html += '<dt class="ui_tpicker_millisec_label" id="ui_tpicker_millisec_label_' + dp_id + '"' +
+					((o.showMillisec) ? '' : noDisplay) + '>' + o.millisecText + '</dt>'+
+					'<dd class="ui_tpicker_millisec"><div id="ui_tpicker_millisec_' + dp_id + '"'+
+							((o.showMillisec) ? '' : noDisplay) + '></div>';
+
+			if (o.showMillisec && o.millisecGrid > 0) {
+				html += '<div style="padding-left: 1px"><table><tr>';
+
+				for (var l = o.millisecMin; l <= millisecMax; l += parseInt(o.millisecGrid,10)) {
+					millisecGridSize++;
+					html += '<td>' + ((l < 10) ? '0' : '') + l + '</td>';
+				}
+
+				html += '</tr></table></div>';
+			}
+			html += '</dd>';
+
+			// Timezone
+			html += '<dt class="ui_tpicker_timezone_label" id="ui_tpicker_timezone_label_' + dp_id + '"' +
+					((o.showTimezone) ? '' : noDisplay) + '>' + o.timezoneText + '</dt>';
+			html += '<dd class="ui_tpicker_timezone" id="ui_tpicker_timezone_' + dp_id + '"'	+
+							((o.showTimezone) ? '' : noDisplay) + '></dd>';
+
+			html += '</dl></div>';
+			$tp = $(html);
+
+				// if we only want time picker...
+			if (o.timeOnly === true) {
+				$tp.prepend(
+					'<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' +
+						'<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' +
+					'</div>');
+				$dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();
+			}
+
+			this.hour_slider = $tp.find('#ui_tpicker_hour_'+ dp_id).slider({
+				orientation: "horizontal",
+				value: this.hour,
+				min: o.hourMin,
+				max: hourMax,
+				step: o.stepHour,
+				slide: function(event, ui) {
+					tp_inst.hour_slider.slider( "option", "value", ui.value);
+					tp_inst._onTimeChange();
+				}
+			});
+
+			
+			// Updated by Peter Medeiros:
+			// - Pass in Event and UI instance into slide function
+			this.minute_slider = $tp.find('#ui_tpicker_minute_'+ dp_id).slider({
+				orientation: "horizontal",
+				value: this.minute,
+				min: o.minuteMin,
+				max: minMax,
+				step: o.stepMinute,
+				slide: function(event, ui) {
+					tp_inst.minute_slider.slider( "option", "value", ui.value);
+					tp_inst._onTimeChange();
+				}
+			});
+
+			this.second_slider = $tp.find('#ui_tpicker_second_'+ dp_id).slider({
+				orientation: "horizontal",
+				value: this.second,
+				min: o.secondMin,
+				max: secMax,
+				step: o.stepSecond,
+				slide: function(event, ui) {
+					tp_inst.second_slider.slider( "option", "value", ui.value);
+					tp_inst._onTimeChange();
+				}
+			});
+
+			this.millisec_slider = $tp.find('#ui_tpicker_millisec_'+ dp_id).slider({
+				orientation: "horizontal",
+				value: this.millisec,
+				min: o.millisecMin,
+				max: millisecMax,
+				step: o.stepMillisec,
+				slide: function(event, ui) {
+					tp_inst.millisec_slider.slider( "option", "value", ui.value);
+					tp_inst._onTimeChange();
+				}
+			});
+
+			this.timezone_select = $tp.find('#ui_tpicker_timezone_'+ dp_id).append('<select></select>').find("select");
+			$.fn.append.apply(this.timezone_select,
+				$.map(o.timezoneList, function(val, idx) {
+					return $("<option />")
+						.val(typeof val == "object" ? val.value : val)
+						.text(typeof val == "object" ? val.label : val);
+				})
+			);
+			this.timezone_select.val((typeof this.timezone != "undefined" && this.timezone != null && this.timezone != "") ? this.timezone : o.timezone);
+			this.timezone_select.change(function() {
+				tp_inst._onTimeChange();
+			});
+
+			// Add grid functionality
+			if (o.showHour && o.hourGrid > 0) {
+				size = 100 * hourGridSize * o.hourGrid / (hourMax - o.hourMin);
+
+				$tp.find(".ui_tpicker_hour table").css({
+					width: size + "%",
+					marginLeft: (size / (-2 * hourGridSize)) + "%",
+					borderCollapse: 'collapse'
+				}).find("td").each( function(index) {
+					$(this).click(function() {
+						var h = $(this).html();
+						if(o.ampm)	{
+							var ap = h.substring(2).toLowerCase(),
+								aph = parseInt(h.substring(0,2), 10);
+							if (ap == 'a') {
+								if (aph == 12) h = 0;
+								else h = aph;
+							} else if (aph == 12) h = 12;
+							else h = aph + 12;
+						}
+						tp_inst.hour_slider.slider("option", "value", h);
+						tp_inst._onTimeChange();
+						tp_inst._onSelectHandler();
+					}).css({
+						cursor: 'pointer',
+						width: (100 / hourGridSize) + '%',
+						textAlign: 'center',
+						overflow: 'hidden'
+					});
+				});
+			}
+
+			if (o.showMinute && o.minuteGrid > 0) {
+				size = 100 * minuteGridSize * o.minuteGrid / (minMax - o.minuteMin);
+				$tp.find(".ui_tpicker_minute table").css({
+					width: size + "%",
+					marginLeft: (size / (-2 * minuteGridSize)) + "%",
+					borderCollapse: 'collapse'
+				}).find("td").each(function(index) {
+					$(this).click(function() {
+						tp_inst.minute_slider.slider("option", "value", $(this).html());
+						tp_inst._onTimeChange();
+						tp_inst._onSelectHandler();
+					}).css({
+						cursor: 'pointer',
+						width: (100 / minuteGridSize) + '%',
+						textAlign: 'center',
+						overflow: 'hidden'
+					});
+				});
+			}
+
+			if (o.showSecond && o.secondGrid > 0) {
+				$tp.find(".ui_tpicker_second table").css({
+					width: size + "%",
+					marginLeft: (size / (-2 * secondGridSize)) + "%",
+					borderCollapse: 'collapse'
+				}).find("td").each(function(index) {
+					$(this).click(function() {
+						tp_inst.second_slider.slider("option", "value", $(this).html());
+						tp_inst._onTimeChange();
+						tp_inst._onSelectHandler();
+					}).css({
+						cursor: 'pointer',
+						width: (100 / secondGridSize) + '%',
+						textAlign: 'center',
+						overflow: 'hidden'
+					});
+				});
+			}
+
+			if (o.showMillisec && o.millisecGrid > 0) {
+				$tp.find(".ui_tpicker_millisec table").css({
+					width: size + "%",
+					marginLeft: (size / (-2 * millisecGridSize)) + "%",
+					borderCollapse: 'collapse'
+				}).find("td").each(function(index) {
+					$(this).click(function() {
+						tp_inst.millisec_slider.slider("option", "value", $(this).html());
+						tp_inst._onTimeChange();
+						tp_inst._onSelectHandler();
+					}).css({
+						cursor: 'pointer',
+						width: (100 / millisecGridSize) + '%',
+						textAlign: 'center',
+						overflow: 'hidden'
+					});
+				});
+			}
+
+			var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');
+			if ($buttonPanel.length) $buttonPanel.before($tp);
+			else $dp.append($tp);
+
+			this.$timeObj = $tp.find('#ui_tpicker_time_'+ dp_id);
+
+			if (this.inst !== null) {
+				var timeDefined = this.timeDefined;
+				this._onTimeChange();
+				this.timeDefined = timeDefined;
+			}
+
+			//Emulate datepicker onSelect behavior. Call on slidestop.
+			var onSelectDelegate = function() {
+				tp_inst._onSelectHandler();
+			};
+			this.hour_slider.bind('slidestop',onSelectDelegate);
+			this.minute_slider.bind('slidestop',onSelectDelegate);
+			this.second_slider.bind('slidestop',onSelectDelegate);
+			this.millisec_slider.bind('slidestop',onSelectDelegate);
+			
+			// slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/
+			if (this._defaults.addSliderAccess){
+				var sliderAccessArgs = this._defaults.sliderAccessArgs;
+				setTimeout(function(){ // fix for inline mode
+					if($tp.find('.ui-slider-access').length == 0){
+						$tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);
+
+						// fix any grids since sliders are shorter
+						var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);
+						if(sliderAccessWidth){
+							$tp.find('table:visible').each(function(){
+								var $g = $(this),
+									oldWidth = $g.outerWidth(),
+									oldMarginLeft = $g.css('marginLeft').toString().replace('%',''),
+									newWidth = oldWidth - sliderAccessWidth,
+									newMarginLeft = ((oldMarginLeft * newWidth)/oldWidth) + '%';
+						
+								$g.css({ width: newWidth, marginLeft: newMarginLeft });
+							});
+						}
+					}
+				},0);
+			}
+			// end slideAccess integration
+			
+		}
+	},
+
+	//########################################################################
+	// This function tries to limit the ability to go outside the
+	// min/max date range
+	//########################################################################
+	_limitMinMaxDateTime: function(dp_inst, adjustSliders){
+		var o = this._defaults,
+			dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);
+
+		if(!this._defaults.showTimepicker) return; // No time so nothing to check here
+
+		if($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date){
+			var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),
+				minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);
+
+			if(this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null){
+				this.hourMinOriginal = o.hourMin;
+				this.minuteMinOriginal = o.minuteMin;
+				this.secondMinOriginal = o.secondMin;
+				this.millisecMinOriginal = o.millisecMin;
+			}
+
+			if(dp_inst.settings.timeOnly || minDateTimeDate.getTime() == dp_date.getTime()) {
+				this._defaults.hourMin = minDateTime.getHours();
+				if (this.hour <= this._defaults.hourMin) {
+					this.hour = this._defaults.hourMin;
+					this._defaults.minuteMin = minDateTime.getMinutes();
+					if (this.minute <= this._defaults.minuteMin) {
+						this.minute = this._defaults.minuteMin;
+						this._defaults.secondMin = minDateTime.getSeconds();
+					} else if (this.second <= this._defaults.secondMin){
+						this.second = this._defaults.secondMin;
+						this._defaults.millisecMin = minDateTime.getMilliseconds();
+					} else {
+						if(this.millisec < this._defaults.millisecMin)
+							this.millisec = this._defaults.millisecMin;
+						this._defaults.millisecMin = this.millisecMinOriginal;
+					}
+				} else {
+					this._defaults.minuteMin = this.minuteMinOriginal;
+					this._defaults.secondMin = this.secondMinOriginal;
+					this._defaults.millisecMin = this.millisecMinOriginal;
+				}
+			}else{
+				this._defaults.hourMin = this.hourMinOriginal;
+				this._defaults.minuteMin = this.minuteMinOriginal;
+				this._defaults.secondMin = this.secondMinOriginal;
+				this._defaults.millisecMin = this.millisecMinOriginal;
+			}
+		}
+
+		if($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date){
+			var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),
+				maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);
+
+			if(this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null){
+				this.hourMaxOriginal = o.hourMax;
+				this.minuteMaxOriginal = o.minuteMax;
+				this.secondMaxOriginal = o.secondMax;
+				this.millisecMaxOriginal = o.millisecMax;
+			}
+
+			if(dp_inst.settings.timeOnly || maxDateTimeDate.getTime() == dp_date.getTime()){
+				this._defaults.hourMax = maxDateTime.getHours();
+				if (this.hour >= this._defaults.hourMax) {
+					this.hour = this._defaults.hourMax;
+					this._defaults.minuteMax = maxDateTime.getMinutes();
+					if (this.minute >= this._defaults.minuteMax) {
+						this.minute = this._defaults.minuteMax;
+						this._defaults.secondMax = maxDateTime.getSeconds();
+					} else if (this.second >= this._defaults.secondMax) {
+						this.second = this._defaults.secondMax;
+						this._defaults.millisecMax = maxDateTime.getMilliseconds();
+					} else {
+						if(this.millisec > this._defaults.millisecMax) this.millisec = this._defaults.millisecMax;
+						this._defaults.millisecMax = this.millisecMaxOriginal;
+					}
+				} else {
+					this._defaults.minuteMax = this.minuteMaxOriginal;
+					this._defaults.secondMax = this.secondMaxOriginal;
+					this._defaults.millisecMax = this.millisecMaxOriginal;
+				}
+			}else{
+				this._defaults.hourMax = this.hourMaxOriginal;
+				this._defaults.minuteMax = this.minuteMaxOriginal;
+				this._defaults.secondMax = this.secondMaxOriginal;
+				this._defaults.millisecMax = this.millisecMaxOriginal;
+			}
+		}
+
+		if(adjustSliders !== undefined && adjustSliders === true){
+			var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)) ,10),
+                minMax  = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)) ,10),
+                secMax  = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)) ,10),
+				millisecMax  = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)) ,10);
+
+			if(this.hour_slider)
+				this.hour_slider.slider("option", { min: this._defaults.hourMin, max: hourMax }).slider('value', this.hour);
+			if(this.minute_slider)
+				this.minute_slider.slider("option", { min: this._defaults.minuteMin, max: minMax }).slider('value', this.minute);
+			if(this.second_slider)
+				this.second_slider.slider("option", { min: this._defaults.secondMin, max: secMax }).slider('value', this.second);
+			if(this.millisec_slider)
+				this.millisec_slider.slider("option", { min: this._defaults.millisecMin, max: millisecMax }).slider('value', this.millisec);
+		}
+
+	},
+
+	
+	//########################################################################
+	// when a slider moves, set the internal time...
+	// on time change is also called when the time is updated in the text field
+	//########################################################################
+	_onTimeChange: function() {
+		var hour   = (this.hour_slider) ? this.hour_slider.slider('value') : false,
+			minute = (this.minute_slider) ? this.minute_slider.slider('value') : false,
+			second = (this.second_slider) ? this.second_slider.slider('value') : false,
+			millisec = (this.millisec_slider) ? this.millisec_slider.slider('value') : false,
+			timezone = (this.timezone_select) ? this.timezone_select.val() : false,
+			o = this._defaults;
+
+		if (typeof(hour) == 'object') hour = false;
+		if (typeof(minute) == 'object') minute = false;
+		if (typeof(second) == 'object') second = false;
+		if (typeof(millisec) == 'object') millisec = false;
+		if (typeof(timezone) == 'object') timezone = false;
+
+		if (hour !== false) hour = parseInt(hour,10);
+		if (minute !== false) minute = parseInt(minute,10);
+		if (second !== false) second = parseInt(second,10);
+		if (millisec !== false) millisec = parseInt(millisec,10);
+
+		var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];
+
+		// If the update was done in the input field, the input field should not be updated.
+		// If the update was done using the sliders, update the input field.
+		var hasChanged = (hour != this.hour || minute != this.minute
+				|| second != this.second || millisec != this.millisec
+				|| (this.ampm.length > 0
+				    && (hour < 12) != ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1))
+				|| timezone != this.timezone);
+		
+		if (hasChanged) {
+
+			if (hour !== false)this.hour = hour;
+			if (minute !== false) this.minute = minute;
+			if (second !== false) this.second = second;
+			if (millisec !== false) this.millisec = millisec;
+			if (timezone !== false) this.timezone = timezone;
+			
+			if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);
+			
+			this._limitMinMaxDateTime(this.inst, true);
+		}
+		if (o.ampm) this.ampm = ampm;
+		
+		this._formatTime();
+		if (this.$timeObj) this.$timeObj.text(this.formattedTime + o.timeSuffix);
+		this.timeDefined = true;
+		if (hasChanged) this._updateDateTime();
+	},
+    
+	//########################################################################
+	// call custom onSelect. 
+	// bind to sliders slidestop, and grid click.
+	//########################################################################
+	_onSelectHandler: function() {
+		var onSelect = this._defaults.onSelect;
+		var inputEl = this.$input ? this.$input[0] : null;
+		if (onSelect && inputEl) {
+			onSelect.apply(inputEl, [this.formattedDateTime, this]);
+		}
+	},
+
+	//########################################################################
+	// format the time all pretty...
+	//########################################################################
+	_formatTime: function(time, format, ampm) {
+		if (ampm == undefined) ampm = this._defaults.ampm;
+		time = time || { hour: this.hour, minute: this.minute, second: this.second, millisec: this.millisec, ampm: this.ampm, timezone: this.timezone };
+		var tmptime = (format || this._defaults.timeFormat).toString();
+
+		var hour = parseInt(time.hour, 10);
+		if (ampm) {
+			if (!$.inArray(time.ampm.toUpperCase(), this.amNames) !== -1)
+				hour = hour % 12;
+			if (hour === 0)
+				hour = 12;
+		}
+		tmptime = tmptime.replace(/(?:hh?|mm?|ss?|[tT]{1,2}|[lz])/g, function(match) {
+			switch (match.toLowerCase()) {
+				case 'hh': return ('0' + hour).slice(-2);
+				case 'h':  return hour;
+				case 'mm': return ('0' + time.minute).slice(-2);
+				case 'm':  return time.minute;
+				case 'ss': return ('0' + time.second).slice(-2);
+				case 's':  return time.second;
+				case 'l':  return ('00' + time.millisec).slice(-3);
+				case 'z':  return time.timezone;
+				case 't': case 'tt':
+					if (ampm) {
+						var _ampm = time.ampm;
+						if (match.length == 1)
+							_ampm = _ampm.charAt(0);
+						return match.charAt(0) == 'T' ? _ampm.toUpperCase() : _ampm.toLowerCase();
+					}
+					return '';
+			}
+		});
+
+		if (arguments.length) return tmptime;
+		else this.formattedTime = tmptime;
+	},
+
+	//########################################################################
+	// update our input with the new date time..
+	//########################################################################
+	_updateDateTime: function(dp_inst) {
+		dp_inst = this.inst || dp_inst;
+		var dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),
+			dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),
+			formatCfg = $.datepicker._getFormatConfig(dp_inst),
+			timeAvailable = dt !== null && this.timeDefined;
+		this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);
+		var formattedDateTime = this.formattedDate;
+		if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0))
+			return;
+
+		if (this._defaults.timeOnly === true) {
+			formattedDateTime = this.formattedTime;
+		} else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) {
+			formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;
+		}
+
+		this.formattedDateTime = formattedDateTime;
+
+		if(!this._defaults.showTimepicker) {
+			this.$input.val(this.formattedDate);
+		} else if (this.$altInput && this._defaults.altFieldTimeOnly === true) {
+			this.$altInput.val(this.formattedTime);
+			this.$input.val(this.formattedDate);
+		} else if(this.$altInput) {
+			this.$altInput.val(formattedDateTime);
+			this.$input.val(formattedDateTime);
+		} else {
+			this.$input.val(formattedDateTime);
+		}
+		
+		this.$input.trigger("change");
+	}
+
+});
+
+$.fn.extend({
+	//########################################################################
+	// shorthand just to use timepicker..
+	//########################################################################
+	timepicker: function(o) {
+		o = o || {};
+		var tmp_args = arguments;
+
+		if (typeof o == 'object') tmp_args[0] = $.extend(o, { timeOnly: true });
+
+		return $(this).each(function() {
+			$.fn.datetimepicker.apply($(this), tmp_args);
+		});
+	},
+
+	//########################################################################
+	// extend timepicker to datepicker
+	//########################################################################
+	datetimepicker: function(o) {
+		o = o || {};
+		var $input = this,
+		tmp_args = arguments;
+
+		if (typeof(o) == 'string'){
+			if(o == 'getDate') 
+				return $.fn.datepicker.apply($(this[0]), tmp_args);
+			else 
+				return this.each(function() {
+					var $t = $(this);
+					$t.datepicker.apply($t, tmp_args);
+				});
+		}
+		else
+			return this.each(function() {
+				var $t = $(this);
+				$t.datepicker($.timepicker._newInst($t, o)._defaults);
+			});
+	}
+});
+
+//########################################################################
+// the bad hack :/ override datepicker so it doesnt close on select
+// inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378
+//########################################################################
+$.datepicker._base_selectDate = $.datepicker._selectDate;
+$.datepicker._selectDate = function (id, dateStr) {
+	var inst = this._getInst($(id)[0]),
+		tp_inst = this._get(inst, 'timepicker');
+
+	if (tp_inst) {
+		tp_inst._limitMinMaxDateTime(inst, true);
+		inst.inline = inst.stay_open = true;
+		//This way the onSelect handler called from calendarpicker get the full dateTime
+		this._base_selectDate(id, dateStr);
+		inst.inline = inst.stay_open = false;
+		this._notifyChange(inst);
+		this._updateDatepicker(inst);
+	}
+	else this._base_selectDate(id, dateStr);
+};
+
+//#############################################################################################
+// second bad hack :/ override datepicker so it triggers an event when changing the input field
+// and does not redraw the datepicker on every selectDate event
+//#############################################################################################
+$.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;
+$.datepicker._updateDatepicker = function(inst) {
+
+	// don't popup the datepicker if there is another instance already opened
+	var input = inst.input[0];
+	if($.datepicker._curInst &&
+	   $.datepicker._curInst != inst &&
+	   $.datepicker._datepickerShowing &&
+	   $.datepicker._lastInput != input) {
+		return;
+	}
+
+	if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {
+				
+		this._base_updateDatepicker(inst);
+		
+		// Reload the time control when changing something in the input text field.
+		var tp_inst = this._get(inst, 'timepicker');
+		if(tp_inst) tp_inst._addTimePicker(inst);
+	}
+};
+
+//#######################################################################################
+// third bad hack :/ override datepicker so it allows spaces and colon in the input field
+//#######################################################################################
+$.datepicker._base_doKeyPress = $.datepicker._doKeyPress;
+$.datepicker._doKeyPress = function(event) {
+	var inst = $.datepicker._getInst(event.target),
+		tp_inst = $.datepicker._get(inst, 'timepicker');
+
+	if (tp_inst) {
+		if ($.datepicker._get(inst, 'constrainInput')) {
+			var ampm = tp_inst._defaults.ampm,
+				dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),
+				datetimeChars = tp_inst._defaults.timeFormat.toString()
+								.replace(/[hms]/g, '')
+								.replace(/TT/g, ampm ? 'APM' : '')
+								.replace(/Tt/g, ampm ? 'AaPpMm' : '')
+								.replace(/tT/g, ampm ? 'AaPpMm' : '')
+								.replace(/T/g, ampm ? 'AP' : '')
+								.replace(/tt/g, ampm ? 'apm' : '')
+								.replace(/t/g, ampm ? 'ap' : '') +
+								" " +
+								tp_inst._defaults.separator +
+								tp_inst._defaults.timeSuffix +
+								(tp_inst._defaults.showTimezone ? tp_inst._defaults.timezoneList.join('') : '') +
+								(tp_inst._defaults.amNames.join('')) +
+								(tp_inst._defaults.pmNames.join('')) +
+								dateChars,
+				chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);
+			return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);
+		}
+	}
+	
+	return $.datepicker._base_doKeyPress(event);
+};
+
+//#######################################################################################
+// Override key up event to sync manual input changes.
+//#######################################################################################
+$.datepicker._base_doKeyUp = $.datepicker._doKeyUp;
+$.datepicker._doKeyUp = function (event) {
+	var inst = $.datepicker._getInst(event.target),
+		tp_inst = $.datepicker._get(inst, 'timepicker');
+
+	if (tp_inst) {
+		if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) {
+			try {
+				$.datepicker._updateDatepicker(inst);
+			}
+			catch (err) {
+				$.datepicker.log(err);
+			}
+		}
+	}
+
+	return $.datepicker._base_doKeyUp(event);
+};
+
+//#######################################################################################
+// override "Today" button to also grab the time.
+//#######################################################################################
+$.datepicker._base_gotoToday = $.datepicker._gotoToday;
+$.datepicker._gotoToday = function(id) {
+	var inst = this._getInst($(id)[0]),
+		$dp = inst.dpDiv;
+	this._base_gotoToday(id);
+	var now = new Date();
+	var tp_inst = this._get(inst, 'timepicker');
+	if (tp_inst._defaults.showTimezone && tp_inst.timezone_select) {
+		var tzoffset = now.getTimezoneOffset(); // If +0100, returns -60
+		var tzsign = tzoffset > 0 ? '-' : '+';
+		tzoffset = Math.abs(tzoffset);
+		var tzmin = tzoffset % 60
+		tzoffset = tzsign + ('0' + (tzoffset - tzmin) / 60).slice(-2) + ('0' + tzmin).slice(-2);
+		if (tp_inst._defaults.timezoneIso8609)
+			tzoffset = tzoffset.substring(0, 3) + ':' + tzoffset.substring(3);
+		tp_inst.timezone_select.val(tzoffset);
+	}
+	this._setTime(inst, now);
+	$( '.ui-datepicker-today', $dp).click(); 
+};
+
+//#######################################################################################
+// Disable & enable the Time in the datetimepicker
+//#######################################################################################
+$.datepicker._disableTimepickerDatepicker = function(target, date, withDate) {
+	var inst = this._getInst(target),
+	tp_inst = this._get(inst, 'timepicker');
+	$(target).datepicker('getDate'); // Init selected[Year|Month|Day]
+	if (tp_inst) {
+		tp_inst._defaults.showTimepicker = false;
+		tp_inst._updateDateTime(inst);
+	}
+};
+
+$.datepicker._enableTimepickerDatepicker = function(target, date, withDate) {
+	var inst = this._getInst(target),
+	tp_inst = this._get(inst, 'timepicker');
+	$(target).datepicker('getDate'); // Init selected[Year|Month|Day]
+	if (tp_inst) {
+		tp_inst._defaults.showTimepicker = true;
+		tp_inst._addTimePicker(inst); // Could be disabled on page load
+		tp_inst._updateDateTime(inst);
+	}
+};
+
+//#######################################################################################
+// Create our own set time function
+//#######################################################################################
+$.datepicker._setTime = function(inst, date) {
+	var tp_inst = this._get(inst, 'timepicker');
+	if (tp_inst) {
+		var defaults = tp_inst._defaults,
+			// calling _setTime with no date sets time to defaults
+			hour = date ? date.getHours() : defaults.hour,
+			minute = date ? date.getMinutes() : defaults.minute,
+			second = date ? date.getSeconds() : defaults.second,
+			millisec = date ? date.getMilliseconds() : defaults.millisec;
+
+		//check if within min/max times..
+		if ((hour < defaults.hourMin || hour > defaults.hourMax) || (minute < defaults.minuteMin || minute > defaults.minuteMax) || (second < defaults.secondMin || second > defaults.secondMax) || (millisec < defaults.millisecMin || millisec > defaults.millisecMax)) {
+			hour = defaults.hourMin;
+			minute = defaults.minuteMin;
+			second = defaults.secondMin;
+			millisec = defaults.millisecMin;
+		}
+
+		tp_inst.hour = hour;
+		tp_inst.minute = minute;
+		tp_inst.second = second;
+		tp_inst.millisec = millisec;
+
+		if (tp_inst.hour_slider) tp_inst.hour_slider.slider('value', hour);
+		if (tp_inst.minute_slider) tp_inst.minute_slider.slider('value', minute);
+		if (tp_inst.second_slider) tp_inst.second_slider.slider('value', second);
+		if (tp_inst.millisec_slider) tp_inst.millisec_slider.slider('value', millisec);
+
+		tp_inst._onTimeChange();
+		tp_inst._updateDateTime(inst);
+	}
+};
+
+//#######################################################################################
+// Create new public method to set only time, callable as $().datepicker('setTime', date)
+//#######################################################################################
+$.datepicker._setTimeDatepicker = function(target, date, withDate) {
+	var inst = this._getInst(target),
+		tp_inst = this._get(inst, 'timepicker');
+
+	if (tp_inst) {
+		this._setDateFromField(inst);
+		var tp_date;
+		if (date) {
+			if (typeof date == "string") {
+				tp_inst._parseTime(date, withDate);
+				tp_date = new Date();
+				tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);
+			}
+			else tp_date = new Date(date.getTime());
+			if (tp_date.toString() == 'Invalid Date') tp_date = undefined;
+			this._setTime(inst, tp_date);
+		}
+	}
+
+};
+
+//#######################################################################################
+// override setDate() to allow setting time too within Date object
+//#######################################################################################
+$.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;
+$.datepicker._setDateDatepicker = function(target, date) {
+	var inst = this._getInst(target),
+	tp_date = (date instanceof Date) ? new Date(date.getTime()) : date;
+
+	this._updateDatepicker(inst);
+	this._base_setDateDatepicker.apply(this, arguments);
+	this._setTimeDatepicker(target, tp_date, true);
+};
+
+//#######################################################################################
+// override getDate() to allow getting time too within Date object
+//#######################################################################################
+$.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;
+$.datepicker._getDateDatepicker = function(target, noDefault) {
+	var inst = this._getInst(target),
+		tp_inst = this._get(inst, 'timepicker');
+
+	if (tp_inst) {
+		this._setDateFromField(inst, noDefault);
+		var date = this._getDate(inst);
+		if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);
+		return date;
+	}
+	return this._base_getDateDatepicker(target, noDefault);
+};
+
+//#######################################################################################
+// override parseDate() because UI 1.8.14 throws an error about "Extra characters"
+// An option in datapicker to ignore extra format characters would be nicer.
+//#######################################################################################
+$.datepicker._base_parseDate = $.datepicker.parseDate;
+$.datepicker.parseDate = function(format, value, settings) {
+	var date;
+	try {
+		date = this._base_parseDate(format, value, settings);
+	} catch (err) {
+		// Hack!  The error message ends with a colon, a space, and
+		// the "extra" characters.  We rely on that instead of
+		// attempting to perfectly reproduce the parsing algorithm.
+		date = this._base_parseDate(format, value.substring(0,value.length-(err.length-err.indexOf(':')-2)), settings);
+	}
+	return date;
+};
+
+//#######################################################################################
+// override formatDate to set date with time to the input
+//#######################################################################################
+$.datepicker._base_formatDate=$.datepicker._formatDate;
+$.datepicker._formatDate = function(inst, day, month, year){
+	var tp_inst = this._get(inst, 'timepicker');
+	if(tp_inst)
+	{
+		if(day)
+			var b = this._base_formatDate(inst, day, month, year);
+		tp_inst._updateDateTime(inst);	
+		return tp_inst.$input.val();
+	}
+	return this._base_formatDate(inst);
+}
+
+//#######################################################################################
+// override options setter to add time to maxDate(Time) and minDate(Time). MaxDate
+//#######################################################################################
+$.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;
+$.datepicker._optionDatepicker = function(target, name, value) {
+	var inst = this._getInst(target),
+		tp_inst = this._get(inst, 'timepicker');
+	if (tp_inst) {
+		var min,max,onselect;
+		if (typeof name == 'string') { // if min/max was set with the string
+			if (name==='minDate' || name==='minDateTime' )
+				min = value;
+			else if (name==='maxDate' || name==='maxDateTime')
+				max = value;
+			else if (name==='onSelect')
+				onselect=value;
+		} else if (typeof name == 'object') { //if min/max was set with the JSON
+			if(name.minDate)
+				min = name.minDate;
+			else if (name.minDateTime)
+				min = name.minDateTime;
+			else if (name.maxDate)
+				max = name.maxDate;
+			else if (name.maxDateTime)
+				max = name.maxDateTime;
+		}
+		if(min){ //if min was set
+			if(min==0)
+				min=new Date();
+			else
+				min= new Date(min);
+			
+			tp_inst._defaults.minDate = min;
+			tp_inst._defaults.minDateTime = min;
+		} else if (max){ //if max was set
+			if(max==0)
+				max=new Date();
+			else
+				max= new Date(max);
+			tp_inst._defaults.maxDate = max;
+			tp_inst._defaults.maxDateTime = max;
+		}
+		else if (onselect)
+			tp_inst._defaults.onSelect=onselect;
+	}
+	if (value === undefined)
+		return this._base_optionDatepicker(target, name);
+	return this._base_optionDatepicker(target, name, value);
+};
+
+//#######################################################################################
+// jQuery extend now ignores nulls!
+//#######################################################################################
+function extendRemove(target, props) {
+	$.extend(target, props);
+	for (var name in props)
+		if (props[name] === null || props[name] === undefined)
+			target[name] = props[name];
+	return target;
+}
+
+$.timepicker = new Timepicker(); // singleton instance
+$.timepicker.version = "0.9.8";
+
+})(jQuery);
+
diff --git a/js/seagullgallery.js b/js/seagullgallery.js
new file mode 100644
index 0000000..9237d76
--- /dev/null
+++ b/js/seagullgallery.js
@@ -0,0 +1,8 @@
+var ajaxurl = '/assets/modules/seagullgallery/ajax.php';
+
+$(document).ready(function() {
+//	� td:not(td:eq(1)) ����������� ������ ��� �������� �� ������� ��� ����� �� ������������ �������
+	$(document).on('click', '#t-galleries tbody tr.row-edit td:not(td:nth-child(2))', function() {
+		postForm('editGallery', $(this).parent('tr').attr('id').replace(/row/, ''));
+	});
+});
\ No newline at end of file
diff --git a/js/seagullgallery_config.js b/js/seagullgallery_config.js
new file mode 100644
index 0000000..129d36c
--- /dev/null
+++ b/js/seagullgallery_config.js
@@ -0,0 +1,67 @@
+/*	SeagullGallery for admin part
+*	Version 0.0.3
+*	Last update: 2012-03-21
+*/
+var ajaxurl = '/assets/modules/seagullgallery/ajax.php';
+
+$(document).ready(function() {
+
+//	COLOR PICKER ------------------------
+	$('input.colorpicker').jPicker({
+		window: {
+			expandable: false,
+			alphaSupport: true,
+			updateInputColor: false,
+			position: {
+				x: 'screenCenter', /* acceptable values "left", "center", "right", "screenCenter", or relative px value */
+				y: 'bottom' /* acceptable values "top", "bottom", "center", or relative px value */
+			}
+		},
+		color: {
+			mode: 'a'
+		}
+	},
+	function(color, context) {
+		$(this).val(color.val('ahex'));
+	}
+	);
+
+	$('#f-add-gallery').ajaxForm({ url:ajaxurl, dataType:'json',
+		success: function(data) {
+			msg.showAjax(data);
+		},
+		error: function(data){
+			msg.show('Ошибка при отправке запроса', 'error');
+		}
+	});
+
+	$('#f-gallery-config').ajaxForm({ url:ajaxurl, dataType:'json', data:{cmd:'saveGallery'},
+		beforeSend: function() {
+		},
+		success: function(data) {
+			msg.showAjax(data);
+		}
+	});
+
+//	RESIZE THUMBS ------------------------
+	$('#btn-resize-thumbs').click(function() {
+//		var id = row.attr('id');
+		msg.show('Операция выполняется...', 'loading');
+
+		$.post(ajaxurl, {cmd:'resizeThumbs', itemID:$('#ff-gid').val()}, function(data) {
+			msg.showAjax(data);
+		}, 'json');
+	});
+
+	$('#btn-clear-tables').click(function() {
+		if (confirm("Будут удалены все галереи без возвратно. Продолжить?")) {
+			msg.show('Операция выполняется...', 'loading');
+
+			$.post(ajaxurl, {cmd:'clearTables', itemID:$('#ff-gid').val()}, function(data) {
+				msg.showAjax(data);
+			}, 'json');
+		}
+		return false;
+	});
+
+});
\ No newline at end of file
diff --git a/js/seagullgallery_images.js b/js/seagullgallery_images.js
new file mode 100644
index 0000000..55baed5
--- /dev/null
+++ b/js/seagullgallery_images.js
@@ -0,0 +1,228 @@
+/*	SeagullGallery for admin part
+*	Version 0.0.3
+*	Last update: 2012-03-21
+*/
+var ajaxurl = '/assets/modules/seagullgallery/ajax.php';
+var arrSelect = [];
+
+$(document).ready(function() {
+	allLockBtns = $('#btn-del-imgs');
+	allLockBtns.addClass('disabled');
+
+// SORT TABLE ---------------------------
+	$("table.tsort").tableDnD({
+		onDragClass: "tsort__dragClass",
+		dragHandle: "tsort__dragHandle",
+		onDrop: function(table, row) {
+			var rows = table.tBodies[0].rows;
+			var w = '';
+			// В цикле создаем разделенный символом ";" список, в котором последовательно размещены id строк
+			for (var i = 0; i < rows.length; i++) {
+				if (i != 0)
+					w += ',';
+				w += rows[i].id;
+			}
+			// Передаем данные на сервер
+			$.ajax({ type:'POST', url:ajaxurl, timeout:5000, dataType:'json',
+				data: {arr_sort: w, cmd: 'imgs_sort'},
+				success: function(data){
+					msg.showAjax(data);
+				},
+				error: function(data){
+					msg.show('Ошибка при отправке запроса', 'error');
+				}
+			});
+		}
+	});
+	$('table.tsort tbody tr').hover(function() {
+		$(this.cells[1]).addClass('showDragHandle');
+	}, function() {
+		$(this.cells[1]).removeClass('showDragHandle');
+	});
+
+//	SELECT IMAGES ------------------------
+	$('.img_select').click(function() {
+		var selTR = $(this).parent('td').parent('tr');
+		var selID = selTR.prop('id');
+
+		if (arrSelect.in_array(selID)) arrSelect.splice(arrSelect.indexOf(selID), 1);
+		else arrSelect.push(selID);
+
+		if (arrSelect.length === 0)	allLockBtns.addClass('disabled');
+		else allLockBtns.removeClass('disabled');
+
+		if ($(this).prop('checked') == true) selTR.addClass('row-selected');
+		else selTR.removeClass('row-selected');
+
+	});
+
+//	UPLOAD IMAGES ------------------------
+	var bar = $('.b-progress__bar');
+	var percent = $('.b-progress__percent');
+
+	$('#btn-add-imgs').click(function() {
+		$('#btn-selectfiles').click();
+		return false;
+	});
+	$('#btn-selectfiles').change(function() {
+		$('#f-upload').submit();
+	});
+
+	$('#f-upload').ajaxForm({ url:ajaxurl, dataType: 'json',
+		beforeSend: function() {
+			$('.b-progress').show();
+			var percentVal = '0%';
+			bar.width(percentVal)
+			percent.html(percentVal);
+		},
+		uploadProgress: function(event, position, total, percentComplete) {
+			console.log('position:'+position+' total:'+total+' percentComplete:'+percentComplete);
+			var percentVal = percentComplete + '%';
+			bar.width(percentVal)
+			percent.html(percentVal);
+			//console.log(percentVal, position, total);
+		},
+		complete: function(xhr) {
+			console.log(xhr.responseText);
+//			status.html(xhr.responseText);
+		},
+		success: function(data) {
+			msg.showAjax(data);
+			$('#t-imgs > tbody').append(data.rows);
+			$('.b-progress').hide();
+			$('#no-imgs').remove();
+		},
+		error: function(data){
+			msg.show('Ошибка при отправке запроса (f-upload)', 'error');
+		}
+	});
+
+//	SUBMIT DELETE IMAGES ------------------------
+	$('#btn-del-imgs').click(function() {
+		if ($(this).hasClass('disabled'))
+			return false;
+
+		var query = $('#f-imgs-form').formSerialize();
+
+		$.post(ajaxurl, query+'&cmd=delImgs', function(data){
+			console.log(data.remove_arr);
+			$(data.remove_arr).remove();
+			msg.showAjax(data);
+//			Скрытие/отключение разных кнопок, чтобы не возникало конфликтов
+//			guiStatus('lock');
+		}, 'json');
+		return false;
+	});
+
+//	enable/disable элементов интерфейса при вызове форм
+	function guiStatus(action) {
+		if (action==='lock') {
+			$('#f-addimage input').attr('disabled', 'disabled');
+//			$('#add-image').button('disable');
+//			$('#submit-image').button('disable');
+//			$('#btn-del-imgs').button('disable');
+		}
+		else {
+			$('#f-addimage input').attr('disabled', '');
+//			$('#add-image').button('enable');
+//			$('#submit-image').button('enable');
+//			$('#btn-del-imgs').button('enable');
+		}
+	};
+
+//	OPEN EDIT FORM ------------------------
+	$(document).on('click', '#t-imgs td.col-edit', function() {
+		btn_cancel();
+
+		var row = $(this).parent('tr');
+		var id = row.attr('id');
+
+		row.before('<tr id="edit_form_row"><td id="photo" style="vertical-align:top"></td><td></td><td id="edit_form_col" colspan="'+($('#t-imgs tr:first-child td').length-2)+'"></td></tr>');
+		row.hide();
+		$('#edit_form_col').append($('#form-container').contents());
+
+		$.post(ajaxurl, {cmd:'getimg', id:id}, function(data){
+
+			$('#photo').append($('#'+id+' td:eq(0)').html());
+
+			$('#ff-img-id').val(data.obj.id);
+			$('#ff-img-title').val(data.obj.title);
+			$('#ff-img-description').val(data.obj.description);
+
+//			Скрытие/отключение разных кнопок, чтобы не возникало конфликтов
+			guiStatus('lock');
+		}, 'json');
+	});
+
+//	CLOSE FORM ------------------------
+	$(document).on('click', '#t-imgs input.btn-cancel', btn_cancel);
+
+	function btn_cancel() {
+		if ($('#edit_form_row').length) {	// if edit form
+			$('#edit_form_row').next().show();
+			$('#edit_form_col').contents().appendTo($('#form-container'));
+			$('#edit_form_row').remove();
+
+			$('#ff-id').remove();
+			$('#f-image').clearForm();
+//			Активация/включение разных кнопок, полей после их блокировки
+			guiStatus('unlock');
+
+			if ($('#btn-crop-release').is(':visible')) {
+				crop_destroy();
+			}
+		}
+		else {	// if new form
+			if ($('#new_form_col').length) {
+				$('#new_form_col').contents().appendTo($('#form-container'));
+				$('#new_form_row').remove();
+
+				$('#btn-new-form').button('option', 'label', $('#btn-new-form').attr('title'));
+				$('#f-image').find('.btn-del').show();
+			}
+		}
+//		$(this).button('enable');
+	};
+
+// SUBMIT FORM ---------------------------
+	$('#f-image').ajaxForm({ url:ajaxurl, dataType:'json',
+		beforeSubmit: function(arr, $form, options) {
+			msg.show('Операция выполняется...', 'loading');
+		},
+		success: function(data) {
+			msg.showAjax(data);
+			if (data.ok.length) {
+				if (data.edit) {
+					$('#edit_form_row').next().remove();	// delete row with old data
+					$('#edit_form_row').after(data.obj); // insert row with new data
+
+					$('#edit_form_col').contents().appendTo($('#form-container'));
+					$('#edit_form_row').remove();
+//						guiStatus('unlock');
+				}
+				else {
+					$('#new_form_row').after(data.obj);
+				}
+				$('#f-image').resetForm();
+			}
+		},
+		error: function(data){
+			msg.show('Ошибка при отправке запроса', 'error');
+		}
+	});
+
+/*	$("#t-imgs img").click(function() {
+
+	});
+*/
+	
+});
+
+Array.prototype.in_array = function(p_val) {
+	for(var i = 0, l = this.length; i < l; i++)	{
+		if(this[i] == p_val) {
+			return true;
+		}
+	}
+	return false;
+}
diff --git a/site/graphics/close.png b/site/graphics/close.png
new file mode 100644
index 0000000..4de4396
Binary files /dev/null and b/site/graphics/close.png differ
diff --git a/site/graphics/closeX.png b/site/graphics/closeX.png
new file mode 100644
index 0000000..cf5d018
Binary files /dev/null and b/site/graphics/closeX.png differ
diff --git a/site/graphics/controlbar-black-border.gif b/site/graphics/controlbar-black-border.gif
new file mode 100644
index 0000000..e2403fe
Binary files /dev/null and b/site/graphics/controlbar-black-border.gif differ
diff --git a/site/graphics/controlbar-text-buttons.png b/site/graphics/controlbar-text-buttons.png
new file mode 100644
index 0000000..d2f72e0
Binary files /dev/null and b/site/graphics/controlbar-text-buttons.png differ
diff --git a/site/graphics/controlbar-white-small.gif b/site/graphics/controlbar-white-small.gif
new file mode 100644
index 0000000..462fce7
Binary files /dev/null and b/site/graphics/controlbar-white-small.gif differ
diff --git a/site/graphics/controlbar-white.gif b/site/graphics/controlbar-white.gif
new file mode 100644
index 0000000..1f143f5
Binary files /dev/null and b/site/graphics/controlbar-white.gif differ
diff --git a/site/graphics/controlbar2.gif b/site/graphics/controlbar2.gif
new file mode 100644
index 0000000..39ad652
Binary files /dev/null and b/site/graphics/controlbar2.gif differ
diff --git a/site/graphics/controlbar3.gif b/site/graphics/controlbar3.gif
new file mode 100644
index 0000000..3eebb81
Binary files /dev/null and b/site/graphics/controlbar3.gif differ
diff --git a/site/graphics/controlbar4-hover.gif b/site/graphics/controlbar4-hover.gif
new file mode 100644
index 0000000..ca08b59
Binary files /dev/null and b/site/graphics/controlbar4-hover.gif differ
diff --git a/site/graphics/controlbar4.gif b/site/graphics/controlbar4.gif
new file mode 100644
index 0000000..7a3ad34
Binary files /dev/null and b/site/graphics/controlbar4.gif differ
diff --git a/site/graphics/fullexpand.gif b/site/graphics/fullexpand.gif
new file mode 100644
index 0000000..26d9ed0
Binary files /dev/null and b/site/graphics/fullexpand.gif differ
diff --git a/site/graphics/geckodimmer.png b/site/graphics/geckodimmer.png
new file mode 100644
index 0000000..309bb27
Binary files /dev/null and b/site/graphics/geckodimmer.png differ
diff --git a/site/graphics/icon.gif b/site/graphics/icon.gif
new file mode 100644
index 0000000..b74a073
Binary files /dev/null and b/site/graphics/icon.gif differ
diff --git a/site/graphics/loader.gif b/site/graphics/loader.gif
new file mode 100644
index 0000000..0b31f6f
Binary files /dev/null and b/site/graphics/loader.gif differ
diff --git a/site/graphics/loader.white.gif b/site/graphics/loader.white.gif
new file mode 100644
index 0000000..f2a1bc0
Binary files /dev/null and b/site/graphics/loader.white.gif differ
diff --git a/site/graphics/outlines/Outlines.psd b/site/graphics/outlines/Outlines.psd
new file mode 100644
index 0000000..5405651
Binary files /dev/null and b/site/graphics/outlines/Outlines.psd differ
diff --git a/site/graphics/outlines/beveled.png b/site/graphics/outlines/beveled.png
new file mode 100644
index 0000000..fc428f4
Binary files /dev/null and b/site/graphics/outlines/beveled.png differ
diff --git a/site/graphics/outlines/drop-shadow.png b/site/graphics/outlines/drop-shadow.png
new file mode 100644
index 0000000..0186c2e
Binary files /dev/null and b/site/graphics/outlines/drop-shadow.png differ
diff --git a/site/graphics/outlines/glossy-dark.png b/site/graphics/outlines/glossy-dark.png
new file mode 100644
index 0000000..3c64c0d
Binary files /dev/null and b/site/graphics/outlines/glossy-dark.png differ
diff --git a/site/graphics/outlines/outer-glow.png b/site/graphics/outlines/outer-glow.png
new file mode 100644
index 0000000..288d43f
Binary files /dev/null and b/site/graphics/outlines/outer-glow.png differ
diff --git a/site/graphics/outlines/rounded-black.png b/site/graphics/outlines/rounded-black.png
new file mode 100644
index 0000000..a77e65d
Binary files /dev/null and b/site/graphics/outlines/rounded-black.png differ
diff --git a/site/graphics/outlines/rounded-white.png b/site/graphics/outlines/rounded-white.png
new file mode 100644
index 0000000..0d4b817
Binary files /dev/null and b/site/graphics/outlines/rounded-white.png differ
diff --git a/site/graphics/resize.gif b/site/graphics/resize.gif
new file mode 100644
index 0000000..9100de7
Binary files /dev/null and b/site/graphics/resize.gif differ
diff --git a/site/graphics/scrollarrows.png b/site/graphics/scrollarrows.png
new file mode 100644
index 0000000..b3d5575
Binary files /dev/null and b/site/graphics/scrollarrows.png differ
diff --git a/site/graphics/zoomin.cur b/site/graphics/zoomin.cur
new file mode 100644
index 0000000..cb79124
Binary files /dev/null and b/site/graphics/zoomin.cur differ
diff --git a/site/graphics/zoomout.cur b/site/graphics/zoomout.cur
new file mode 100644
index 0000000..acf6199
Binary files /dev/null and b/site/graphics/zoomout.cur differ
diff --git a/site/highslide-ie6.css b/site/highslide-ie6.css
new file mode 100644
index 0000000..b4d5484
--- /dev/null
+++ b/site/highslide-ie6.css
@@ -0,0 +1,76 @@
+.closebutton {
+    /* NOTE! This URL is relative to the HTML page, not the CSS */
+	filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(
+		src='../highslide/graphics/close.png', sizingMethod='scale');
+
+	background: none;
+	cursor: hand;
+}
+
+/* Viewport fixed hack */
+.highslide-viewport {
+	position: absolute;
+    left: expression( ( ( ignoreMe1 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
+	top: expression( ( ignoreMe2 = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) + 'px' );
+	width: expression( ( ( ignoreMe3 = document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) ) + 'px' );
+	height: expression( ( ( ignoreMe4 = document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) ) + 'px' );
+}
+
+/* Thumbstrip PNG fix */
+.highslide-scroll-down, .highslide-scroll-up {
+	position: relative;
+	overflow: hidden;
+}
+.highslide-scroll-down div, .highslide-scroll-up div {
+	/* NOTE! This URL is relative to the HTML page, not the CSS */
+	filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(
+		src='../highslide/graphics/scrollarrows.png', sizingMethod='scale');
+	background: none !important;
+	position: absolute;
+	cursor: hand;
+	width: 75px;
+	height: 75px !important;
+}
+.highslide-thumbstrip-horizontal .highslide-scroll-down div {
+	left: -50px;
+	top: -15px;
+}
+.highslide-thumbstrip-horizontal .highslide-scroll-up div {
+	top: -15px;
+}
+.highslide-thumbstrip-vertical .highslide-scroll-down div {
+	top: -50px;
+}
+
+/* Thumbstrip marker arrow trasparent background fix */
+.highslide-thumbstrip .highslide-marker {
+	border-color: white; /* match the background */
+}
+.dark .highslide-thumbstrip-horizontal .highslide-marker {
+	border-color: #111;
+}
+.highslide-viewport .highslide-marker {
+	border-color: #333;
+}
+.highslide-thumbstrip {
+	float: left;
+}
+
+/* Positioning fixes for the control bar */
+.text-controls .highslide-controls {
+	width: 480px;
+}
+.text-controls a span {
+	width: 4em;
+}
+.text-controls .highslide-full-expand a span {
+	width: 0;
+}
+.text-controls .highslide-close a span {
+	width: 0;
+}
+
+/* Special */
+.in-page .highslide-thumbstrip-horizontal .highslide-marker {
+    border-bottom: gray;
+}
diff --git a/site/highslide-with-gallery.packed.js b/site/highslide-with-gallery.packed.js
new file mode 100644
index 0000000..449942c
--- /dev/null
+++ b/site/highslide-with-gallery.packed.js
@@ -0,0 +1,9 @@
+/** 
+ * Name:    Highslide JS
+ * Version: 4.1.13 (2011-10-06)
+ * Config:  default +slideshow +positioning +transitions +viewport +thumbstrip +packed
+ * Author:  Torstein Hønsi
+ * Support: www.highslide.com/support
+ * License: www.highslide.com/#license
+ */
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('q(!m){u m={18:{9C:\'9t\',9f:\'bb...\',9g:\'8o 1L ba\',9Y:\'8o 1L bd 1L bw\',7p:\'bx 1L bl B (f)\',aS:\'bp by <i>8H 8I</i>\',b0:\'bn 1L bj 8H 8I bz\',8T:\'8C\',8U:\'8D\',8w:\'8E\',8v:\'8J\',8t:\'8J (bv)\',bu:\'bg\',8P:\'8G\',8A:\'8G 1g (8B)\',8N:\'8F\',8M:\'8F 1g (8B)\',8S:\'8C (8l 14)\',8O:\'8D (8l 2V)\',8s:\'8E\',8r:\'1:1\',3n:\'b9 %1 bq %2\',84:\'8o 1L 26 2M, c4 8L c6 1L 3i. c0 8l c1 K 1p 8L 3c.\'},4p:\'L/bX/\',5M:\'bI.4y\',5m:\'bK.4y\',7f:53,8p:53,4L:15,9M:15,4j:15,9K:15,4z:bE,91:0.75,9j:J,7A:5,3B:2,bP:3,4R:1f,at:\'4g 2V\',aq:1,an:J,aF:\'bQ://L.c2/\',aE:\'bO\',8V:J,8e:[\'a\'],2Z:[],aL:53,3I:0,7G:50,3Q:\'2n\',6H:\'2n\',8y:H,8x:H,7v:J,5c:8R,5w:8R,5q:J,1B:\'bR-bS\',a6:{2B:\'<X 2s="L-2B"><7V>\'+\'<1R 2s="L-3c">\'+\'<a 1Y="#" 1X="{m.18.8S}">\'+\'<23>{m.18.8T}</23></a>\'+\'</1R>\'+\'<1R 2s="L-3r">\'+\'<a 1Y="#" 1X="{m.18.8A}">\'+\'<23>{m.18.8P}</23></a>\'+\'</1R>\'+\'<1R 2s="L-2S">\'+\'<a 1Y="#" 1X="{m.18.8M}">\'+\'<23>{m.18.8N}</23></a>\'+\'</1R>\'+\'<1R 2s="L-1p">\'+\'<a 1Y="#" 1X="{m.18.8O}">\'+\'<23>{m.18.8U}</23></a>\'+\'</1R>\'+\'<1R 2s="L-3i">\'+\'<a 1Y="#" 1X="{m.18.8s}">\'+\'<23>{m.18.8w}</23></a>\'+\'</1R>\'+\'<1R 2s="L-1a-2D">\'+\'<a 1Y="#" 1X="{m.18.7p}">\'+\'<23>{m.18.8r}</23></a>\'+\'</1R>\'+\'<1R 2s="L-26">\'+\'<a 1Y="#" 1X="{m.18.8t}" >\'+\'<23>{m.18.8v}</23></a>\'+\'</1R>\'+\'</7V></X>\'},4X:[],6Z:J,W:[],6V:[\'5q\',\'30\',\'3Q\',\'6H\',\'8y\',\'8x\',\'1B\',\'3B\',\'bG\',\'bH\',\'bJ\',\'8u\',\'bW\',\'cd\',\'cc\',\'8z\',\'aW\',\'7v\',\'3D\',\'5b\',\'2Z\',\'3I\',\'M\',\'1b\',\'7B\',\'5c\',\'5w\',\'6F\',\'6R\',\'9i\',\'2t\',\'2r\',\'aT\',\'aD\',\'1G\'],1x:[],4V:0,7q:{x:[\'9H\',\'14\',\'4i\',\'2V\',\'9L\'],y:[\'4T\',\'11\',\'8h\',\'4g\',\'6D\']},66:{},8z:{},8u:{},3u:[],4U:[],48:{},7I:{},5G:[],21:/ca\\/4\\.0/.19(4B.5r)?8:8n((4B.5r.5Y().2H(/.+(?:9y|c9|ce|2m)[\\/: ]([\\d.]+)/)||[0,\'0\'])[1]),2m:(R.52&&!1A.3q),4u:/cf/.19(4B.5r),5Z:/ci.+9y:1\\.[0-8].+cg/.19(4B.5r),$:z(1M){q(1M)D R.c7(1M)},2p:z(2o,3j){2o[2o.S]=3j},1c:z(9m,4k,3P,8b,9n){u C=R.1c(9m);q(4k)m.3b(C,4k);q(9n)m.V(C,{bY:0,aM:\'1F\',6S:0});q(3P)m.V(C,3P);q(8b)8b.2E(C);D C},3b:z(C,4k){K(u x 2T 4k)C[x]=4k[x];D C},V:z(C,3P){K(u x 2T 3P){q(m.4d&&x==\'1n\'){q(3P[x]>0.99)C.G.c5(\'5j\');I C.G.5j=\'9o(1n=\'+(3P[x]*28)+\')\'}I C.G[x]=3P[x]}},2b:z(C,Z,31){u 41,4v,47;q(1q 31!=\'6q\'||31===H){u 36=9V;31={3J:36[2],2r:36[3],63:36[4]}}q(1q 31.3J!=\'3n\')31.3J=53;31.2r=1d[31.2r]||1d.93;31.5S=m.3b({},Z);K(u 35 2T Z){u e=24 m.1E(C,31,35);41=8n(m.7U(C,35))||0;4v=8n(Z[35]);47=35!=\'1n\'?\'F\':\'\';e.3F(41,4v,47)}},7U:z(C,Z){q(C.G[Z]){D C.G[Z]}I q(R.6T){D R.6T.9P(C,H).9Q(Z)}I{q(Z==\'1n\')Z=\'5j\';u 3j=C.bf[Z.2j(/\\-(\\w)/g,z(a,b){D b.92()})];q(Z==\'5j\')3j=3j.2j(/9o\\(1n=([0-9]+)\\)/,z(a,b){D b/28});D 3j===\'\'?1:3j}},6v:z(){u d=R,w=1A,5d=d.6i&&d.6i!=\'7P\'?d.4l:d.3x,4d=m.2m&&(m.21<9||1q 9l==\'1C\');u M=4d?5d.8m:(d.4l.8m||5J.b2),1b=4d?5d.aK:5J.b3;m.3S={M:M,1b:1b,5l:4d?5d.5l:9l,5i:4d?5d.5i:be};D m.3S},6g:z(C){u p={x:C.4f,y:C.9h};4o(C.9k){C=C.9k;p.x+=C.4f;p.y+=C.9h;q(C!=R.3x&&C!=R.4l){p.x-=C.5l;p.y-=C.5i}}D p},2D:z(a,2O,3F,T){q(!a)a=m.1c(\'a\',H,{1u:\'1F\'},m.22);q(1q a.5u==\'z\')D 2O;2d{24 m.4Z(a,2O,3F);D 1f}1W(e){D J}},a4:z(C,4F,U){u 1i=C.2L(4F);K(u i=0;i<1i.S;i++){q((24 5X(U)).19(1i[i].U)){D 1i[i]}}D H},a7:z(s){s=s.2j(/\\s/g,\' \');u 1T=/{m\\.18\\.([^}]+)\\}/g,4S=s.2H(1T),18;q(4S)K(u i=0;i<4S.S;i++){18=4S[i].2j(1T,"$1");q(1q m.18[18]!=\'1C\')s=s.2j(4S[i],m.18[18])}D s},9w:z(){u 7J=0,6j=-1,W=m.W,A,1r;K(u i=0;i<W.S;i++){A=W[i];q(A){1r=A.Q.G.1r;q(1r&&1r>7J){7J=1r;6j=i}}}q(6j==-1)m.3v=-1;I W[6j].43()},5h:z(a,5p){a.5u=a.2G;u p=a.5u?a.5u():H;a.5u=H;D(p&&1q p[5p]!=\'1C\')?p[5p]:(1q m[5p]!=\'1C\'?m[5p]:H)},73:z(a){u 1G=m.5h(a,\'1G\');q(1G)D 1G;D a.1Y},4W:z(1M){u 3w=m.$(1M),45=m.7I[1M],a={};q(!3w&&!45)D H;q(!45){45=3w.7j(J);45.1M=\'\';m.7I[1M]=45;D 3w}I{D 45.7j(J)}},3H:z(d){q(d)m.8j.2E(d);m.8j.2R=\'\'},1m:z(A){q(!m.2a){7E=J;m.2a=m.1c(\'X\',{U:\'L-bk L-1Z-B\',4x:\'\',2G:z(){m.26()}},{1e:\'1D\',1n:0},m.22,J);q(/(bm|bt|bo|br)/.19(4B.5r)){u 3x=R.3x;z 7H(){m.V(m.2a,{M:3x.bA+\'F\',1b:3x.b5+\'F\'})}7H();m.1Q(1A,\'3O\',7H)}}m.2a.G.1u=\'\';u 7E=m.2a.4x==\'\';m.2a.4x+=\'|\'+A.P;q(7E){q(m.5Z&&m.9q)m.V(m.2a,{9e:\'5O(\'+m.4p+\'bh.97)\',1n:1});I m.2b(m.2a,{1n:A.3I},m.7G)}},7Q:z(P){q(!m.2a)D;q(1q P!=\'1C\')m.2a.4x=m.2a.4x.2j(\'|\'+P,\'\');q((1q P!=\'1C\'&&m.2a.4x!=\'\')||(m.1U&&m.5h(m.1U,\'3I\')))D;q(m.5Z&&m.9q)m.2a.G.1u=\'1F\';I m.2b(m.2a,{1n:0},m.7G,H,z(){m.2a.G.1u=\'1F\'})},83:z(6n,A){u Y=A||m.2h();A=Y;q(m.1U)D 1f;I m.Y=Y;m.49(R,1A.3q?\'5P\':\'5Q\',m.4N);2d{m.1U=6n;6n.2G()}1W(e){m.Y=m.1U=H}2d{q(!6n||A.2Z[1]!=\'3Y\')A.26()}1W(e){}D 1f},6d:z(C,1P){u A=m.2h(C);q(A)D m.83(A.7b(1P),A);I D 1f},3c:z(C){D m.6d(C,-1)},1p:z(C){D m.6d(C,1)},4N:z(e){q(!e)e=1A.29;q(!e.2i)e.2i=e.7l;q(1q e.2i.9x!=\'1C\')D J;u A=m.2h();u 1P=H;8Y(e.cq){1I 70:q(A)A.6k();D J;1I 32:1P=2;5B;1I 34:1I 39:1I 40:1P=1;5B;1I 8:1I 33:1I 37:1I 38:1P=-1;5B;1I 27:1I 13:1P=0}q(1P!==H){q(1P!=2)m.49(R,1A.3q?\'5P\':\'5Q\',m.4N);q(!m.8V)D J;q(e.4D)e.4D();I e.9W=1f;q(A){q(1P==0){A.26()}I q(1P==2){q(A.1g)A.1g.ad()}I{q(A.1g)A.1g.2S();m.6d(A.P,1P)}D 1f}}D J},d5:z(O){m.2p(m.1x,m.3b(O,{1H:\'1H\'+m.4V++}))},d4:z(1h){u 2C=1h.2t;q(1q 2C==\'6q\'){K(u i=0;i<2C.S;i++){u o={};K(u x 2T 1h)o[x]=1h[x];o.2t=2C[i];m.2p(m.4U,o)}}I{m.2p(m.4U,1h)}},86:z(7N,65){u C,1T=/^L-Q-([0-9]+)$/;C=7N;4o(C.1O){q(C.5F!==1C)D C.5F;q(C.1M&&1T.19(C.1M))D C.1M.2j(1T,"$1");C=C.1O}q(!65){C=7N;4o(C.1O){q(C.4F&&m.5L(C)){K(u P=0;P<m.W.S;P++){u A=m.W[P];q(A&&A.a==C)D P}}C=C.1O}}D H},2h:z(C,65){q(1q C==\'1C\')D m.W[m.3v]||H;q(1q C==\'3n\')D m.W[C]||H;q(1q C==\'8q\')C=m.$(C);D m.W[m.86(C,65)]||H},5L:z(a){D(a.2G&&a.2G.aI().2j(/\\s/g,\' \').2H(/m.(d6|e)d7/))},ai:z(){K(u i=0;i<m.W.S;i++)q(m.W[i]&&m.W[i].55)m.9w()},87:z(e){q(!e)e=1A.29;q(e.d9>1)D J;q(!e.2i)e.2i=e.7l;u C=e.2i;4o(C.1O&&!(/L-(2M|3i|5W|3O)/.19(C.U))){C=C.1O}u A=m.2h(C);q(A&&(A.8c||!A.55))D J;q(A&&e.T==\'aH\'){q(e.2i.9x)D J;u 2H=C.U.2H(/L-(2M|3i|3O)/);q(2H){m.2I={A:A,T:2H[1],14:A.x.E,M:A.x.B,11:A.y.E,1b:A.y.B,9v:e.6c,9u:e.68};m.1Q(R,\'6o\',m.5V);q(e.4D)e.4D();q(/L-(2M|5W)-89/.19(A.17.U)){A.43();m.7R=J}D 1f}}I q(e.T==\'aA\'){m.49(R,\'6o\',m.5V);q(m.2I){q(m.4I&&m.2I.T==\'2M\')m.2I.A.17.G.46=m.4I;u 3y=m.2I.3y;q(!3y&&!m.7R&&!/(3i|3O)/.19(m.2I.T)){A.26()}I q(3y||(!3y&&m.d8)){m.2I.A.5s(\'1s\')}m.7R=1f;m.2I=H}I q(/L-2M-89/.19(C.U)){C.G.46=m.4I}}D 1f},5V:z(e){q(!m.2I)D J;q(!e)e=1A.29;u a=m.2I,A=a.A;a.5T=e.6c-a.9v;a.7o=e.68-a.9u;u 7s=1d.ck(1d.9r(a.5T,2)+1d.9r(a.7o,2));q(!a.3y)a.3y=(a.T!=\'2M\'&&7s>0)||(7s>(m.cX||5));q(a.3y&&e.6c>5&&e.68>5){q(a.T==\'3O\')A.3O(a);I{A.7C(a.14+a.5T,a.11+a.7o);q(a.T==\'2M\')A.17.G.46=\'3i\'}}D 1f},8Q:z(e){2d{q(!e)e=1A.29;u 6C=/cW/i.19(e.T);q(!e.2i)e.2i=e.7l;q(!e.6E)e.6E=6C?e.db:e.di;u A=m.2h(e.2i);q(!A.55)D;q(!A||!e.6E||m.2h(e.6E,J)==A||m.2I)D;K(u i=0;i<A.1x.S;i++)(z(){u o=m.$(\'1H\'+A.1x[i]);q(o&&o.69){q(6C)m.V(o,{1e:\'1D\',1u:\'\'});m.2b(o,{1n:6C?o.1n:0},o.3t)}})()}1W(e){}},1Q:z(C,29,3l){q(C==R&&29==\'3s\'){m.2p(m.5G,3l)}2d{C.1Q(29,3l,1f)}1W(e){2d{C.9s(\'54\'+29,3l);C.dn(\'54\'+29,3l)}1W(e){C[\'54\'+29]=3l}}},49:z(C,29,3l){2d{C.49(29,3l,1f)}1W(e){2d{C.9s(\'54\'+29,3l)}1W(e){C[\'54\'+29]=H}}},6A:z(i){q(m.6Z&&m.4X[i]&&m.4X[i]!=\'1C\'){u 1y=R.1c(\'1y\');1y.64=z(){1y=H;m.6A(i+1)};1y.1G=m.4X[i]}},9R:z(3n){q(3n&&1q 3n!=\'6q\')m.7A=3n;u 2o=m.60();K(u i=0;i<2o.4A.S&&i<m.7A;i++){m.2p(m.4X,m.73(2o.4A[i]))}q(m.1B)24 m.4O(m.1B,z(){m.6A(0)});I m.6A(0);q(m.5m)u 4y=m.1c(\'1y\',{1G:m.4p+m.5m})},71:z(){q(!m.22){m.3E=m.2m&&m.21<7;m.4d=m.2m&&m.21<9;m.6v();K(u x 2T m.5U){q(1q m[x]!=\'1C\')m.18[x]=m[x];I q(1q m.18[x]==\'1C\'&&1q m.5U[x]!=\'1C\')m.18[x]=m.5U[x]}m.22=m.1c(\'X\',{U:\'L-22\'},{1j:\'2v\',14:0,11:0,M:\'28%\',1r:m.4z,9F:\'9t\'},R.3x,J);m.1S=m.1c(\'a\',{U:\'L-1S\',1X:m.18.9g,2R:m.18.9f,1Y:\'av:;\'},{1j:\'2v\',11:\'-4P\',1n:m.91,1r:1},m.22);m.8j=m.1c(\'X\',H,{1u:\'1F\'},m.22);m.1Z=m.1c(\'X\',{U:\'L-1Z L-1Z-B\'},{1e:(m.4u&&m.21<6t)?\'1D\':\'1s\'},m.22,1);1d.de=z(t,b,c,d){D c*t/d+b};1d.93=z(t,b,c,d){D c*(t/=d)*t+b};1d.7n=z(t,b,c,d){D-c*(t/=d)*(t-2)+b};m.9U=m.3E;m.9z=((1A.3q&&m.21<9)||4B.cU==\'cV\'||(m.3E&&m.21<5.5))}},3s:z(){q(m.6I)D;m.6I=J;K(u i=0;i<m.5G.S;i++)m.5G[i]()},7O:z(){u C,1i,52=[],4A=[],2N={},1T;K(u i=0;i<m.8e.S;i++){1i=R.2L(m.8e[i]);K(u j=0;j<1i.S;j++){C=1i[j];1T=m.5L(C);q(1T){m.2p(52,C);q(1T[0]==\'m.2D\')m.2p(4A,C);u g=m.5h(C,\'2t\')||\'1F\';q(!2N[g])2N[g]=[];m.2p(2N[g],C)}}}m.3R={52:52,2N:2N,4A:4A};D m.3R},60:z(){D m.3R||m.7O()},26:z(C){u A=m.2h(C);q(A)A.26();D 1f}};m.1E=z(2F,1h,Z){k.1h=1h;k.2F=2F;k.Z=Z;q(!1h.8Z)1h.8Z={}};m.1E.5o={8a:z(){(m.1E.3k[k.Z]||m.1E.3k.96)(k);q(k.1h.3k)k.1h.3k.95(k.2F,k.4c,k)},3F:z(72,1L,47){k.80=(24 8X()).94();k.41=72;k.4v=1L;k.47=47;k.4c=k.41;k.E=k.7X=0;u 5J=k;z t(5N){D 5J.3k(5N)}t.2F=k.2F;q(t()&&m.3u.2p(t)==1){m.8W=cx(z(){u 3u=m.3u;K(u i=0;i<3u.S;i++)q(!3u[i]())3u.cw(i--,1);q(!3u.S){cv(m.8W)}},13)}},3k:z(5N){u t=(24 8X()).94();q(5N||t>=k.1h.3J+k.80){k.4c=k.4v;k.E=k.7X=1;k.8a();k.1h.5S[k.Z]=J;u 8d=J;K(u i 2T k.1h.5S)q(k.1h.5S[i]!==J)8d=1f;q(8d){q(k.1h.63)k.1h.63.95(k.2F)}D 1f}I{u n=t-k.80;k.7X=n/k.1h.3J;k.E=k.1h.2r(n,0,1,k.1h.3J);k.4c=k.41+((k.4v-k.41)*k.E);k.8a()}D J}};m.3b(m.1E,{3k:{1n:z(1E){m.V(1E.2F,{1n:1E.4c})},96:z(1E){2d{q(1E.2F.G&&1E.2F.G[1E.Z]!=H)1E.2F.G[1E.Z]=1E.4c+1E.47;I 1E.2F[1E.Z]=1E.4c}1W(e){}}}});m.4O=z(1B,3V){k.3V=3V;k.1B=1B;u v=m.21,3L;k.7h=m.2m&&m.21<7;q(!1B){q(3V)3V();D}m.71();k.1V=m.1c(\'1V\',{cr:0},{1e:\'1s\',1j:\'2v\',cC:\'cD\',M:0},m.22,J);u 4a=m.1c(\'4a\',H,H,k.1V,1);k.2e=[];K(u i=0;i<=8;i++){q(i%3==0)3L=m.1c(\'3L\',H,{1b:\'2n\'},4a,J);k.2e[i]=m.1c(\'2e\',H,H,3L,J);u G=i!=4?{cP:0,cO:0}:{1j:\'8i\'};m.V(k.2e[i],G)}k.2e[4].U=1B+\' L-16\';k.98()};m.4O.5o={98:z(){u 1G=m.4p+(m.cN||"cQ/")+k.1B+".97";u 9a=m.4u&&m.21<6t?m.22:H;k.3d=m.1c(\'1y\',H,{1j:\'2v\',11:\'-4P\'},9a,J);u 7T=k;k.3d.64=z(){7T.9b()};k.3d.1G=1G},9b:z(){u o=k.1k=k.3d.M/4,E=[[0,0],[0,-4],[-2,0],[0,-8],0,[-2,-8],[0,-2],[0,-6],[-2,-2]],1m={1b:(2*o)+\'F\',M:(2*o)+\'F\'};K(u i=0;i<=8;i++){q(E[i]){q(k.7h){u w=(i==1||i==7)?\'28%\':k.3d.M+\'F\';u X=m.1c(\'X\',H,{M:\'28%\',1b:\'28%\',1j:\'8i\',3a:\'1s\'},k.2e[i],J);m.1c(\'X\',H,{5j:"cL:cG.cF.cE(cH=cI, 1G=\'"+k.3d.1G+"\')",1j:\'2v\',M:w,1b:k.3d.1b+\'F\',14:(E[i][0]*o)+\'F\',11:(E[i][1]*o)+\'F\'},X,J)}I{m.V(k.2e[i],{9e:\'5O(\'+k.3d.1G+\') \'+(E[i][0]*o)+\'F \'+(E[i][1]*o)+\'F\'})}q(1A.3q&&(i==3||i==5))m.1c(\'X\',H,1m,k.2e[i],J);m.V(k.2e[i],1m)}}k.3d=H;q(m.48[k.1B])m.48[k.1B].5x();m.48[k.1B]=k;q(k.3V)k.3V()},3Z:z(E,1k,9d,3t,2r){u A=k.A,cK=A.Q.G,1k=1k||0,E=E||{x:A.x.E+1k,y:A.y.E+1k,w:A.x.N(\'1N\')-2*1k,h:A.y.N(\'1N\')-2*1k};q(9d)k.1V.G.1e=(E.h>=4*k.1k)?\'1D\':\'1s\';m.V(k.1V,{14:(E.x-k.1k)+\'F\',11:(E.y-k.1k)+\'F\',M:(E.w+2*k.1k)+\'F\'});E.w-=2*k.1k;E.h-=2*k.1k;m.V(k.2e[4],{M:E.w>=0?E.w+\'F\':0,1b:E.h>=0?E.h+\'F\':0});q(k.7h)k.2e[3].G.1b=k.2e[5].G.1b=k.2e[4].G.1b},5x:z(9c){q(9c)k.1V.G.1e=\'1s\';I m.3H(k.1V)}};m.6r=z(A,1m){k.A=A;k.1m=1m;k.3m=1m==\'x\'?\'ah\':\'au\';k.3G=k.3m.5Y();k.4M=1m==\'x\'?\'af\':\'ag\';k.6B=k.4M.5Y();k.7d=1m==\'x\'?\'a5\':\'a8\';k.90=k.7d.5Y();k.1o=k.2z=0};m.6r.5o={N:z(P){8Y(P){1I\'78\':D k.1K+k.3o+(k.t-m.1S[\'1k\'+k.3m])/2;1I\'6Q\':D k.E+k.cb+k.1o+(k.B-m.1S[\'1k\'+k.3m])/2;1I\'1N\':D k.B+2*k.cb+k.1o+k.2z;1I\'4n\':D k.3W-k.2P-k.3X;1I\'7a\':D k.N(\'4n\')-2*k.cb-k.1o-k.2z;1I\'5t\':D k.E-(k.A.16?k.A.16.1k:0);1I\'7M\':D k.N(\'1N\')+(k.A.16?2*k.A.16.1k:0);1I\'2f\':D k.1z?1d.2y((k.B-k.1z)/2):0}},74:z(){k.cb=(k.A.17[\'1k\'+k.3m]-k.t)/2;k.3X=m[\'6S\'+k.7d]},6X:z(){k.t=k.A.C[k.3G]?7L(k.A.C[k.3G]):k.A.C[\'1k\'+k.3m];k.1K=k.A.1K[k.1m];k.3o=(k.A.C[\'1k\'+k.3m]-k.t)/2;q(k.1K==0||k.1K==-1){k.1K=(m.3S[k.3G]/2)+m.3S[\'1J\'+k.4M]}},6P:z(){u A=k.A;k.2k=\'2n\';q(A.6H==\'4i\')k.2k=\'4i\';I q(24 5X(k.6B).19(A.3Q))k.2k=H;I q(24 5X(k.90).19(A.3Q))k.2k=\'56\';k.E=k.1K-k.cb+k.3o;q(k.6R&&k.1m==\'x\')A.6F=1d.2X(A.6F||k.1a,A.6R*k.1a/A.y.1a);k.B=1d.2X(k.1a,A[\'56\'+k.3m]||k.1a);k.2q=A.5q?1d.2X(A[\'2X\'+k.3m],k.1a):k.1a;q(A.3A&&A.30){k.B=A[k.3G];k.1z=k.1a}q(k.1m==\'x\'&&m.4R)k.2q=A.5c;k.2i=A[\'2i\'+k.1m.92()];k.2P=m[\'6S\'+k.4M];k.1J=m.3S[\'1J\'+k.4M];k.3W=m.3S[k.3G]},82:z(i){u A=k.A;q(A.3A&&(A.30||m.4R)){k.1z=i;k.B=1d.56(k.B,k.1z);A.17.G[k.6B]=k.N(\'2f\')+\'F\'}I k.B=i;A.17.G[k.3G]=i+\'F\';A.Q.G[k.3G]=k.N(\'1N\')+\'F\';q(A.16)A.16.3Z();q(k.1m==\'x\'&&A.1l)A.4K(J);q(k.1m==\'x\'&&A.1g&&A.3A){q(i==k.1a)A.1g.4J(\'1a-2D\');I A.1g.3T(\'1a-2D\')}},7Z:z(i){k.E=i;k.A.Q.G[k.6B]=i+\'F\';q(k.A.16)k.A.16.3Z()}};m.4Z=z(a,2O,3F,2Q){q(R.cs&&m.2m&&!m.6I){m.1Q(R,\'3s\',z(){24 m.4Z(a,2O,3F,2Q)});D}k.a=a;k.3F=3F;k.2Q=2Q||\'2M\';k.3A=!k.cp;m.6Z=1f;k.1x=[];k.Y=m.Y;m.Y=H;m.71();u P=k.P=m.W.S;K(u i=0;i<m.6V.S;i++){u 35=m.6V[i];k[35]=2O&&1q 2O[35]!=\'1C\'?2O[35]:m[35]}q(!k.1G)k.1G=a.1Y;u C=(2O&&2O.7y)?m.$(2O.7y):a;C=k.9p=C.2L(\'1y\')[0]||C;k.6x=C.1M||a.1M;K(u i=0;i<m.W.S;i++){q(m.W[i]&&m.W[i].a==a&&!(k.Y&&k.2Z[1]==\'3Y\')){m.W[i].43();D 1f}}q(!m.cm)K(u i=0;i<m.W.S;i++){q(m.W[i]&&m.W[i].9p!=C&&!m.W[i].6G){m.W[i].5K()}}m.W[P]=k;q(!m.9j&&!m.1U){q(m.W[P-1])m.W[P-1].26();q(1q m.3v!=\'1C\'&&m.W[m.3v])m.W[m.3v].26()}k.C=C;k.1K=k.9i||m.6g(C);m.6v();u x=k.x=24 m.6r(k,\'x\');x.6X();u y=k.y=24 m.6r(k,\'y\');y.6X();k.Q=m.1c(\'X\',{1M:\'L-Q-\'+k.P,U:\'L-Q \'+k.7B},{1e:\'1s\',1j:\'2v\',1r:m.4z+=2},H,J);k.Q.cu=k.Q.cB=m.8Q;q(k.2Q==\'2M\'&&k.3B==2)k.3B=0;q(!k.1B||(k.Y&&k.3A&&k.2Z[1]==\'3Y\')){k[k.2Q+\'6J\']()}I q(m.48[k.1B]){k.6L();k[k.2Q+\'6J\']()}I{k.6U();u A=k;24 m.4O(k.1B,z(){A.6L();A[A.2Q+\'6J\']()})}D J};m.4Z.5o={7D:z(e){q(m.dm)dk(\'do \'+e.d0+\': \'+e.d1);I 1A.cZ.1Y=k.1G},6L:z(){u 16=k.16=m.48[k.1B];16.A=k;16.1V.G.1r=k.Q.G.1r-1;m.48[k.1B]=H},6U:z(){q(k.6G||k.1S)D;k.1S=m.1S;u A=k;k.1S.2G=z(){A.5K()};u A=k,l=k.x.N(\'78\')+\'F\',t=k.y.N(\'78\')+\'F\';q(!2l&&k.Y&&k.2Z[1]==\'3Y\')u 2l=k.Y;q(2l){l=2l.x.N(\'6Q\')+\'F\';t=2l.y.N(\'6Q\')+\'F\';k.1S.G.1r=m.4z++}4r(z(){q(A.1S)m.V(A.1S,{14:l,11:t,1r:m.4z++})},28)},da:z(){u A=k;u 1y=R.1c(\'1y\');k.17=1y;1y.64=z(){q(m.W[A.P])A.8K()};q(m.cY)1y.dj=z(){D 1f};1y.U=\'L-2M\';m.V(1y,{1e:\'1s\',1u:\'4H\',1j:\'2v\',6F:\'4P\',1r:3});1y.1X=m.18.84;q(m.4u&&m.21<6t)m.22.2E(1y);q(m.2m&&m.dc)1y.1G=H;1y.1G=k.1G;k.6U()},8K:z(){2d{q(!k.17)D;k.17.64=H;q(k.6G)D;I k.6G=J;u x=k.x,y=k.y;q(k.1S){m.V(k.1S,{11:\'-4P\'});k.1S=H}x.1a=k.17.M;y.1a=k.17.1b;m.V(k.17,{M:x.t+\'F\',1b:y.t+\'F\'});k.Q.2E(k.17);m.22.2E(k.Q);x.74();y.74();m.V(k.Q,{14:(x.1K+x.3o-x.cb)+\'F\',11:(y.1K+x.3o-y.cb)+\'F\'});k.aB();k.9J();u 2x=x.1a/y.1a;x.6P();k.2k(x);y.6P();k.2k(y);q(k.1l)k.4K(0,1);q(k.5q){k.aZ(2x);u 1v=k.1g;q(1v&&k.Y&&1v.2B&&1v.ar){u E=1v.aC.1j||\'\',p;K(u 1m 2T m.7q)K(u i=0;i<5;i++){p=k[1m];q(E.2H(m.7q[1m][i])){p.E=k.Y[1m].E+(k.Y[1m].1o-p.1o)+(k.Y[1m].B-p.B)*[0,0,.5,1,1][i];q(1v.ar==\'dg\'){q(p.E+p.B+p.1o+p.2z>p.1J+p.3W-p.3X)p.E=p.1J+p.3W-p.B-p.2P-p.3X-p.1o-p.2z;q(p.E<p.1J+p.2P)p.E=p.1J+p.2P}}}}q(k.3A&&k.x.1a>(k.x.1z||k.x.B)){k.ap();q(k.1x.S==1)k.4K()}}k.aG()}1W(e){k.7D(e)}},2k:z(p,4C){u 4b,2l=p.2i,1m=p==k.x?\'x\':\'y\';q(2l&&2l.2H(/ /)){4b=2l.dh(\' \');2l=4b[0]}q(2l&&m.$(2l)){p.E=m.6g(m.$(2l))[1m];q(4b&&4b[1]&&4b[1].2H(/^[-]?[0-9]+F$/))p.E+=7L(4b[1]);q(p.B<p.2q)p.B=p.2q}I q(p.2k==\'2n\'||p.2k==\'4i\'){u 79=1f;u 4q=p.A.5q;q(p.2k==\'4i\')p.E=1d.2y(p.1J+(p.3W+p.2P-p.3X-p.N(\'1N\'))/2);I p.E=1d.2y(p.E-((p.N(\'1N\')-p.t)/2));q(p.E<p.1J+p.2P){p.E=p.1J+p.2P;79=J}q(!4C&&p.B<p.2q){p.B=p.2q;4q=1f}q(p.E+p.N(\'1N\')>p.1J+p.3W-p.3X){q(!4C&&79&&4q){p.B=1d.2X(p.B,p.N(1m==\'y\'?\'4n\':\'7a\'))}I q(p.N(\'1N\')<p.N(\'4n\')){p.E=p.1J+p.3W-p.3X-p.N(\'1N\')}I{p.E=p.1J+p.2P;q(!4C&&4q)p.B=p.N(1m==\'y\'?\'4n\':\'7a\')}}q(!4C&&p.B<p.2q){p.B=p.2q;4q=1f}}I q(p.2k==\'56\'){p.E=1d.df(p.E-p.B+p.t)}q(p.E<p.2P){u aU=p.E;p.E=p.2P;q(4q&&!4C)p.B=p.B-(p.E-aU)}},aZ:z(2x){u x=k.x,y=k.y,3e=1f,2A=1d.2X(x.1a,x.B),2Y=1d.2X(y.1a,y.B),30=(k.30||m.4R);q(2A/2Y>2x){ 2A=2Y*2x;q(2A<x.2q){2A=x.2q;2Y=2A/2x}3e=J}I q(2A/2Y<2x){ 2Y=2A/2x;3e=J}q(m.4R&&x.1a<x.2q){x.1z=x.1a;y.B=y.1z=y.1a}I q(k.30){x.1z=2A;y.1z=2Y}I{x.B=2A;y.B=2Y}3e=k.aY(k.30?H:2x,3e);q(30&&y.B<y.1z){y.1z=y.B;x.1z=y.B*2x}q(3e||30){x.E=x.1K-x.cb+x.3o;x.2q=x.B;k.2k(x,J);y.E=y.1K-y.cb+y.3o;y.2q=y.B;k.2k(y,J);q(k.1l)k.4K()}},aY:z(2x,3e){u x=k.x,y=k.y;q(k.1l){4o(y.B>k.5w&&x.B>k.5c&&y.N(\'1N\')>y.N(\'4n\')){y.B-=10;q(2x)x.B=y.B*2x;k.4K(0,1);3e=J}}D 3e},aG:z(){u x=k.x,y=k.y;k.5s(\'1s\');q(k.1g&&k.1g.2g)k.1g.2g.4G();k.8f(1,{Q:{M:x.N(\'1N\'),1b:y.N(\'1N\'),14:x.E,11:y.E},17:{14:x.1o+x.N(\'2f\'),11:y.1o+y.N(\'2f\'),M:x.1z||x.B,1b:y.1z||y.B}},m.7f)},8f:z(1t,1L,3t){u 5k=k.2Z,6M=1t?(k.Y?k.Y.a:H):m.1U,t=(5k[1]&&6M&&m.5h(6M,\'2Z\')[1]==5k[1])?5k[1]:5k[0];q(k[t]&&t!=\'2D\'){k[t](1t,1L);D}q(k.16&&!k.3B){q(1t)k.16.3Z();I k.16.5x()}q(!1t)k.67();u A=k,x=A.x,y=A.y,2r=k.2r;q(!1t)2r=k.aT||2r;u ay=1t?z(){q(A.16)A.16.1V.G.1e="1D";4r(z(){A.62()},50)}:z(){A.5v()};q(1t)m.V(k.Q,{M:x.t+\'F\',1b:y.t+\'F\'});q(k.aD){m.V(k.Q,{1n:1t?0:1});m.3b(1L.Q,{1n:1t})}m.2b(k.Q,1L.Q,{3J:3t,2r:2r,3k:z(3j,36){q(A.16&&A.3B&&36.Z==\'11\'){u 4Q=1t?36.E:1-36.E;u E={w:x.t+(x.N(\'1N\')-x.t)*4Q,h:y.t+(y.N(\'1N\')-y.t)*4Q,x:x.1K+(x.E-x.1K)*4Q,y:y.1K+(y.E-y.1K)*4Q};A.16.3Z(E,0,1)}}});m.2b(k.17,1L.17,3t,2r,ay);q(1t){k.Q.G.1e=\'1D\';k.17.G.1e=\'1D\';k.a.U+=\' L-42-3Q\'}},5n:z(1t,1L){k.3B=1f;u A=k,t=1t?m.7f:0;q(1t){m.2b(k.Q,1L.Q,0);m.V(k.Q,{1n:0,1e:\'1D\'});m.2b(k.17,1L.17,0);k.17.G.1e=\'1D\';m.2b(k.Q,{1n:1},t,H,z(){A.62()})}q(k.16){k.16.1V.G.1r=k.Q.G.1r;u 5D=1t||-1,1k=k.16.1k,7c=1t?3:1k,6Y=1t?1k:3;K(u i=7c;5D*i<=5D*6Y;i+=5D,t+=25){(z(){u o=1t?6Y-i:7c-i;4r(z(){A.16.3Z(0,o,1)},t)})()}}q(1t){}I{4r(z(){q(A.16)A.16.5x(A.cz);A.67();m.2b(A.Q,{1n:0},m.8p,H,z(){A.5v()})},t)}},3Y:z(1t,1L,72){q(!1t)D;u A=k,Y=k.Y,x=k.x,y=k.y,2W=Y.x,2U=Y.y,Q=k.Q,17=k.17,1l=k.1l;m.49(R,\'6o\',m.5V);m.V(17,{M:(x.1z||x.B)+\'F\',1b:(y.1z||y.B)+\'F\'});q(1l)1l.G.3a=\'1D\';k.16=Y.16;q(k.16)k.16.A=A;Y.16=H;u 4s=m.1c(\'X\',{U:\'L-\'+k.2Q},{1j:\'2v\',1r:4,3a:\'1s\',1u:\'1F\'});u 77={aO:Y,aR:k};K(u n 2T 77){k[n]=77[n].17.7j(1);m.V(k[n],{1j:\'2v\',aM:0,1e:\'1D\'});4s.2E(k[n])}Q.2E(4s);q(1l){1l.U=\'\';Q.2E(1l)}4s.G.1u=\'\';Y.17.G.1u=\'1F\';q(m.4u&&m.21<6t){k.Q.G.1e=\'1D\'}m.2b(Q,{M:x.B},{3J:m.aL,3k:z(3j,36){u E=36.E,3U=1-E;u Z,B={},6N=[\'E\',\'B\',\'1o\',\'2z\'];K(u n 2T 6N){Z=6N[n];B[\'x\'+Z]=1d.2y(3U*2W[Z]+E*x[Z]);B[\'y\'+Z]=1d.2y(3U*2U[Z]+E*y[Z]);B.aJ=1d.2y(3U*(2W.1z||2W.B)+E*(x.1z||x.B));B.6p=1d.2y(3U*2W.N(\'2f\')+E*x.N(\'2f\'));B.aN=1d.2y(3U*(2U.1z||2U.B)+E*(y.1z||y.B));B.6f=1d.2y(3U*2U.N(\'2f\')+E*y.N(\'2f\'))}q(A.16)A.16.3Z({x:B.2K,y:B.2J,w:B.58+B.3C+B.6O+2*x.cb,h:B.5a+B.3z+B.6W+2*y.cb});Y.Q.G.ct=\'cn(\'+(B.2J-2U.E)+\'F, \'+(B.58+B.3C+B.6O+B.2K+2*2W.cb-2W.E)+\'F, \'+(B.5a+B.3z+B.6W+B.2J+2*2U.cb-2U.E)+\'F, \'+(B.2K-2W.E)+\'F)\';m.V(17,{11:(B.3z+y.N(\'2f\'))+\'F\',14:(B.3C+x.N(\'2f\'))+\'F\',4j:(y.E-B.2J)+\'F\',4L:(x.E-B.2K)+\'F\'});m.V(Q,{11:B.2J+\'F\',14:B.2K+\'F\',M:(B.3C+B.6O+B.58+2*x.cb)+\'F\',1b:(B.3z+B.6W+B.5a+2*y.cb)+\'F\'});m.V(4s,{M:(B.aJ||B.58)+\'F\',1b:(B.aN||B.5a)+\'F\',14:(B.3C+B.6p)+\'F\',11:(B.3z+B.6f)+\'F\',1e:\'1D\'});m.V(A.aO,{11:(2U.E-B.2J+2U.1o-B.3z+2U.N(\'2f\')-B.6f)+\'F\',14:(2W.E-B.2K+2W.1o-B.3C+2W.N(\'2f\')-B.6p)+\'F\'});m.V(A.aR,{1n:E,11:(y.E-B.2J+y.1o-B.3z+y.N(\'2f\')-B.6f)+\'F\',14:(x.E-B.2K+x.1o-B.3C+x.N(\'2f\')-B.6p)+\'F\'});q(1l)m.V(1l,{M:B.58+\'F\',1b:B.5a+\'F\',14:(B.3C+x.cb)+\'F\',11:(B.3z+y.cb)+\'F\'})},63:z(){Q.G.1e=17.G.1e=\'1D\';17.G.1u=\'4H\';m.3H(4s);A.62();Y.5v();A.Y=H}})},9E:z(o,C){q(!k.Y)D 1f;K(u i=0;i<k.Y.1x.S;i++){u 61=m.$(\'1H\'+k.Y.1x[i]);q(61&&61.1H==o.1H){k.7z();61.cl=k.P;m.2p(k.1x,k.Y.1x[i]);D J}}D 1f},62:z(){k.55=J;k.43();q(k.3I)m.1m(k);q(m.1U&&m.1U==k.a)m.1U=H;k.aQ();u p=m.3S,7i=m.66.x+p.5l,7e=m.66.y+p.5i;k.7m=k.x.E<7i&&7i<k.x.E+k.x.N(\'1N\')&&k.y.E<7e&&7e<k.y.E+k.y.N(\'1N\');q(k.1l)k.ak()},aQ:z(){u P=k.P;u 1B=k.1B;24 m.4O(1B,z(){2d{m.W[P].aP()}1W(e){}})},aP:z(){u 1p=k.7b(1);q(1p&&1p.2G.aI().2H(/m\\.2D/))u 1y=m.1c(\'1y\',{1G:m.73(1p)})},7b:z(1P){u 7g=k.6e(),as=m.3R.2N[k.2t||\'1F\'];q(as&&!as[7g+1P]&&k.1g&&k.1g.ab){q(1P==1)D as[0];I q(1P==-1)D as[as.S-1]}D(as&&as[7g+1P])||H},6e:z(){u 2o=m.60().2N[k.2t||\'1F\'];q(2o)K(u i=0;i<2o.S;i++){q(2o[i]==k.a)D i}D H},a3:z(){q(k[k.5b]){u 2o=m.3R.2N[k.2t||\'1F\'];q(2o){u s=m.18.3n.2j(\'%1\',k.6e()+1).2j(\'%2\',2o.S);k[k.5b].2R=\'<X 2s="L-3n">\'+s+\'</X>\'+k[k.5b].2R}}},aB:z(){q(!k.Y){K(u i=0;i<m.4U.S;i++){u 1v=m.4U[i],2C=1v.2t;q(1q 2C==\'1C\'||2C===H||2C===k.2t)k.1g=24 m.7S(k.P,1v)}}I{k.1g=k.Y.1g}u 1v=k.1g;q(!1v)D;u P=1v.3N=k.P;1v.aa();1v.4J(\'1a-2D\');q(1v.2B){k.4h(m.3b(1v.aC||{},{44:1v.2B,1H:\'2B\',1r:5}))}q(1v.2g)1v.2g.6s(k);q(!k.Y&&k.3D)1v.3r(J);q(1v.3D){1v.3D=4r(z(){m.1p(P)},(1v.cT||cS))}},5K:z(){m.3H(k.Q);m.W[k.P]=H;q(m.1U==k.a)m.1U=H;m.7Q(k.P);q(k.1S)m.1S.G.14=\'-4P\'},am:z(){q(k.4Y)D;k.4Y=m.1c(\'a\',{1Y:m.aF,2i:m.aE,U:\'L-4Y\',2R:m.18.aS,1X:m.18.b0});k.4h({44:k.4Y,1j:k.aW||\'11 14\',1H:\'4Y\'})},a2:z(76,aw){K(u i=0;i<76.S;i++){u T=76[i],s=H;q(!k[T+\'4t\']&&k.6x)k[T+\'4t\']=T+\'-K-\'+k.6x;q(k[T+\'4t\'])k[T]=m.4W(k[T+\'4t\']);q(!k[T]&&!k[T+\'6K\']&&k[T+\'aX\'])2d{s=cJ(k[T+\'aX\'])}1W(e){}q(!k[T]&&k[T+\'6K\']){s=k[T+\'6K\']}q(!k[T]&&!s){k[T]=m.4W(k.a[\'aV\'+T+\'4t\']);q(!k[T]){u 1p=k.a.b1;4o(1p&&!m.5L(1p)){q((24 5X(\'L-\'+T)).19(1p.U||H)){q(!1p.1M)k.a[\'aV\'+T+\'4t\']=1p.1M=\'1H\'+m.4V++;k[T]=m.4W(1p.1M);5B}1p=1p.b1}}}q(!k[T]&&!s&&k.5b==T)s=\'\\n\';q(!k[T]&&s)k[T]=m.1c(\'X\',{U:\'L-\'+T,2R:s});q(aw&&k[T]){u o={1j:(T==\'6z\')?\'4T\':\'6D\'};K(u x 2T k[T+\'9T\'])o[x]=k[T+\'9T\'][x];o.44=k[T];k.4h(o)}}},5s:z(1e){q(m.9U)k.5I(\'cM\',1e);q(m.9z)k.5I(\'cR\',1e);q(m.5Z)k.5I(\'*\',1e)},5I:z(4F,1e){u 1i=R.2L(4F);u Z=4F==\'*\'?\'3a\':\'1e\';K(u i=0;i<1i.S;i++){q(Z==\'1e\'||(R.6T.9P(1i[i],"").9Q(\'3a\')==\'2n\'||1i[i].a1(\'1s-by\')!=H)){u 2u=1i[i].a1(\'1s-by\');q(1e==\'1D\'&&2u){2u=2u.2j(\'[\'+k.P+\']\',\'\');1i[i].5A(\'1s-by\',2u);q(!2u)1i[i].G[Z]=1i[i].88}I q(1e==\'1s\'){u 3g=m.6g(1i[i]);3g.w=1i[i].2c;3g.h=1i[i].3f;q(!k.3I){u ax=(3g.x+3g.w<k.x.N(\'5t\')||3g.x>k.x.N(\'5t\')+k.x.N(\'7M\'));u 9Z=(3g.y+3g.h<k.y.N(\'5t\')||3g.y>k.y.N(\'5t\')+k.y.N(\'7M\'))}u 5H=m.86(1i[i]);q(!ax&&!9Z&&5H!=k.P){q(!2u){1i[i].5A(\'1s-by\',\'[\'+k.P+\']\');1i[i].88=1i[i].G[Z];1i[i].G[Z]=\'1s\'}I q(2u.9X(\'[\'+k.P+\']\')==-1){1i[i].5A(\'1s-by\',2u+\'[\'+k.P+\']\')}}I q((2u==\'[\'+k.P+\']\'||m.3v==5H)&&5H!=k.P){1i[i].5A(\'1s-by\',\'\');1i[i].G[Z]=1i[i].88||\'\'}I q(2u&&2u.9X(\'[\'+k.P+\']\')>-1){1i[i].5A(\'1s-by\',2u.2j(\'[\'+k.P+\']\',\'\'))}}}}},43:z(){k.Q.G.1r=m.4z+=2;K(u i=0;i<m.W.S;i++){q(m.W[i]&&i==m.3v){u 5g=m.W[i];5g.17.U+=\' L-\'+5g.2Q+\'-89\';5g.17.G.46=m.3E?\'9O\':\'5R\';5g.17.1X=m.18.9Y}}q(k.16)k.16.1V.G.1r=k.Q.G.1r-1;k.17.U=\'L-\'+k.2Q;k.17.1X=m.18.84;q(m.5m){m.4I=1A.3q?\'5R\':\'5O(\'+m.4p+m.5m+\'), 5R\';q(m.3E&&m.21<6)m.4I=\'9O\';k.17.G.46=m.4I}m.3v=k.P;m.1Q(R,1A.3q?\'5P\':\'5Q\',m.4N)},7C:z(x,y){k.x.7Z(x);k.y.7Z(y)},3O:z(e){u w,h,r=e.M/e.1b;w=1d.56(e.M+e.5T,1d.2X(k.5c,k.x.1a));q(k.3A&&1d.co(w-k.x.1a)<12)w=k.x.1a;h=w/r;q(h<1d.2X(k.5w,k.y.1a)){h=1d.2X(k.5w,k.y.1a);q(k.3A)w=h*r}k.7k(w,h)},7k:z(w,h){k.y.82(h);k.x.82(w);k.Q.G.1b=k.y.N(\'1N\')+\'F\'},26:z(){q(k.8c||!k.55)D;q(k.2Z[1]==\'3Y\'&&m.1U){m.2h(m.1U).5K();m.1U=H}k.8c=J;q(k.1g&&!m.1U)k.1g.2S();m.49(R,1A.3q?\'5P\':\'5Q\',m.4N);2d{k.17.G.46=\'cA\';k.8f(0,{Q:{M:k.x.t,1b:k.y.t,14:k.x.1K-k.x.cb+k.x.3o,11:k.y.1K-k.y.cb+k.y.3o},17:{14:0,11:0,M:k.x.t,1b:k.y.t}},m.8p)}1W(e){k.5v()}},4h:z(o){u C=o.44,4E=(o.9A==\'1Z\'&&!/6w$/.19(o.1j));q(1q C==\'8q\')C=m.4W(C);q(o.5W)C=m.1c(\'X\',{2R:o.5W});q(!C||1q C==\'8q\')D;C.G.1u=\'4H\';o.1H=o.1H||o.44;q(k.2Z[1]==\'3Y\'&&k.9E(o,C))D;k.7z();u M=o.M&&/^[0-9]+(F|%)$/.19(o.M)?o.M:\'2n\';q(/^(14|2V)6w$/.19(o.1j)&&!/^[0-9]+F$/.19(o.M))M=\'cy\';u O=m.1c(\'X\',{1M:\'1H\'+m.4V++,1H:o.1H},{1j:\'2v\',1e:\'1s\',M:M,9F:m.18.9C||\'\',1n:0},4E?m.1Z:k.1l,J);q(4E)O.5F=k.P;O.2E(C);m.3b(O,{1n:1,9B:0,9G:0,3t:(o.5n===0||o.5n===1f||(o.5n==2&&m.2m))?0:53});m.3b(O,o);q(k.al){k.5y(O);q(!O.69||k.7m)m.2b(O,{1n:O.1n},O.3t)}m.2p(k.1x,m.4V-1)},5y:z(O){u p=O.1j||\'8h 4i\',4E=(O.9A==\'1Z\'),5E=O.9B,5C=O.9G;q(4E){m.1Z.G.1u=\'4H\';O.5F=k.P;q(O.2c>O.1O.2c)O.G.M=\'28%\'}I q(O.1O!=k.1l)k.1l.2E(O);q(/14$/.19(p))O.G.14=5E+\'F\';q(/4i$/.19(p))m.V(O,{14:\'50%\',4L:(5E-1d.2y(O.2c/2))+\'F\'});q(/2V$/.19(p))O.G.2V=-5E+\'F\';q(/^9H$/.19(p)){m.V(O,{2V:\'28%\',9M:k.x.cb+\'F\',11:-k.y.cb+\'F\',4g:-k.y.cb+\'F\',3a:\'2n\'});k.x.1o=O.2c}I q(/^9L$/.19(p)){m.V(O,{14:\'28%\',4L:k.x.cb+\'F\',11:-k.y.cb+\'F\',4g:-k.y.cb+\'F\',3a:\'2n\'});k.x.2z=O.2c}u 8g=O.1O.3f;O.G.1b=\'2n\';q(4E&&O.3f>8g)O.G.1b=m.3E?8g+\'F\':\'28%\';q(/^11/.19(p))O.G.11=5C+\'F\';q(/^8h/.19(p))m.V(O,{11:\'50%\',4j:(5C-1d.2y(O.3f/2))+\'F\'});q(/^4g/.19(p))O.G.4g=-5C+\'F\';q(/^4T$/.19(p)){m.V(O,{14:(-k.x.1o-k.x.cb)+\'F\',2V:(-k.x.2z-k.x.cb)+\'F\',4g:\'28%\',9K:k.y.cb+\'F\',M:\'2n\'});k.y.1o=O.3f}I q(/^6D$/.19(p)){m.V(O,{1j:\'8i\',14:(-k.x.1o-k.x.cb)+\'F\',2V:(-k.x.2z-k.x.cb)+\'F\',11:\'28%\',4j:k.y.cb+\'F\',M:\'2n\'});k.y.2z=O.3f;O.G.1j=\'2v\'}},9J:z(){k.a2([\'6z\',\'dd\'],J);k.a3();q(k.6z&&k.7v)k.6z.U+=\' L-3i\';q(m.an)k.am();K(u i=0;i<m.1x.S;i++){u o=m.1x[i],6y=o.7y,2C=o.2t;q((!6y&&!2C)||(6y&&6y==k.6x)||(2C&&2C===k.2t)){k.4h(o)}}u 6u=[];K(u i=0;i<k.1x.S;i++){u o=m.$(\'1H\'+k.1x[i]);q(/6w$/.19(o.1j))k.5y(o);I m.2p(6u,o)}K(u i=0;i<6u.S;i++)k.5y(6u[i]);k.al=J},7z:z(){q(!k.1l)k.1l=m.1c(\'X\',{U:k.7B},{1j:\'2v\',M:(k.x.B||(k.30?k.M:H)||k.x.1a)+\'F\',1b:(k.y.B||k.y.1a)+\'F\',1e:\'1s\',3a:\'1s\',1r:m.2m?4:\'2n\'},m.22,J)},4K:z(7t,aj){u 1l=k.1l,x=k.x,y=k.y;m.V(1l,{M:x.B+\'F\',1b:y.B+\'F\'});q(7t||aj){K(u i=0;i<k.1x.S;i++){u o=m.$(\'1H\'+k.1x[i]);u 7u=(m.3E||R.6i==\'7P\');q(o&&/^(4T|6D)$/.19(o.1j)){q(7u){o.G.M=(1l.2c+2*x.cb+x.1o+x.2z)+\'F\'}y[o.1j==\'4T\'?\'1o\':\'2z\']=o.3f}q(o&&7u&&/^(14|2V)6w$/.19(o.1j)){o.G.1b=(1l.3f+2*y.cb)+\'F\'}}}q(7t){m.V(k.17,{11:y.1o+\'F\'});m.V(1l,{11:(y.1o+y.cb)+\'F\'})}},ak:z(){u b=k.1l;b.U=\'\';m.V(b,{11:(k.y.1o+k.y.cb)+\'F\',14:(k.x.1o+k.x.cb)+\'F\',3a:\'1D\'});q(m.4u)b.G.1e=\'1D\';k.Q.2E(b);K(u i=0;i<k.1x.S;i++){u o=m.$(\'1H\'+k.1x[i]);o.G.1r=o.1r||4;q(!o.69||k.7m){o.G.1e=\'1D\';m.V(o,{1e:\'1D\',1u:\'\'});m.2b(o,{1n:o.1n},o.3t)}}},67:z(){q(!k.1x.S)D;q(k.1g){u c=k.1g.2B;q(c&&m.2h(c)==k)c.1O.dl(c)}K(u i=0;i<k.1x.S;i++){u o=m.$(\'1H\'+k.1x[i]);q(o&&o.1O==m.1Z&&m.2h(o)==k)m.3H(o)}m.3H(k.1l)},ap:z(){q(k.1g&&k.1g.2B){k.1g.3T(\'1a-2D\');D}k.6a=m.1c(\'a\',{1Y:\'av:m.W[\'+k.P+\'].6k();\',1X:m.18.7p,U:\'L-1a-2D\'});k.4h({44:k.6a,1j:m.at,69:J,1n:m.aq})},6k:z(){2d{q(k.6a)m.3H(k.6a);k.43();u 2A=k.x.B,2Y=k.y.B;k.7k(k.x.1a,k.y.1a);u 2K=k.x.E-(k.x.B-2A)/2;q(2K<m.4L)2K=m.4L;u 2J=k.y.E-(k.y.B-2Y)/2;q(2J<m.4j)2J=m.4j;k.7C(2K,2J);k.5s(\'1s\')}1W(e){k.7D(e)}},5v:z(){k.a.U=k.a.U.2j(\'L-42-3Q\',\'\');k.5s(\'1D\');q(k.16&&k.3B)k.16.5x();m.3H(k.Q);k.67();q(!m.1Z.6l.S)m.1Z.G.1u=\'1F\';q(k.3I)m.7Q(k.P);m.W[k.P]=H;m.ai()}};m.7S=z(3N,1h){q(m.d2!==1f)m.7O();k.3N=3N;K(u x 2T 1h)k[x]=1h[x];q(k.d3)k.a9();q(k.2g)k.2g=m.ae(k)};m.7S.5o={a9:z(){k.2B=m.1c(\'X\',{2R:m.a7(m.a6.2B)},H,m.22);u 59=[\'3r\',\'2S\',\'3c\',\'1p\',\'3i\',\'1a-2D\',\'26\'];k.1w={};u 7T=k;K(u i=0;i<59.S;i++){k.1w[59[i]]=m.a4(k.2B,\'1R\',\'L-\'+59[i]);k.3T(59[i])}k.1w.2S.G.1u=\'1F\'},aa:z(){q(k.ab||!k.2B)D;u A=m.W[k.3N],4y=A.6e(),1T=/6m$/;q(4y==0)k.4J(\'3c\');I q(1T.19(k.1w.3c.2L(\'a\')[0].U))k.3T(\'3c\');q(4y+1==m.3R.2N[A.2t||\'1F\'].S){k.4J(\'1p\');k.4J(\'3r\')}I q(1T.19(k.1w.1p.2L(\'a\')[0].U)){k.3T(\'1p\');k.3T(\'3r\')}},3T:z(1w){q(!k.1w)D;u a0=k,a=k.1w[1w].2L(\'a\')[0],1T=/6m$/;a.2G=z(){a0[1w]();D 1f};q(1T.19(a.U))a.U=a.U.2j(1T,\'\')},4J:z(1w){q(!k.1w)D;u a=k.1w[1w].2L(\'a\')[0];a.2G=z(){D 1f};q(!/6m$/.19(a.U))a.U+=\' 6m\'},ad:z(){q(k.3D)k.2S();I k.3r()},3r:z(ac){q(k.1w){k.1w.3r.G.1u=\'1F\';k.1w.2S.G.1u=\'\'}k.3D=J;q(!ac)m.1p(k.3N)},2S:z(){q(k.1w){k.1w.2S.G.1u=\'1F\';k.1w.3r.G.1u=\'\'}b8(k.3D);k.3D=H},3c:z(){k.2S();m.3c(k.1w.3c)},1p:z(){k.2S();m.1p(k.1w.1p)},3i:z(){},\'1a-2D\':z(){m.2h().6k()},26:z(){m.26(k.1w.26)}};m.ae=z(1g){z 6s(A){m.3b(1h||{},{44:4e,1H:\'2g\',U:\'L-2g-\'+4m+\'-O \'+(1h.U||\'\')});q(m.3E)1h.5n=0;A.4h(1h);m.V(4e.1O,{3a:\'1s\'})};z 1J(3h){4G(1C,1d.2y(3h*4e[3p?\'2c\':\'3f\']*0.7))};z 4G(i,7K){q(i===1C)K(u j=0;j<51.S;j++){q(51[j]==m.W[1g.3N].a){i=j;5B}}q(i===1C)D;u as=4e.2L(\'a\'),42=as[i],3M=42.1O,14=3p?\'af\':\'ag\',2V=3p?\'a5\':\'a8\',M=3p?\'ah\':\'au\',4f=\'1k\'+14,2c=\'1k\'+M,6h=X.1O.1O[2c],4w=6h-1V[2c],5z=7L(1V.G[3p?\'14\':\'11\'])||0,2w=5z,bs=20;q(7K!==1C){2w=5z-7K;q(4w>0)4w=0;q(2w>0)2w=0;q(2w<4w)2w=4w}I{K(u j=0;j<as.S;j++)as[j].U=\'\';42.U=\'L-42-3Q\';u 7F=i>0?as[i-1].1O[4f]:3M[4f],7x=3M[4f]+3M[2c]+(as[i+1]?as[i+1].1O[2c]:0);q(7x>6h-5z)2w=6h-7x;I q(7F<-5z)2w=-7F}u 7r=3M[4f]+(3M[2c]-6b[2c])/2+2w;m.2b(1V,3p?{14:2w}:{11:2w},H,\'7n\');m.2b(6b,3p?{14:7r}:{11:7r},H,\'7n\');7Y.G.1u=2w<0?\'4H\':\'1F\';85.G.1u=(2w>4w)?\'4H\':\'1F\'};u 51=m.3R.2N[m.W[1g.3N].2t||\'1F\'],1h=1g.2g,4m=1h.4m||\'ao\',81=(4m==\'bi\'),3K=81?[\'X\',\'7V\',\'1R\',\'23\']:[\'1V\',\'4a\',\'3L\',\'2e\'],3p=(4m==\'ao\'),4e=m.1c(\'X\',{U:\'L-2g L-2g-\'+4m,2R:\'<X 2s="L-2g-b4">\'+\'<\'+3K[0]+\'><\'+3K[1]+\'></\'+3K[1]+\'></\'+3K[0]+\'></X>\'+\'<X 2s="L-1J-1t"><X></X></X>\'+\'<X 2s="L-1J-b6"><X></X></X>\'+\'<X 2s="L-6b"><X></X></X>\'},{1u:\'1F\'},m.22),57=4e.6l,X=57[0],7Y=57[1],85=57[2],6b=57[3],1V=X.b7,4a=4e.2L(3K[1])[0],3L;K(u i=0;i<51.S;i++){q(i==0||!3p)3L=m.1c(3K[2],H,H,4a);(z(){u a=51[i],3M=m.1c(3K[3],H,H,3L),cj=i;m.1c(\'a\',{1Y:a.1Y,1X:a.1X,2G:z(){q(/L-42-3Q/.19(k.U))D 1f;m.2h(k).43();D m.83(a)},2R:m.9I?m.9I(a):a.2R},H,3M)})()}q(!81){7Y.2G=z(){1J(-1)};85.2G=z(){1J(1)};m.1Q(4a,R.c3!==1C?\'bB\':\'bZ\',z(e){u 3h=0;e=e||1A.29;q(e.9D){3h=e.9D/ch;q(m.3q)3h=-3h}I q(e.9N){3h=-e.9N/3}q(3h)1J(-3h*0.2);q(e.4D)e.4D();e.9W=1f})}D{6s:6s,4G:4G}};m.5U=m.18;u bC=m.4Z;q(m.2m&&1A==1A.11){(z(){2d{R.4l.bD(\'14\')}1W(e){4r(9V.bF,50);D}m.3s()})()}m.1Q(R,\'bL\',m.3s);m.1Q(1A,\'az\',m.3s);m.1Q(R,\'3s\',z(){q(m.5M||m.3I){u G=m.1c(\'G\',{T:\'bM/7U\'},H,R.2L(\'bT\')[0]),8k=R.6i==\'7P\';z 5e(7w,7W){q(m.2m&&(m.21<9||8k)){u Y=R.9S[R.9S.S-1];q(1q(Y.5e)=="6q")Y.5e(7w,7W)}I{G.2E(R.bU(7w+" {"+7W+"}"))}}z 5f(Z){D\'bV( ( ( bN = R.4l.\'+Z+\' ? R.4l.\'+Z+\' : R.3x.\'+Z+\' ) ) + \\\'F\\\' );\'}q(m.5M)5e(\'.L 1y\',\'46: 5O(\'+m.4p+m.5M+\'), 5R !c8;\');5e(\'.L-1Z-B\',m.2m&&(m.21<7||8k)?\'1j: 2v; \'+\'14:\'+5f(\'5l\')+\'11:\'+5f(\'5i\')+\'M:\'+5f(\'8m\')+\'1b:\'+5f(\'aK\'):\'1j: bc; M: 28%; 1b: 28%; 14: 0; 11: 0\')}});m.1Q(1A,\'3O\',z(){m.6v();q(m.1Z)K(u i=0;i<m.1Z.6l.S;i++){u 3w=m.1Z.6l[i],A=m.2h(3w);A.5y(3w);q(3w.1H==\'2g\')A.1g.2g.4G()}});m.1Q(R,\'6o\',z(e){m.66={x:e.6c,y:e.68}});m.1Q(R,\'aH\',m.87);m.1Q(R,\'aA\',m.87);m.1Q(R,\'3s\',m.60);m.1Q(1A,\'az\',m.9R)}',62,831,'||||||||||||||||||||this||hs||||if||||var|||||function|exp|size|el|return|pos|px|style|null|else|true|for|highslide|width|get|overlay|key|wrapper|document|length|type|className|setStyles|expanders|div|last|prop||top|||left||outline|content|lang|test|full|height|createElement|Math|visibility|false|slideshow|options|els|position|offset|overlayBox|dim|opacity|p1|next|typeof|zIndex|hidden|up|display|ss|btn|overlays|img|imgSize|window|outlineType|undefined|visible|fx|none|src|hsId|case|scroll|tpos|to|id|wsize|parentNode|op|addEventListener|li|loading|re|upcoming|table|catch|title|href|viewport||uaVersion|container|span|new||close||100|event|dimmer|animate|offsetWidth|try|td|imgPad|thumbstrip|getExpander|target|replace|justify|tgt|ie|auto|arr|push|minSize|easing|class|slideshowGroup|hiddenBy|absolute|tblPos|ratio|round|p2|xSize|controls|sg|expand|appendChild|elem|onclick|match|dragArgs|ypos|xpos|getElementsByTagName|image|groups|params|marginMin|contentType|innerHTML|pause|in|lastY|right|lastX|min|ySize|transitions|useBox|opt||||name|args||||overflow|extend|previous|graphic|changed|offsetHeight|elPos|delta|move|val|step|func|ucwh|number|tb|isX|opera|play|ready|dur|timers|focusKey|node|body|hasDragged|yp1|isImage|outlineWhileAnimating|xp1|autoplay|ieLt7|custom|wh|discardElement|dimmingOpacity|duration|tree|tr|cell|expKey|resize|styles|anchor|anchors|page|enable|invPos|onLoad|clientSize|marginMax|crossfade|setPosition||start|active|focus|overlayId|clone|cursor|unit|pendingOutlines|removeEventListener|tbody|tgtArr|now|ieLt9|dom|offsetLeft|bottom|createOverlay|center|marginTop|attribs|documentElement|mode|fitsize|while|graphicsDir|allowReduce|setTimeout|fadeBox|Id|safari|end|minTblPos|owner|cur|zIndexCounter|images|navigator|moveOnly|preventDefault|relToVP|tagName|selectThumb|block|styleRestoreCursor|disable|sizeOverlayBox|marginLeft|uclt|keyHandler|Outline|9999px|fac|padToMinWidth|matches|above|slideshows|idCounter|getNode|preloadTheseImages|credits|Expander||group|all|250|on|isExpanded|max|domCh|xsize|buttons|ysize|numberPosition|minWidth|iebody|addRule|fix|blurExp|getParam|scrollTop|filter|trans|scrollLeft|restoreCursor|fade|prototype|param|allowSizeReduction|userAgent|doShowHide|opos|getParams|afterClose|minHeight|destroy|positionOverlay|curTblPos|setAttribute|break|offY|dir|offX|hsKey|onReady|wrapperKey|showHideElements|self|cancelLoading|isHsAnchor|expandCursor|gotoEnd|url|keypress|keydown|pointer|curAnim|dX|langDefaults|dragHandler|html|RegExp|toLowerCase|geckoMac|getAnchors|oDiv|afterExpand|complete|onload|expOnly|mouse|destroyOverlays|clientY|hideOnMouseOut|fullExpandLabel|marker|clientX|previousOrNext|getAnchorIndex|yimgPad|getPosition|overlayWidth|compatMode|topmostKey|doFullExpand|childNodes|disabled|adj|mousemove|ximgPad|object|Dimension|add|525|os|getPageSize|panel|thumbsUserSetId|tId|heading|preloadFullImage|lt|over|below|relatedTarget|maxWidth|onLoadStarted|align|isReady|Create|Text|connectOutline|other|props|xp2|calcExpanded|loadingPosXfade|maxHeight|margin|defaultView|showLoading|overrides|yp2|calcThumb|endOff|continuePreloading||init|from|getSrc|calcBorders||types|names|loadingPos|hasMovedMin|maxsize|getAdjacentAnchor|startOff|ucrb|mY|expandDuration|current|hasAlphaImageLoader|mX|cloneNode|resizeTo|srcElement|mouseIsOver|easeOutQuad|dY|fullExpandTitle|oPos|markerPos|distance|doWrapper|ie6|dragByHeading|sel|activeRight|thumbnailId|genOverlayBox|numberOfImagesToPreload|wrapperClassName|moveTo|error|isNew|activeLeft|dimmingDuration|pixDimmerSize|clones|topZ|scrollBy|parseInt|osize|element|updateAnchors|BackCompat|undim|hasFocused|Slideshow|pThis|css|ul|dec|state|scrollUp|setPos|startTime|floatMode|setSize|transit|restoreTitle|scrollDown|getWrapperKey|mouseClickHandler|origProp|blur|update|parent|isClosing|done|openerTagNames|changeSize|parOff|middle|relative|garbageBin|backCompat|arrow|clientWidth|parseFloat|Click|restoreDuration|string|fullExpandText|moveTitle|closeTitle|captionOverlay|closeText|moveText|targetY|targetX|headingOverlay|playTitle|spacebar|Previous|Next|Move|Pause|Play|Highslide|JS|Close|contentLoaded|and|pauseTitle|pauseText|nextTitle|playText|wrapperMouseHandler|200|previousTitle|previousText|nextText|enableKeyListener|timerId|Date|switch|orig|rb|loadingOpacity|toUpperCase|easeInQuad|getTime|call|_default|png|preloadGraphic||appendTo|onGraphicLoad|hide|vis|background|loadingText|loadingTitle|offsetTop|pageOrigin|allowMultipleInstances|offsetParent|pageXOffset|tag|nopad|alpha|thumb|dimmingGeckoFix|pow|detachEvent|ltr|clickY|clickX|focusTopmost|form|rv|hideIframes|relativeTo|offsetX|cssDirection|wheelDelta|reuseOverlay|direction|offsetY|leftpanel|stripItemFormatter|getOverlays|marginBottom|rightpanel|marginRight|detail|hand|getComputedStyle|getPropertyValue|preloadImages|styleSheets|Overlay|hideSelects|arguments|returnValue|indexOf|focusTitle|clearsY|sls|getAttribute|getInline|getNumber|getElementByClass|Right|skin|replaceLang|Bottom|getControls|checkFirstAndLast|repeat|wait|hitSpace|Thumbstrip|Left|Top|Width|reOrder|doPanels|showOverlays|gotOverlays|writeCredits|showCredits|horizontal|createFullExpand|fullExpandOpacity|fixedControls||fullExpandPosition|Height|javascript|addOverlay|clearsX|after|load|mouseup|initSlideshow|overlayOptions|fadeInOut|creditsTarget|creditsHref|show|mousedown|toString|ximgSize|clientHeight|transitionDuration|border|yimgSize|oldImg|preloadNext|prepareNextOutline|newImg|creditsText|easingClose|tmpMin|_|creditsPosition|Eval|fitOverlayBox|correctRatio|creditsTitle|nextSibling|innerWidth|innerHeight|inner|scrollHeight|down|firstChild|clearTimeout|Image|cancel|Loading|fixed|bring|pageYOffset|currentStyle|Resize|geckodimmer|float|the|dimming|actual|Android|Go|iPhone|Powered|of|iPod|mgnRight|iPad|resizeTitle|esc|front|Expand||homepage|scrollWidth|mousewheel|HsExpander|doScroll|1001|callee|captionId|captionText|zoomin|captionEval|zoomout|DOMContentLoaded|text|ignoreMe|_self|outlineStartOffset|http|drop|shadow|HEAD|createTextNode|expression|headingId|graphics|padding|DOMMouseScroll|Use|keys|com|onmousewheel|click|removeAttribute|drag|getElementById|important|it|Trident||headingEval|headingText|ra|Safari|Gecko|120|Macintosh|pI|sqrt|reuse|allowSimultaneousLoading|rect|abs|isHtml|keyCode|cellSpacing|readyState|clip|onmouseover|clearInterval|splice|setInterval|200px|preserveContent|default|onmouseout|borderCollapse|collapse|AlphaImageLoader|Microsoft|DXImageTransform|sizingMethod|scale|eval|stl|progid|SELECT|outlinesDir|fontSize|lineHeight|outlines|IFRAME|500|interval|vendor|KDE|mouseover|dragSensitivity|blockRightClick|location|lineNumber|message|dynamicallyUpdateAnchors|useControls|addSlideshow|registerOverlay|htmlE|xpand|hasHtmlExpanders|button|imageCreate|fromElement|flushImgSize|caption|linearTween|floor|fit|split|toElement|oncontextmenu|alert|removeChild|debug|attachEvent|Line'.split('|'),0,{}))
diff --git a/site/highslide.css b/site/highslide.css
new file mode 100644
index 0000000..adae509
--- /dev/null
+++ b/site/highslide.css
@@ -0,0 +1,955 @@
+/**
+* @file: highslide.css 
+* @version: 4.1.13
+*/
+.highslide-container div {
+	font-family: Verdana, Helvetica;
+	font-size: 10pt;
+}
+.highslide-container table {
+	background: none;
+	table-layout: auto;
+}
+.highslide {
+	outline: none;
+	text-decoration: none;
+}
+.highslide img {
+	border: 2px solid silver;
+}
+.highslide:hover img {
+	border-color: gray;
+}
+.highslide-active-anchor img {
+	visibility: hidden;
+}
+.highslide-gallery .highslide-active-anchor img {
+	border-color: black;
+	visibility: visible;
+	cursor: default;
+}
+.highslide-image {
+	border-width: 2px;
+	border-style: solid;
+	border-color: white;
+}
+.highslide-wrapper, .highslide-outline {
+	background: white;
+}
+.glossy-dark {
+	background: #111;
+}
+
+.highslide-image-blur {
+}
+.highslide-number {
+	font-weight: bold;
+	color: gray;
+	font-size: .9em;
+}
+.highslide-caption {
+	display: none;
+	font-size: 1em;
+	padding: 5px;
+	/*background: white;*/
+}
+.highslide-heading {
+	display: none;
+	font-weight: bold;
+	margin: 0.4em;
+}
+.highslide-dimming {
+	/*position: absolute;*/
+	background: black;
+}
+a.highslide-full-expand {
+   background: url(graphics/fullexpand.gif) no-repeat;
+   display: block;
+   margin: 0 10px 10px 0;
+   width: 34px;
+   height: 34px;
+}
+.highslide-loading {
+	display: block;
+	color: black;
+	font-size: 9px;
+	font-weight: bold;
+	text-transform: uppercase;
+	text-decoration: none;
+	padding: 3px;
+	border: 1px solid white;
+	background-color: white;
+	padding-left: 22px;
+	background-image: url(graphics/loader.white.gif);
+	background-repeat: no-repeat;
+	background-position: 3px 1px;
+}
+a.highslide-credits,
+a.highslide-credits i {
+	padding: 2px;
+	color: silver;
+	text-decoration: none;
+	font-size: 10px;
+}
+a.highslide-credits:hover,
+a.highslide-credits:hover i {
+	color: white;
+	background-color: gray;
+}
+.highslide-move, .highslide-move * {
+	cursor: move;
+}
+
+.highslide-viewport {
+	display: none;
+	position: fixed;
+	width: 100%;
+	height: 100%;
+	z-index: 1;
+	background: none;
+	left: 0;
+	top: 0;
+}
+.highslide-overlay {
+	display: none;
+}
+.hidden-container {
+	display: none;
+}
+/* Example of a semitransparent, offset closebutton */
+.closebutton {
+	position: relative;
+	top: -15px;
+	left: 15px;
+	width: 30px;
+	height: 30px;
+	cursor: pointer;
+	background: url(graphics/close.png);
+	/* NOTE! For IE6, you also need to update the highslide-ie6.css file. */
+}
+
+/*****************************************************************************/
+/* Thumbnail boxes for the galleries.                                        */
+/* Remove these if you are not using a gallery.                              */
+/*****************************************************************************/
+.highslide-gallery ul {
+	list-style-type: none;
+	margin: 0;
+	padding: 0;
+}
+.highslide-gallery ul li {
+	display: block;
+	position: relative;
+	float: left;
+	width: 106px;
+	height: 106px;
+	border: 1px solid silver;
+	background: #ededed;
+	margin: 2px;
+	padding: 0;
+	line-height: 0;
+	overflow: hidden;
+}
+.highslide-gallery ul a {
+	position: absolute;
+	top: 50%;
+	left: 50%;
+}
+.highslide-gallery ul img {
+ 	position: relative;
+	top: -50%;
+	left: -50%;
+}
+html>/**/body .highslide-gallery ul li {
+	display: table;
+	text-align: center;
+}
+html>/**/body .highslide-gallery ul li {
+	text-align: center;
+}
+html>/**/body .highslide-gallery ul a {
+	position: static;
+	display: table-cell;
+	vertical-align: middle;
+}
+html>/**/body .highslide-gallery ul img {
+	position: static;
+}
+
+/*****************************************************************************/
+/* Controls for the galleries.											     */
+/* Remove these if you are not using a gallery							     */
+/*****************************************************************************/
+.highslide-controls {
+	width: 195px;
+	height: 40px;
+	background: url(graphics/controlbar-white.gif) 0 -90px no-repeat;
+	margin: 20px 15px 10px 0;
+}
+.highslide-controls ul {
+	position: relative;
+	left: 15px;
+	height: 40px;
+	list-style: none;
+	margin: 0;
+	padding: 0;
+	background: url(graphics/controlbar-white.gif) right -90px no-repeat;
+
+}
+.highslide-controls li {
+	float: left;
+	padding: 5px 0;
+	margin:0;
+	list-style: none;
+}
+.highslide-controls a {
+	background-image: url(graphics/controlbar-white.gif);
+	display: block;
+	float: left;
+	height: 30px;
+	width: 30px;
+	outline: none;
+}
+.highslide-controls a.disabled {
+	cursor: default;
+}
+.highslide-controls a.disabled span {
+	cursor: default;
+}
+.highslide-controls a span {
+	/* hide the text for these graphic buttons */
+	display: none;
+	cursor: pointer;
+}
+
+
+/* The CSS sprites for the controlbar - see http://www.google.com/search?q=css+sprites */
+.highslide-controls .highslide-previous a {
+	background-position: 0 0;
+}
+.highslide-controls .highslide-previous a:hover {
+	background-position: 0 -30px;
+}
+.highslide-controls .highslide-previous a.disabled {
+	background-position: 0 -60px !important;
+}
+.highslide-controls .highslide-play a {
+	background-position: -30px 0;
+}
+.highslide-controls .highslide-play a:hover {
+	background-position: -30px -30px;
+}
+.highslide-controls .highslide-play a.disabled {
+	background-position: -30px -60px !important;
+}
+.highslide-controls .highslide-pause a {
+	background-position: -60px 0;
+}
+.highslide-controls .highslide-pause a:hover {
+	background-position: -60px -30px;
+}
+.highslide-controls .highslide-next a {
+	background-position: -90px 0;
+}
+.highslide-controls .highslide-next a:hover {
+	background-position: -90px -30px;
+}
+.highslide-controls .highslide-next a.disabled {
+	background-position: -90px -60px !important;
+}
+.highslide-controls .highslide-move a {
+	background-position: -120px 0;
+}
+.highslide-controls .highslide-move a:hover {
+	background-position: -120px -30px;
+}
+.highslide-controls .highslide-full-expand a {
+	background-position: -150px 0;
+}
+.highslide-controls .highslide-full-expand a:hover {
+	background-position: -150px -30px;
+}
+.highslide-controls .highslide-full-expand a.disabled {
+	background-position: -150px -60px !important;
+}
+.highslide-controls .highslide-close a {
+	background-position: -180px 0;
+}
+.highslide-controls .highslide-close a:hover {
+	background-position: -180px -30px;
+}
+
+/*****************************************************************************/
+/* Styles for the HTML popups											     */
+/* Remove these if you are not using Highslide HTML						     */
+/*****************************************************************************/
+.highslide-maincontent {
+	display: none;
+}
+.highslide-html {
+	background-color: white;
+}
+.mobile .highslide-html {
+	border: 1px solid silver;
+}
+.highslide-html-content {
+	display: none;
+	width: 400px;
+	padding: 0 5px 5px 5px;
+}
+.highslide-header {
+	padding-bottom: 5px;
+}
+.highslide-header ul {
+	margin: 0;
+	padding: 0;
+	text-align: right;
+}
+.highslide-header ul li {
+	display: inline;
+	padding-left: 1em;
+}
+.highslide-header ul li.highslide-previous, .highslide-header ul li.highslide-next {
+	display: none;
+}
+.highslide-header a {
+	font-weight: bold;
+	color: gray;
+	text-transform: uppercase;
+	text-decoration: none;
+}
+.highslide-header a:hover {
+	color: black;
+}
+.highslide-header .highslide-move a {
+	cursor: move;
+}
+.highslide-footer {
+	height: 16px;
+}
+.highslide-footer .highslide-resize {
+	display: block;
+	float: right;
+	margin-top: 5px;
+	height: 11px;
+	width: 11px;
+	background: url(graphics/resize.gif) no-repeat;
+}
+.highslide-footer .highslide-resize span {
+	display: none;
+}
+.highslide-body {
+}
+.highslide-resize {
+	cursor: nw-resize;
+}
+
+/*****************************************************************************/
+/* Styles for the Individual wrapper class names.							 */
+/* See www.highslide.com/ref/hs.wrapperClassName							 */
+/* You can safely remove the class name themes you don't use				 */
+/*****************************************************************************/
+
+/* hs.wrapperClassName = 'draggable-header' */
+.draggable-header .highslide-header {
+	height: 18px;
+	border-bottom: 1px solid #dddddd;
+}
+.draggable-header .highslide-heading {
+	position: absolute;
+	margin: 2px 0.4em;
+}
+
+.draggable-header .highslide-header .highslide-move {
+	cursor: move;
+	display: block;
+	height: 16px;
+	position: absolute;
+	right: 24px;
+	top: 0;
+	width: 100%;
+	z-index: 1;
+}
+.draggable-header .highslide-header .highslide-move * {
+	display: none;
+}
+.draggable-header .highslide-header .highslide-close {
+	position: absolute;
+	right: 2px;
+	top: 2px;
+	z-index: 5;
+	padding: 0;
+}
+.draggable-header .highslide-header .highslide-close a {
+	display: block;
+	height: 16px;
+	width: 16px;
+	background-image: url(graphics/closeX.png);
+}
+.draggable-header .highslide-header .highslide-close a:hover {
+	background-position: 0 16px;
+}
+.draggable-header .highslide-header .highslide-close span {
+	display: none;
+}
+.draggable-header .highslide-maincontent {
+	padding-top: 1em;
+}
+
+/* hs.wrapperClassName = 'titlebar' */
+.titlebar .highslide-header {
+	height: 18px;
+	border-bottom: 1px solid #dddddd;
+}
+.titlebar .highslide-heading {
+	position: absolute;
+	width: 90%;
+	margin: 1px 0 1px 5px;
+	color: #666666;
+}
+
+.titlebar .highslide-header .highslide-move {
+	cursor: move;
+	display: block;
+	height: 16px;
+	position: absolute;
+	right: 24px;
+	top: 0;
+	width: 100%;
+	z-index: 1;
+}
+.titlebar .highslide-header .highslide-move * {
+	display: none;
+}
+.titlebar .highslide-header li {
+	position: relative;
+	top: 3px;
+	z-index: 2;
+	padding: 0 0 0 1em;
+}
+.titlebar .highslide-maincontent {
+	padding-top: 1em;
+}
+
+/* hs.wrapperClassName = 'no-footer' */
+.no-footer .highslide-footer {
+	display: none;
+}
+
+/* hs.wrapperClassName = 'wide-border' */
+.wide-border {
+	background: white;
+}
+.wide-border .highslide-image {
+	border-width: 10px;
+}
+.wide-border .highslide-caption {
+	padding: 0 10px 10px 10px;
+}
+
+/* hs.wrapperClassName = 'borderless' */
+.borderless .highslide-image {
+	border: none;
+}
+.borderless .highslide-caption {
+	border-bottom: 1px solid white;
+	border-top: 1px solid white;
+	background: silver;
+}
+
+/* hs.wrapperClassName = 'outer-glow' */
+.outer-glow {
+	background: #444;
+}
+.outer-glow .highslide-image {
+	border: 5px solid #444444;
+}
+.outer-glow .highslide-caption {
+	border: 5px solid #444444;
+	border-top: none;
+	padding: 5px;
+	background-color: gray;
+}
+
+/* hs.wrapperClassName = 'colored-border' */
+.colored-border {
+	background: white;
+}
+.colored-border .highslide-image {
+	border: 2px solid green;
+}
+.colored-border .highslide-caption {
+	border: 2px solid green;
+	border-top: none;
+}
+
+/* hs.wrapperClassName = 'dark' */
+.dark {
+	background: #111;
+}
+.dark .highslide-image {
+	border-color: black black #202020 black;
+	background: gray;
+}
+.dark .highslide-caption {
+	color: white;
+	background: #111;
+}
+.dark .highslide-controls,
+.dark .highslide-controls ul,
+.dark .highslide-controls a {
+	background-image: url(graphics/controlbar-black-border.gif);
+}
+
+/* hs.wrapperClassName = 'floating-caption' */
+.floating-caption .highslide-caption {
+	position: absolute;
+	padding: 1em 0 0 0;
+	background: none;
+	color: white;
+	border: none;
+	font-weight: bold;
+}
+
+/* hs.wrapperClassName = 'controls-in-heading' */
+.controls-in-heading .highslide-heading {
+	color: gray;
+	font-weight: bold;
+	height: 20px;
+	overflow: hidden;
+	cursor: default;
+	padding: 0 0 0 22px;
+	margin: 0;
+	background: url(graphics/icon.gif) no-repeat 0 1px;
+}
+.controls-in-heading .highslide-controls {
+	width: 105px;
+	height: 20px;
+	position: relative;
+	margin: 0;
+	top: -23px;
+	left: 7px;
+	background: none;
+}
+.controls-in-heading .highslide-controls ul {
+	position: static;
+	height: 20px;
+	background: none;
+}
+.controls-in-heading .highslide-controls li {
+	padding: 0;
+}
+.controls-in-heading .highslide-controls a {
+	background-image: url(graphics/controlbar-white-small.gif);
+	height: 20px;
+	width: 20px;
+}
+
+.controls-in-heading .highslide-controls .highslide-move {
+	display: none;
+}
+
+.controls-in-heading .highslide-controls .highslide-previous a {
+	background-position: 0 0;
+}
+.controls-in-heading .highslide-controls .highslide-previous a:hover {
+	background-position: 0 -20px;
+}
+.controls-in-heading .highslide-controls .highslide-previous a.disabled {
+	background-position: 0 -40px !important;
+}
+.controls-in-heading .highslide-controls .highslide-play a {
+	background-position: -20px 0;
+}
+.controls-in-heading .highslide-controls .highslide-play a:hover {
+	background-position: -20px -20px;
+}
+.controls-in-heading .highslide-controls .highslide-play a.disabled {
+	background-position: -20px -40px !important;
+}
+.controls-in-heading .highslide-controls .highslide-pause a {
+	background-position: -40px 0;
+}
+.controls-in-heading .highslide-controls .highslide-pause a:hover {
+	background-position: -40px -20px;
+}
+.controls-in-heading .highslide-controls .highslide-next a {
+	background-position: -60px 0;
+}
+.controls-in-heading .highslide-controls .highslide-next a:hover {
+	background-position: -60px -20px;
+}
+.controls-in-heading .highslide-controls .highslide-next a.disabled {
+	background-position: -60px -40px !important;
+}
+.controls-in-heading .highslide-controls .highslide-full-expand a {
+	background-position: -100px 0;
+}
+.controls-in-heading .highslide-controls .highslide-full-expand a:hover {
+	background-position: -100px -20px;
+}
+.controls-in-heading .highslide-controls .highslide-full-expand a.disabled {
+	background-position: -100px -40px !important;
+}
+.controls-in-heading .highslide-controls .highslide-close a {
+	background-position: -120px 0;
+}
+.controls-in-heading .highslide-controls .highslide-close a:hover {
+	background-position: -120px -20px;
+}
+
+/*****************************************************************************/
+/* Styles for text based controls.						                     */
+/* You can safely remove this if you don't use text based controls			 */
+/*****************************************************************************/
+
+.text-controls .highslide-controls {
+	width: auto;
+	height: auto;
+	margin: 0;
+	text-align: center;
+	background: none;
+}
+.text-controls ul {
+	position: static;
+	background: none;
+	height: auto;
+	left: 0;
+}
+.text-controls .highslide-move {
+	display: none;
+}
+.text-controls li {
+    background-image: url(graphics/controlbar-text-buttons.png);
+	background-position: right top !important;
+	padding: 0;
+	margin-left: 15px;
+	display: block;
+	width: auto;
+}
+.text-controls a {
+    background: url(graphics/controlbar-text-buttons.png) no-repeat;
+    background-position: left top !important;
+    position: relative;
+    left: -10px;
+	display: block;
+	width: auto;
+	height: auto;
+	text-decoration: none !important;
+}
+.text-controls a span {
+	background: url(graphics/controlbar-text-buttons.png) no-repeat;
+    margin: 1px 2px 1px 10px;
+	display: block;
+    min-width: 4em;
+    height: 18px;
+    line-height: 18px;
+	padding: 1px 0 1px 18px;
+    color: #333;
+	font-family: "Trebuchet MS", Arial, sans-serif;
+	font-size: 12px;
+	font-weight: bold;
+	white-space: nowrap;
+}
+.text-controls .highslide-next {
+	margin-right: 1em;
+}
+.text-controls .highslide-full-expand a span {
+	min-width: 0;
+	margin: 1px 0;
+	padding: 1px 0 1px 10px;
+}
+.text-controls .highslide-close a span {
+	min-width: 0;
+}
+.text-controls a:hover span {
+	color: black;
+}
+.text-controls a.disabled span {
+	color: #999;
+}
+
+.text-controls .highslide-previous span {
+	background-position: 0 -40px;
+}
+.text-controls .highslide-previous a.disabled {
+	background-position: left top !important;
+}
+.text-controls .highslide-previous a.disabled span {
+	background-position: 0 -140px;
+}
+.text-controls .highslide-play span {
+	background-position: 0 -60px;
+}
+.text-controls .highslide-play a.disabled {
+	background-position: left top !important;
+}
+.text-controls .highslide-play a.disabled span {
+	background-position: 0 -160px;
+}
+.text-controls .highslide-pause span {
+	background-position: 0 -80px;
+}
+.text-controls .highslide-next span {
+	background-position: 0 -100px;
+}
+.text-controls .highslide-next a.disabled {
+	background-position: left top !important;
+}
+.text-controls .highslide-next a.disabled span {
+	background-position: 0 -200px;
+}
+.text-controls .highslide-full-expand span {
+	background: none;
+}
+.text-controls .highslide-full-expand a.disabled {
+	background-position: left top !important;
+}
+.text-controls .highslide-close span {
+	background-position: 0 -120px;
+}
+
+
+/*****************************************************************************/
+/* Styles for the thumbstrip.							                     */
+/* See www.highslide.com/ref/hs.addSlideshow    							 */
+/* You can safely remove this if you don't use a thumbstrip 				 */
+/*****************************************************************************/
+
+.highslide-thumbstrip {
+	height: 100%;
+	direction: ltr;
+}
+.highslide-thumbstrip div {
+	overflow: hidden;
+}
+.highslide-thumbstrip table {
+	position: relative;
+	padding: 0;
+	border-collapse: collapse;
+}
+.highslide-thumbstrip td {
+	padding: 1px;
+	/*text-align: center;*/
+}
+.highslide-thumbstrip a {
+	outline: none;
+}
+.highslide-thumbstrip img {
+	display: block;
+	border: 1px solid gray;
+	margin: 0 auto;
+}
+.highslide-thumbstrip .highslide-active-anchor img {
+	visibility: visible;
+}
+.highslide-thumbstrip .highslide-marker {
+	position: absolute;
+	width: 0;
+	height: 0;
+	border-width: 0;
+	border-style: solid;
+	border-color: transparent; /* change this to actual background color in highslide-ie6.css */
+}
+.highslide-thumbstrip-horizontal div {
+	width: auto;
+	/* width: 100% breaks in small strips in IE */
+}
+.highslide-thumbstrip-horizontal .highslide-scroll-up {
+	display: none;
+	position: absolute;
+	top: 3px;
+	left: 3px;
+	width: 25px;
+	height: 42px;
+}
+.highslide-thumbstrip-horizontal .highslide-scroll-up div {
+	margin-bottom: 10px;
+	cursor: pointer;
+	background: url(graphics/scrollarrows.png) left center no-repeat;
+	height: 42px;
+}
+.highslide-thumbstrip-horizontal .highslide-scroll-down {
+	display: none;
+	position: absolute;
+	top: 3px;
+	right: 3px;
+	width: 25px;
+	height: 42px;
+}
+.highslide-thumbstrip-horizontal .highslide-scroll-down div {
+	margin-bottom: 10px;
+	cursor: pointer;
+	background: url(graphics/scrollarrows.png) center right no-repeat;
+	height: 42px;
+}
+.highslide-thumbstrip-horizontal table {
+	margin: 2px 0 10px 0;
+}
+.highslide-viewport .highslide-thumbstrip-horizontal table {
+	margin-left: 10px;
+}
+.highslide-thumbstrip-horizontal img {
+	width: auto;
+	height: 40px;
+}
+.highslide-thumbstrip-horizontal .highslide-marker {
+	top: 47px;
+	border-left-width: 6px;
+	border-right-width: 6px;
+	border-bottom: 6px solid gray;
+}
+.highslide-viewport .highslide-thumbstrip-horizontal .highslide-marker {
+	margin-left: 10px;
+}
+.dark .highslide-thumbstrip-horizontal .highslide-marker, .highslide-viewport .highslide-thumbstrip-horizontal .highslide-marker {
+	border-bottom-color: white !important;
+}
+
+.highslide-thumbstrip-vertical-overlay {
+	overflow: hidden !important;
+}
+.highslide-thumbstrip-vertical div {
+	height: 100%;
+}
+.highslide-thumbstrip-vertical a {
+	display: block;
+}
+.highslide-thumbstrip-vertical .highslide-scroll-up {
+	display: none;
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 25px;
+}
+.highslide-thumbstrip-vertical .highslide-scroll-up div {
+	margin-left: 10px;
+	cursor: pointer;
+	background: url(graphics/scrollarrows.png) top center no-repeat;
+	height: 25px;
+}
+.highslide-thumbstrip-vertical .highslide-scroll-down {
+	display: none;
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	width: 100%;
+	height: 25px;
+}
+.highslide-thumbstrip-vertical .highslide-scroll-down div {
+	margin-left: 10px;
+	cursor: pointer;
+	background: url(graphics/scrollarrows.png) bottom center no-repeat;
+	height: 25px;
+}
+.highslide-thumbstrip-vertical table {
+	margin: 10px 0 0 10px;
+}
+.highslide-thumbstrip-vertical img {
+	width: 60px; /* t=5481 */
+}
+.highslide-thumbstrip-vertical .highslide-marker {
+	left: 0;
+	margin-top: 8px;
+	border-top-width: 6px;
+	border-bottom-width: 6px;
+	border-left: 6px solid gray;
+}
+.dark .highslide-thumbstrip-vertical .highslide-marker, .highslide-viewport .highslide-thumbstrip-vertical .highslide-marker {
+	border-left-color: white;
+}
+
+.highslide-viewport .highslide-thumbstrip-float {
+	overflow: auto;
+}
+.highslide-thumbstrip-float ul {
+	margin: 2px 0;
+	padding: 0;
+}
+.highslide-thumbstrip-float li {
+	display: block;
+	height: 60px;
+	margin: 0 2px;
+	list-style: none;
+	float: left;
+}
+.highslide-thumbstrip-float img {
+	display: inline;
+	border-color: silver;
+	max-height: 56px;
+}
+.highslide-thumbstrip-float .highslide-active-anchor img {
+	border-color: black;
+}
+.highslide-thumbstrip-float .highslide-scroll-up div, .highslide-thumbstrip-float .highslide-scroll-down div {
+	display: none;
+}
+.highslide-thumbstrip-float .highslide-marker {
+	display: none;
+}
+
+
+/*****************************************************************************/
+/* The following styles are added by the Highslide Editor                    */
+/*****************************************************************************/
+.highslide-wrapper, .highslide-outline {
+	background: #111111;
+}
+.highslide img {
+	border: 1px solid #D0D0D0;
+}
+.highslide:hover img {
+	border-color: #A0A0A0;
+}
+.highslide-active-anchor img {
+	visibility: visible;
+	border-color: #808080 !important;
+}
+.highslide-dimming {
+	background: #000000;
+}
+.highslide-image {
+	border: none;
+}
+.highslide-caption {
+	position: absolute;
+	width: 100%;
+	color: #FFFFFF;
+	font-weight: bold;
+	padding: 5px;
+	padding-right: 0px;
+	padding-bottom: 0px;
+	padding-left: 0px;
+}
+.highslide-loading {
+	color: black;
+	border: 1px solid black;
+	background-color: white;
+	background-image: url(graphics/loader.white.gif);
+}
+
+.highslide-controls {
+	position: static !important;
+	margin-bottom: 0;
+	width: 135px !important;
+}
+.large-dark .highslide-controls, .large-dark .highslide-controls ul, .large-dark .highslide-controls a {
+	background-image: url(graphics/controlbar-black-border.gif);
+}
+.highslide-controls .highslide-play {
+	display: none;
+}
+.highslide-controls .highslide-pause {
+	display: none;
+}
+.highslide-controls .highslide-move {
+	display: none;
+}
+.highslide-gallery ul li {
+	width: 106px;
+	height: 106px;
+	border: 1px solid #D0D0D0;
+	background: #EDEDED;
+	margin: 2px;
+}
diff --git a/site/images/ad_next.png b/site/images/ad_next.png
new file mode 100644
index 0000000..5da3694
Binary files /dev/null and b/site/images/ad_next.png differ
diff --git a/site/images/ad_prev.png b/site/images/ad_prev.png
new file mode 100644
index 0000000..38c0667
Binary files /dev/null and b/site/images/ad_prev.png differ
diff --git a/site/images/ad_scroll_back.png b/site/images/ad_scroll_back.png
new file mode 100644
index 0000000..ef69c15
Binary files /dev/null and b/site/images/ad_scroll_back.png differ
diff --git a/site/images/ad_scroll_forward.png b/site/images/ad_scroll_forward.png
new file mode 100644
index 0000000..d47bc7c
Binary files /dev/null and b/site/images/ad_scroll_forward.png differ
diff --git a/site/images/loader.gif b/site/images/loader.gif
new file mode 100644
index 0000000..7e717cd
Binary files /dev/null and b/site/images/loader.gif differ
diff --git a/site/images/opa75.png b/site/images/opa75.png
new file mode 100644
index 0000000..0dd750e
Binary files /dev/null and b/site/images/opa75.png differ
diff --git a/site/jquery.ad-gallery.css b/site/jquery.ad-gallery.css
new file mode 100644
index 0000000..62af329
--- /dev/null
+++ b/site/jquery.ad-gallery.css
@@ -0,0 +1,168 @@
+.ad-gallery {
+  width: 600px;
+}
+.ad-gallery, .ad-gallery * {
+  margin: 0;
+  padding: 0;
+}
+  .ad-gallery .ad-image-wrapper {
+    width: 100%;
+    height: 400px;
+    margin-bottom: 10px;
+    position: relative;
+    overflow: hidden;
+  }
+    .ad-gallery .ad-image-wrapper .ad-loader {
+      position: absolute;
+      z-index: 10;
+      top: 48%;
+      left: 48%;
+      border: 1px solid #CCC;
+    }
+    .ad-gallery .ad-image-wrapper .ad-next {
+      position: absolute;
+      right: 0;
+      top: 0;
+      width: 25%;
+      height: 100%;
+      cursor: pointer;
+      display: block;
+      z-index: 100;
+    }
+    .ad-gallery .ad-image-wrapper .ad-prev {
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 25%;
+      height: 100%;
+      cursor: pointer;
+      display: block;
+      z-index: 100;
+    }
+    .ad-gallery .ad-image-wrapper .ad-prev, .ad-gallery .ad-image-wrapper .ad-next {
+      /* Or else IE will hide it */
+      background: url(non-existing.jpg)\9
+    }
+      .ad-gallery .ad-image-wrapper .ad-prev .ad-prev-image, .ad-gallery .ad-image-wrapper .ad-next .ad-next-image {
+        background: url(ad_prev.png);
+        width: 30px;
+        height: 30px;
+        display: none;
+        position: absolute;
+        top: 47%;
+        left: 0;
+        z-index: 101;
+      }
+      .ad-gallery .ad-image-wrapper .ad-next .ad-next-image {
+        background: url(ad_next.png);
+        width: 30px;
+        height: 30px;
+        right: 0;
+        left: auto;
+      }
+    .ad-gallery .ad-image-wrapper .ad-image {
+      position: absolute;
+      overflow: hidden;
+      top: 0;
+      left: 0;
+      z-index: 9;
+    }
+      .ad-gallery .ad-image-wrapper .ad-image a img {
+        border: 0;
+      }
+      .ad-gallery .ad-image-wrapper .ad-image .ad-image-description {
+        position: absolute;
+        bottom: 0px;
+        left: 0px;
+        padding: 7px;
+        text-align: left;
+        width: 100%;
+        z-index: 2;
+        background: url(opa75.png);
+        color: #000;
+      }
+      * html .ad-gallery .ad-image-wrapper .ad-image .ad-image-description {
+        background: none;
+        filter:progid:DXImageTransform.Microsoft.AlphaImageLoader (enabled=true, sizingMethod=scale, src='opa75.png');
+      }
+        .ad-gallery .ad-image-wrapper .ad-image .ad-image-description .ad-description-title {
+          display: block;
+        }
+  .ad-gallery .ad-controls {
+    height: 20px;
+  }
+    .ad-gallery .ad-info {
+      float: left;
+    }
+    .ad-gallery .ad-slideshow-controls {
+      float: right;
+    }
+      .ad-gallery .ad-slideshow-controls .ad-slideshow-start, .ad-gallery .ad-slideshow-controls .ad-slideshow-stop {
+        padding-left: 5px;
+        cursor: pointer;
+      }
+      .ad-gallery .ad-slideshow-controls .ad-slideshow-countdown {
+        padding-left: 5px;
+        font-size: 0.9em;
+      }
+    .ad-gallery .ad-slideshow-running .ad-slideshow-start {
+      cursor: default;
+      font-style: italic;
+    }
+  .ad-gallery .ad-nav {
+    width: 100%;
+    position: relative;
+  }
+    .ad-gallery .ad-forward, .ad-gallery .ad-back {
+      position: absolute;
+      top: 0;
+      height: 100%;
+      z-index: 10;
+    }
+    /* IE 6 doesn't like height: 100% */
+    * html .ad-gallery .ad-forward, .ad-gallery .ad-back {
+      height: 100px;
+    }
+    .ad-gallery .ad-back {
+      cursor: pointer;
+      left: -20px;
+      width: 13px;
+      display: block;
+      background: url(ad_scroll_back.png) 0px 22px no-repeat;
+    }
+    .ad-gallery .ad-forward {
+      cursor: pointer;
+      display: block;
+      right: -20px;
+      width: 13px;
+      background: url(ad_scroll_forward.png) 0px 22px no-repeat;
+    }
+    .ad-gallery .ad-nav .ad-thumbs {
+      overflow: hidden;
+      width: 100%;
+    }
+      .ad-gallery .ad-thumbs .ad-thumb-list {
+        float: left;
+        width: 9000px;
+        list-style: none;
+      }
+        .ad-gallery .ad-thumbs li {
+          float: left;
+          padding-right: 5px;
+        }
+          .ad-gallery .ad-thumbs li a {
+            display: block;
+          }
+            .ad-gallery .ad-thumbs li a img {
+              border: 3px solid #CCC;
+              display: block;
+            }
+            .ad-gallery .ad-thumbs li a.ad-active img {
+              border: 3px solid #616161;
+            }
+/* Can't do display none, since Opera won't load the images then */
+.ad-preloads {
+  position: absolute;
+  left: -9000px;
+  top: -9000px;
+}
\ No newline at end of file
diff --git a/site/jquery.ad-gallery.js b/site/jquery.ad-gallery.js
new file mode 100644
index 0000000..01ab7d5
--- /dev/null
+++ b/site/jquery.ad-gallery.js
@@ -0,0 +1,850 @@
+/**
+ * Copyright (c) 2010 Anders Ekdahl (http://coffeescripter.com/)
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ *
+ * Version: 1.2.4
+ *
+ * Demo and documentation: http://coffeescripter.com/code/ad-gallery/
+ */
+(function($) {
+  $.fn.adGallery = function(options) {
+    var defaults = { loader_image: 'loader.gif',
+                     start_at_index: 0,
+                     description_wrapper: false,
+                     thumb_opacity: 0.7,
+                     animate_first_image: true,
+                     animation_speed: 400,
+                     width: false,
+                     height: false,
+                     display_next_and_prev: true,
+                     display_back_and_forward: true,
+                     scroll_jump: 0, // If 0, it jumps the width of the container
+                     slideshow: {
+                       enable: false,
+                       autostart: false,
+                       speed: 5000,
+                       start_label: 'Start',
+                       stop_label: 'Stop',
+                       stop_on_scroll: true,
+                       countdown_prefix: '(',
+                       countdown_sufix: ')',
+                       onStart: false,
+                       onStop: false
+                     },
+                     effect: 'fade', // or 'slide-vert', 'fade', or 'resize', 'none'
+                     enable_keyboard_move: true,
+                     cycle: true,
+                     callbacks: {
+                       init: false,
+                       afterImageVisible: false,
+                       beforeImageVisible: false
+                     }
+    };
+    var settings = $.extend(false, defaults, options);
+    if(options && options.slideshow) {
+      settings.slideshow = $.extend(false, defaults.slideshow, options.slideshow);
+    };
+    if(!settings.slideshow.enable) {
+      settings.slideshow.autostart = false;
+    };
+    var galleries = [];
+    $(this).each(function() {
+      var gallery = new AdGallery(this, settings);
+      galleries[galleries.length] = gallery;
+    });
+    // Sorry, breaking the jQuery chain because the gallery instances
+    // are returned so you can fiddle with them
+    return galleries;
+  };
+
+  function VerticalSlideAnimation(img_container, direction, desc) {
+    var current_top = parseInt(img_container.css('top'), 10);
+    if(direction == 'left') {
+      var old_image_top = '-'+ this.image_wrapper_height +'px';
+      img_container.css('top', this.image_wrapper_height +'px');
+    } else {
+      var old_image_top = this.image_wrapper_height +'px';
+      img_container.css('top', '-'+ this.image_wrapper_height +'px');
+    };
+    if(desc) {
+      desc.css('bottom', '-'+ desc[0].offsetHeight +'px');
+      desc.animate({bottom: 0}, this.settings.animation_speed * 2);
+    };
+    if(this.current_description) {
+      this.current_description.animate({bottom: '-'+ this.current_description[0].offsetHeight +'px'}, this.settings.animation_speed * 2);
+    };
+    return {old_image: {top: old_image_top},
+            new_image: {top: current_top}};
+  };
+
+  function HorizontalSlideAnimation(img_container, direction, desc) {
+    var current_left = parseInt(img_container.css('left'), 10);
+    if(direction == 'left') {
+      var old_image_left = '-'+ this.image_wrapper_width +'px';
+      img_container.css('left',this.image_wrapper_width +'px');
+    } else {
+      var old_image_left = this.image_wrapper_width +'px';
+      img_container.css('left','-'+ this.image_wrapper_width +'px');
+    };
+    if(desc) {
+      desc.css('bottom', '-'+ desc[0].offsetHeight +'px');
+      desc.animate({bottom: 0}, this.settings.animation_speed * 2);
+    };
+    if(this.current_description) {
+      this.current_description.animate({bottom: '-'+ this.current_description[0].offsetHeight +'px'}, this.settings.animation_speed * 2);
+    };
+    return {old_image: {left: old_image_left},
+            new_image: {left: current_left}};
+  };
+
+  function ResizeAnimation(img_container, direction, desc) {
+    var image_width = img_container.width();
+    var image_height = img_container.height();
+    var current_left = parseInt(img_container.css('left'), 10);
+    var current_top = parseInt(img_container.css('top'), 10);
+    img_container.css({width: 0, height: 0, top: this.image_wrapper_height / 2, left: this.image_wrapper_width / 2});
+    return {old_image: {width: 0,
+                        height: 0,
+                        top: this.image_wrapper_height / 2,
+                        left: this.image_wrapper_width / 2},
+            new_image: {width: image_width,
+                        height: image_height,
+                        top: current_top,
+                        left: current_left}};
+  };
+
+  function FadeAnimation(img_container, direction, desc) {
+    img_container.css('opacity', 0);
+    return {old_image: {opacity: 0},
+            new_image: {opacity: 1}};
+  };
+
+  // Sort of a hack, will clean this up... eventually
+  function NoneAnimation(img_container, direction, desc) {
+    img_container.css('opacity', 0);
+    return {old_image: {opacity: 0},
+            new_image: {opacity: 1},
+            speed: 0};
+  };
+
+  function AdGallery(wrapper, settings) {
+    this.init(wrapper, settings);
+  };
+  AdGallery.prototype = {
+    // Elements
+    wrapper: false,
+    image_wrapper: false,
+    gallery_info: false,
+    nav: false,
+    loader: false,
+    preloads: false,
+    thumbs_wrapper: false,
+    scroll_back: false,
+    scroll_forward: false,
+    next_link: false,
+    prev_link: false,
+
+    slideshow: false,
+    image_wrapper_width: 0,
+    image_wrapper_height: 0,
+    current_index: 0,
+    current_image: false,
+    current_description: false,
+    nav_display_width: 0,
+    settings: false,
+    images: false,
+    in_transition: false,
+    animations: false,
+    init: function(wrapper, settings) {
+      var context = this;
+      this.wrapper = $(wrapper);
+      this.settings = settings;
+      this.setupElements();
+      this.setupAnimations();
+      if(this.settings.width) {
+        this.image_wrapper_width = this.settings.width;
+        this.image_wrapper.width(this.settings.width);
+        this.wrapper.width(this.settings.width);
+      } else {
+        this.image_wrapper_width = this.image_wrapper.width();
+      };
+      if(this.settings.height) {
+        this.image_wrapper_height = this.settings.height;
+        this.image_wrapper.height(this.settings.height);
+      } else {
+        this.image_wrapper_height = this.image_wrapper.height();
+      };
+      this.nav_display_width = this.nav.width();
+      this.current_index = 0;
+      this.current_image = false;
+      this.current_description = false;
+      this.in_transition = false;
+      this.findImages();
+      if(this.settings.display_next_and_prev) {
+        this.initNextAndPrev();
+      };
+      // The slideshow needs a callback to trigger the next image to be shown
+      // but we don't want to give it access to the whole gallery instance
+      var nextimage_callback = function(callback) {
+        return context.nextImage(callback);
+      };
+      this.slideshow = new AdGallerySlideshow(nextimage_callback, this.settings.slideshow);
+      this.controls.append(this.slideshow.create());
+      if(this.settings.slideshow.enable) {
+        this.slideshow.enable();
+      } else {
+        this.slideshow.disable();
+      };
+      if(this.settings.display_back_and_forward) {
+        this.initBackAndForward();
+      };
+      if(this.settings.enable_keyboard_move) {
+        this.initKeyEvents();
+      };
+      var start_at = parseInt(this.settings.start_at_index, 10);
+      if(window.location.hash && window.location.hash.indexOf('#ad-image') === 0) {
+        start_at = window.location.hash.replace(/[^0-9]+/g, '');
+        // Check if it's a number
+        if((start_at * 1) != start_at) {
+          start_at = this.settings.start_at_index;
+        };
+      };
+
+      this.loading(true);
+      this.showImage(start_at,
+        function() {
+          // We don't want to start the slideshow before the image has been
+          // displayed
+          if(context.settings.slideshow.autostart) {
+            context.preloadImage(start_at + 1);
+            context.slideshow.start();
+          };
+        }
+      );
+      this.fireCallback(this.settings.callbacks.init);
+    },
+    setupAnimations: function() {
+      this.animations = {
+        'slide-vert': VerticalSlideAnimation,
+        'slide-hori': HorizontalSlideAnimation,
+        'resize': ResizeAnimation,
+        'fade': FadeAnimation,
+        'none': NoneAnimation
+      };
+    },
+    setupElements: function() {
+      this.controls = this.wrapper.find('.ad-controls');
+      this.gallery_info = $('<p class="ad-info"></p>');
+      this.controls.append(this.gallery_info);
+      this.image_wrapper = this.wrapper.find('.ad-image-wrapper');
+      this.image_wrapper.empty();
+      this.nav = this.wrapper.find('.ad-nav');
+      this.thumbs_wrapper = this.nav.find('.ad-thumbs');
+      this.preloads = $('<div class="ad-preloads"></div>');
+      this.loader = $('<img class="ad-loader" src="'+ this.settings.loader_image +'">');
+      this.image_wrapper.append(this.loader);
+      this.loader.hide();
+      $(document.body).append(this.preloads);
+    },
+    loading: function(bool) {
+      if(bool) {
+        this.loader.show();
+      } else {
+        this.loader.hide();
+      };
+    },
+    addAnimation: function(name, fn) {
+      if($.isFunction(fn)) {
+        this.animations[name] = fn;
+      };
+    },
+    findImages: function() {
+      var context = this;
+      this.images = [];
+      var thumb_wrapper_width = 0;
+      var thumbs_loaded = 0;
+      var thumbs = this.thumbs_wrapper.find('a');
+      var thumb_count = thumbs.length;
+      if(this.settings.thumb_opacity < 1) {
+        thumbs.find('img').css('opacity', this.settings.thumb_opacity);
+      };
+      thumbs.each(
+        function(i) {
+          var link = $(this);
+          var image_src = link.attr('href');
+          var thumb = link.find('img');
+          // Check if the thumb has already loaded
+          if(!context.isImageLoaded(thumb[0])) {
+            thumb.load(
+              function() {
+                thumb_wrapper_width += this.parentNode.parentNode.offsetWidth;
+                thumbs_loaded++;
+              }
+            );
+          } else{
+            thumb_wrapper_width += thumb[0].parentNode.parentNode.offsetWidth;
+            thumbs_loaded++;
+          };
+          link.addClass('ad-thumb'+ i);
+          link.click(
+            function() {
+              context.showImage(i);
+              context.slideshow.stop();
+              return false;
+            }
+          ).hover(
+            function() {
+              if(!$(this).is('.ad-active') && context.settings.thumb_opacity < 1) {
+                $(this).find('img').fadeTo(300, 1);
+              };
+              context.preloadImage(i);
+            },
+            function() {
+              if(!$(this).is('.ad-active') && context.settings.thumb_opacity < 1) {
+                $(this).find('img').fadeTo(300, context.settings.thumb_opacity);
+              };
+            }
+          );
+          var link = false;
+          if(thumb.data('ad-link')) {
+            link = thumb.data('ad-link');
+          } else if(thumb.attr('longdesc') && thumb.attr('longdesc').length) {
+            link = thumb.attr('longdesc');
+          };
+          var desc = false;
+          if(thumb.data('ad-desc')) {
+            desc = thumb.data('ad-desc');
+          } else if(thumb.attr('alt') && thumb.attr('alt').length) {
+            desc = thumb.attr('alt');
+          };
+          var title = false;
+          if(thumb.data('ad-title')) {
+            title = thumb.data('ad-title');
+          } else if(thumb.attr('title') && thumb.attr('title').length) {
+            title = thumb.attr('title');
+          };
+          context.images[i] = { thumb: thumb.attr('src'), image: image_src, error: false,
+                                preloaded: false, desc: desc, title: title, size: false,
+                                link: link };
+        }
+      );
+      // Wait until all thumbs are loaded, and then set the width of the ul
+      var inter = setInterval(
+        function() {
+          if(thumb_count == thumbs_loaded) {
+            thumb_wrapper_width -= 100;
+            var list = context.nav.find('.ad-thumb-list');
+            list.css('width', thumb_wrapper_width +'px');
+            var i = 1;
+            var last_height = list.height();
+            while(i < 201) {
+              list.css('width', (thumb_wrapper_width + i) +'px');
+              if(last_height != list.height()) {
+                break;
+              }
+              last_height = list.height();
+              i++;
+            }
+            clearInterval(inter);
+          };
+        },
+        100
+      );
+    },
+    initKeyEvents: function() {
+      var context = this;
+      $(document).keydown(
+        function(e) {
+          if(e.keyCode == 39) {
+            // right arrow
+            context.nextImage();
+            context.slideshow.stop();
+          } else if(e.keyCode == 37) {
+            // left arrow
+            context.prevImage();
+            context.slideshow.stop();
+          };
+        }
+      );
+    },
+    initNextAndPrev: function() {
+      this.next_link = $('<div class="ad-next"><div class="ad-next-image"></div></div>');
+      this.prev_link = $('<div class="ad-prev"><div class="ad-prev-image"></div></div>');
+      this.image_wrapper.append(this.next_link);
+      this.image_wrapper.append(this.prev_link);
+      var context = this;
+      this.prev_link.add(this.next_link).mouseover(
+        function(e) {
+          // IE 6 hides the wrapper div, so we have to set it's width
+          $(this).css('height', context.image_wrapper_height);
+          $(this).find('div').show();
+        }
+      ).mouseout(
+        function(e) {
+          $(this).find('div').hide();
+        }
+      ).click(
+        function() {
+          if($(this).is('.ad-next')) {
+            context.nextImage();
+            context.slideshow.stop();
+          } else {
+            context.prevImage();
+            context.slideshow.stop();
+          };
+        }
+      ).find('div').css('opacity', 0.7);
+    },
+    initBackAndForward: function() {
+      var context = this;
+      this.scroll_forward = $('<div class="ad-forward"></div>');
+      this.scroll_back = $('<div class="ad-back"></div>');
+      this.nav.append(this.scroll_forward);
+      this.nav.prepend(this.scroll_back);
+      var has_scrolled = 0;
+      var thumbs_scroll_interval = false;
+      $(this.scroll_back).add(this.scroll_forward).click(
+        function() {
+          // We don't want to jump the whole width, since an image
+          // might be cut at the edge
+          var width = context.nav_display_width - 50;
+          if(context.settings.scroll_jump > 0) {
+            var width = context.settings.scroll_jump;
+          };
+          if($(this).is('.ad-forward')) {
+            var left = context.thumbs_wrapper.scrollLeft() + width;
+          } else {
+            var left = context.thumbs_wrapper.scrollLeft() - width;
+          };
+          if(context.settings.slideshow.stop_on_scroll) {
+            context.slideshow.stop();
+          };
+          context.thumbs_wrapper.animate({scrollLeft: left +'px'});
+          return false;
+        }
+      ).css('opacity', 0.6).hover(
+        function() {
+          var direction = 'left';
+          if($(this).is('.ad-forward')) {
+            direction = 'right';
+          };
+/*          thumbs_scroll_interval = setInterval(
+            function() {
+              has_scrolled++;
+              // Don't want to stop the slideshow just because we scrolled a pixel or two
+              if(has_scrolled > 30 && context.settings.slideshow.stop_on_scroll) {
+                context.slideshow.stop();
+              };
+              var left = context.thumbs_wrapper.scrollLeft() + 1;
+              if(direction == 'left') {
+                left = context.thumbs_wrapper.scrollLeft() - 1;
+              };
+              context.thumbs_wrapper.scrollLeft(left);
+            },
+            10
+          );*/
+          $(this).css('opacity', 1);
+        },
+        function() {
+          has_scrolled = 0;
+          clearInterval(thumbs_scroll_interval);
+          $(this).css('opacity', 0.6);
+        }
+      );
+    },
+    _afterShow: function() {
+      this.gallery_info.html((this.current_index + 1) +' / '+ this.images.length);
+      if(!this.settings.cycle) {
+        // Needed for IE
+        this.prev_link.show().css('height', this.image_wrapper_height);
+        this.next_link.show().css('height', this.image_wrapper_height);
+        if(this.current_index == (this.images.length - 1)) {
+          this.next_link.hide();
+        };
+        if(this.current_index == 0) {
+          this.prev_link.hide();
+        };
+      };
+      this.fireCallback(this.settings.callbacks.afterImageVisible);
+    },
+    /**
+     * Checks if the image is small enough to fit inside the container
+     * If it's not, shrink it proportionally
+     */
+    _getContainedImageSize: function(image_width, image_height) {
+      if(image_height > this.image_wrapper_height) {
+        var ratio = image_width / image_height;
+        image_height = this.image_wrapper_height;
+        image_width = this.image_wrapper_height * ratio;
+      };
+      if(image_width > this.image_wrapper_width) {
+  	    var ratio = image_height / image_width;
+  	    image_width = this.image_wrapper_width;
+  	    image_height = this.image_wrapper_width * ratio;
+  	  };
+      return {width: image_width, height: image_height};
+    },
+    /**
+     * If the image dimensions are smaller than the wrapper, we position
+     * it in the middle anyway
+     */
+    _centerImage: function(img_container, image_width, image_height) {
+      img_container.css('top', '0px');
+      if(image_height < this.image_wrapper_height) {
+        var dif = this.image_wrapper_height - image_height;
+        img_container.css('top', (dif / 2) +'px');
+      };
+      img_container.css('left', '0px');
+      if(image_width < this.image_wrapper_width) {
+        var dif = this.image_wrapper_width - image_width;
+        img_container.css('left', (dif / 2) +'px');
+      };
+    },
+    _getDescription: function(image) {
+      var desc = false;
+      if(image.desc.length || image.title.length) {
+        var title = '';
+        if(image.title.length) {
+          title = '<strong class="ad-description-title">'+ image.title +'</strong>';
+        };
+        var desc = '';
+        if(image.desc.length) {
+          desc = '<span>'+ image.desc +'</span>';
+        };
+        desc = $('<p class="ad-image-description">'+ title + desc +'</p>');
+      };
+      return desc;
+    },
+    /**
+     * @param function callback Gets fired when the image has loaded, is displaying
+     *                          and it's animation has finished
+     */
+    showImage: function(index, callback) {
+      if(this.images[index] && !this.in_transition) {
+        var context = this;
+        var image = this.images[index];
+        this.in_transition = true;
+        if(!image.preloaded) {
+          this.loading(true);
+          this.preloadImage(index, function() {
+            context.loading(false);
+            context._showWhenLoaded(index, callback);
+          });
+        } else {
+          this._showWhenLoaded(index, callback);
+        };
+      };
+    },
+    /**
+     * @param function callback Gets fired when the image has loaded, is displaying
+     *                          and it's animation has finished
+     */
+    _showWhenLoaded: function(index, callback) {
+      if(this.images[index]) {
+        var context = this;
+        var image = this.images[index];
+        var img_container = $(document.createElement('div')).addClass('ad-image');
+        var img = $(new Image()).attr('src', image.image);
+        if(image.link) {
+          var link = $('<a href="'+ image.link +'" target="_blank"></a>');
+          link.append(img);
+          img_container.append(link);
+        } else {
+          img_container.append(img);
+        }
+        this.image_wrapper.prepend(img_container);
+        var size = this._getContainedImageSize(image.size.width, image.size.height);
+        img.attr('width', size.width);
+        img.attr('height', size.height);
+        img_container.css({width: size.width +'px', height: size.height +'px'});
+        this._centerImage(img_container, size.width, size.height);
+        var desc = this._getDescription(image, img_container);
+        if(desc) {
+          if(!this.settings.description_wrapper) {
+            img_container.append(desc);
+            var width = size.width - parseInt(desc.css('padding-left'), 10) - parseInt(desc.css('padding-right'), 10);
+            desc.css('width', width +'px');
+          } else {
+            this.settings.description_wrapper.append(desc);
+          }
+        };
+        this.highLightThumb(this.nav.find('.ad-thumb'+ index));
+
+        var direction = 'right';
+        if(this.current_index < index) {
+          direction = 'left';
+        };
+        this.fireCallback(this.settings.callbacks.beforeImageVisible);
+        if(this.current_image || this.settings.animate_first_image) {
+          var animation_speed = this.settings.animation_speed;
+          var easing = 'swing';
+          var animation = this.animations[this.settings.effect].call(this, img_container, direction, desc);
+          if(typeof animation.speed != 'undefined') {
+            animation_speed = animation.speed;
+          };
+          if(typeof animation.easing != 'undefined') {
+            easing = animation.easing;
+          };
+          if(this.current_image) {
+            var old_image = this.current_image;
+            var old_description = this.current_description;
+            old_image.animate(animation.old_image, animation_speed, easing,
+              function() {
+                old_image.remove();
+                if(old_description) old_description.remove();
+              }
+            );
+          };
+          img_container.animate(animation.new_image, animation_speed, easing,
+            function() {
+              context.current_index = index;
+              context.current_image = img_container;
+              context.current_description = desc;
+              context.in_transition = false;
+              context._afterShow();
+              context.fireCallback(callback);
+            }
+          );
+        } else {
+          this.current_index = index;
+          this.current_image = img_container;
+          context.current_description = desc;
+          this.in_transition = false;
+          context._afterShow();
+          this.fireCallback(callback);
+        };
+      };
+    },
+    nextIndex: function() {
+      if(this.current_index == (this.images.length - 1)) {
+        if(!this.settings.cycle) {
+          return false;
+        };
+        var next = 0;
+      } else {
+        var next = this.current_index + 1;
+      };
+      return next;
+    },
+    nextImage: function(callback) {
+      var next = this.nextIndex();
+      if(next === false) return false;
+      this.preloadImage(next + 1);
+      this.showImage(next, callback);
+      return true;
+    },
+    prevIndex: function() {
+      if(this.current_index == 0) {
+        if(!this.settings.cycle) {
+          return false;
+        };
+        var prev = this.images.length - 1;
+      } else {
+        var prev = this.current_index - 1;
+      };
+      return prev;
+    },
+    prevImage: function(callback) {
+      var prev = this.prevIndex();
+      if(prev === false) return false;
+      this.preloadImage(prev - 1);
+      this.showImage(prev, callback);
+      return true;
+    },
+    preloadAll: function() {
+      var context = this;
+      var i = 0;
+      function preloadNext() {
+        if(i < context.images.length) {
+          i++;
+          context.preloadImage(i, preloadNext);
+        };
+      };
+      context.preloadImage(i, preloadNext);
+    },
+    preloadImage: function(index, callback) {
+      if(this.images[index]) {
+        var image = this.images[index];
+        if(!this.images[index].preloaded) {
+          var img = $(new Image());
+          img.attr('src', image.image);
+          if(!this.isImageLoaded(img[0])) {
+            this.preloads.append(img);
+            var context = this;
+            img.load(
+              function() {
+                image.preloaded = true;
+                image.size = { width: this.width, height: this.height };
+                context.fireCallback(callback);
+              }
+            ).error(
+              function() {
+                image.error = true;
+                image.preloaded = false;
+                image.size = false;
+              }
+            );
+          } else {
+            image.preloaded = true;
+            image.size = { width: img[0].width, height: img[0].height };
+            this.fireCallback(callback);
+          };
+        } else {
+          this.fireCallback(callback);
+        };
+      };
+    },
+    isImageLoaded: function(img) {
+      if(typeof img.complete != 'undefined' && !img.complete) {
+        return false;
+      };
+      if(typeof img.naturalWidth != 'undefined' && img.naturalWidth == 0) {
+        return false;
+      };
+      return true;
+    },
+    highLightThumb: function(thumb) {
+      this.thumbs_wrapper.find('.ad-active').removeClass('ad-active');
+      thumb.addClass('ad-active');
+      if(this.settings.thumb_opacity < 1) {
+        this.thumbs_wrapper.find('a:not(.ad-active) img').fadeTo(300, this.settings.thumb_opacity);
+        thumb.find('img').fadeTo(300, 1);
+      };
+      var left = thumb[0].parentNode.offsetLeft;
+      left -= (this.nav_display_width / 2) - (thumb[0].offsetWidth / 2);
+      this.thumbs_wrapper.animate({scrollLeft: left +'px'});
+    },
+    fireCallback: function(fn) {
+      if($.isFunction(fn)) {
+        fn.call(this);
+      };
+    }
+  };
+
+  function AdGallerySlideshow(nextimage_callback, settings) {
+    this.init(nextimage_callback, settings);
+  };
+  AdGallerySlideshow.prototype = {
+    start_link: false,
+    stop_link: false,
+    countdown: false,
+    controls: false,
+
+    settings: false,
+    nextimage_callback: false,
+    enabled: false,
+    running: false,
+    countdown_interval: false,
+    init: function(nextimage_callback, settings) {
+      var context = this;
+      this.nextimage_callback = nextimage_callback;
+      this.settings = settings;
+    },
+    create: function() {
+      this.start_link = $('<span class="ad-slideshow-start">'+ this.settings.start_label +'</span>');
+      this.stop_link = $('<span class="ad-slideshow-stop">'+ this.settings.stop_label +'</span>');
+      this.countdown = $('<span class="ad-slideshow-countdown"></span>');
+      this.controls = $('<div class="ad-slideshow-controls"></div>');
+      this.controls.append(this.start_link).append(this.stop_link).append(this.countdown);
+      this.countdown.hide();
+
+      var context = this;
+      this.start_link.click(
+        function() {
+          context.start();
+        }
+      );
+      this.stop_link.click(
+        function() {
+          context.stop();
+        }
+      );
+      $(document).keydown(
+        function(e) {
+          if(e.keyCode == 83) {
+            // 's'
+            if(context.running) {
+              context.stop();
+            } else {
+              context.start();
+            };
+          };
+        }
+      );
+      return this.controls;
+    },
+    disable: function() {
+      this.enabled = false;
+      this.stop();
+      this.controls.hide();
+    },
+    enable: function() {
+      this.enabled = true;
+      this.controls.show();
+    },
+    toggle: function() {
+      if(this.enabled) {
+        this.disable();
+      } else {
+        this.enable();
+      };
+    },
+    start: function() {
+      if(this.running || !this.enabled) return false;
+      var context = this;
+      this.running = true;
+      this.controls.addClass('ad-slideshow-running');
+      this._next();
+      this.fireCallback(this.settings.onStart);
+      return true;
+    },
+    stop: function() {
+      if(!this.running) return false;
+      this.running = false;
+      this.countdown.hide();
+      this.controls.removeClass('ad-slideshow-running');
+      clearInterval(this.countdown_interval);
+      this.fireCallback(this.settings.onStop);
+      return true;
+    },
+    _next: function() {
+      var context = this;
+      var pre = this.settings.countdown_prefix;
+      var su = this.settings.countdown_sufix;
+      clearInterval(context.countdown_interval);
+      this.countdown.show().html(pre + (this.settings.speed / 1000) + su);
+      var slide_timer = 0;
+      this.countdown_interval = setInterval(
+        function() {
+          slide_timer += 1000;
+          if(slide_timer >= context.settings.speed) {
+            var whenNextIsShown = function() {
+              // A check so the user hasn't stoped the slideshow during the
+              // animation
+              if(context.running) {
+                context._next();
+              };
+              slide_timer = 0;
+            };
+            if(!context.nextimage_callback(whenNextIsShown)) {
+              context.stop();
+            };
+            slide_timer = 0;
+          };
+          var sec = parseInt(context.countdown.text().replace(/[^0-9]/g, ''), 10);
+          sec--;
+          if(sec > 0) {
+            context.countdown.html(pre + sec + su);
+          };
+        },
+        1000
+      );
+    },
+    fireCallback: function(fn) {
+      if($.isFunction(fn)) {
+        fn.call(this);
+      };
+    }
+  };
+})(jQuery);
\ No newline at end of file
diff --git a/site/jquery.ad-gallery.pack.js b/site/jquery.ad-gallery.pack.js
new file mode 100644
index 0000000..65e3900
--- /dev/null
+++ b/site/jquery.ad-gallery.pack.js
@@ -0,0 +1,10 @@
+/**
+ * Copyright (c) 2010 Anders Ekdahl (http://coffeescripter.com/)
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ *
+ * Version: 1.2.4
+ *
+ * Demo and documentation: http://coffeescripter.com/code/ad-gallery/
+ */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(8($){$.3n.3o=8(b){5 c={2s:\'Z.3p\',1W:0,1X:q,11:0.7,2t:q,1b:3q,v:q,x:q,2u:B,2v:B,1Y:0,t:{1c:B,1Z:q,1d:3r,2w:\'3s\',2x:\'3t\',20:B,2y:\'(\',2z:\')\',2A:q,2B:q},2C:\'21-2D\',2E:B,1z:B,1A:{1e:q,2F:q,2G:q}};5 d=$.2H(q,c,b);4(b&&b.t){d.t=$.2H(q,c.t,b.t)};4(!d.t.1c){d.t.1Z=q};5 e=[];$(3).2I(8(){5 a=1B 22(3,d);e[e.J]=a});w e};8 2J(a,b,c){5 d=12(a.u(\'Q\'),10);4(b==\'C\'){5 e=\'-\'+3.D+\'z\';a.u(\'Q\',3.D+\'z\')}y{5 e=3.D+\'z\';a.u(\'Q\',\'-\'+3.D+\'z\')};4(c){c.u(\'1f\',\'-\'+c[0].1C+\'z\');c.13({1f:0},3.r.1b*2)};4(3.R){3.R.13({1f:\'-\'+3.R[0].1C+\'z\'},3.r.1b*2)};w{1g:{Q:e},1h:{Q:d}}};8 2K(a,b,c){5 d=12(a.u(\'C\'),10);4(b==\'C\'){5 e=\'-\'+3.K+\'z\';a.u(\'C\',3.K+\'z\')}y{5 e=3.K+\'z\';a.u(\'C\',\'-\'+3.K+\'z\')};4(c){c.u(\'1f\',\'-\'+c[0].1C+\'z\');c.13({1f:0},3.r.1b*2)};4(3.R){3.R.13({1f:\'-\'+3.R[0].1C+\'z\'},3.r.1b*2)};w{1g:{C:e},1h:{C:d}}};8 2L(a,b,c){5 d=a.v();5 e=a.x();5 f=12(a.u(\'C\'),10);5 g=12(a.u(\'Q\'),10);a.u({v:0,x:0,Q:3.D/2,C:3.K/2});w{1g:{v:0,x:0,Q:3.D/2,C:3.K/2},1h:{v:d,x:e,Q:g,C:f}}};8 2M(a,b,c){a.u(\'S\',0);w{1g:{S:0},1h:{S:1}}};8 2N(a,b,c){a.u(\'S\',0);w{1g:{S:0},1h:{S:1},1d:0}};8 22(a,b){3.1e(a,b)};22.2O={17:q,T:q,1D:q,V:q,Z:q,1r:q,N:q,1E:q,1F:q,1i:q,1j:q,t:q,K:0,D:0,O:0,18:q,R:q,1G:0,r:q,G:q,1k:q,1H:q,1e:8(b,c){5 d=3;3.17=$(b);3.r=c;3.2P();3.2Q();4(3.r.v){3.K=3.r.v;3.T.v(3.r.v);3.17.v(3.r.v)}y{3.K=3.T.v()};4(3.r.x){3.D=3.r.x;3.T.x(3.r.x)}y{3.D=3.T.x()};3.1G=3.V.v();3.O=0;3.18=q;3.R=q;3.1k=q;3.2R();4(3.r.2u){3.2S()};5 e=8(a){w d.1I(a)};3.t=1B 23(e,3.r.t);3.L.F(3.t.2T());4(3.r.t.1c){3.t.1c()}y{3.t.24()};4(3.r.2v){3.2U()};4(3.r.2E){3.2V()};5 f=12(3.r.1W,10);4(25.26.27&&25.26.27.3u(\'#s-W\')===0){f=25.26.27.2W(/[^0-9]+/g,\'\');4((f*1)!=f){f=3.r.1W}};3.1J(B);3.1s(f,8(){4(d.r.t.1Z){d.14(f+1);d.t.1t()}});3.P(3.r.1A.1e)},2Q:8(){3.1H={\'21-3v\':2J,\'21-2D\':2K,\'3w\':2L,\'3x\':2M,\'3y\':2N}},2P:8(){3.L=3.17.E(\'.s-L\');3.1D=$(\'<p H="s-3z"></p>\');3.L.F(3.1D);3.T=3.17.E(\'.s-W-17\');3.T.3A();3.V=3.17.E(\'.s-V\');3.N=3.V.E(\'.s-3B\');3.1r=$(\'<A H="s-1r"></A>\');3.Z=$(\'<19 H="s-Z" 1K="\'+3.r.2s+\'">\');3.T.F(3.Z);3.Z.15();$(1L.3C).F(3.1r)},1J:8(a){4(a){3.Z.1l()}y{3.Z.15()}},3D:8(a,b){4($.28(b)){3.1H[a]=b}},2R:8(){5 f=3;3.G=[];5 g=0;5 h=0;5 j=3.N.E(\'a\');5 k=j.J;4(3.r.11<1){j.E(\'19\').u(\'S\',3.r.11)};j.2I(8(i){5 a=$(3);5 b=a.I(\'2X\');5 c=a.E(\'19\');4(!f.29(c[0])){c.2Y(8(){g+=3.1u.1u.2a;h++})}y{g+=c[0].1u.1u.2a;h++};a.1M(\'s-1N\'+i);a.1v(8(){f.1s(i);f.t.M();w q}).2Z(8(){4(!$(3).1w(\'.s-1m\')&&f.r.11<1){$(3).E(\'19\').1O(1P,1)};f.14(i)},8(){4(!$(3).1w(\'.s-1m\')&&f.r.11<1){$(3).E(\'19\').1O(1P,f.r.11)}});5 a=q;4(c.1n(\'s-1x\')){a=c.1n(\'s-1x\')}y 4(c.I(\'2b\')&&c.I(\'2b\').J){a=c.I(\'2b\')};5 d=q;4(c.1n(\'s-1o\')){d=c.1n(\'s-1o\')}y 4(c.I(\'2c\')&&c.I(\'2c\').J){d=c.I(\'2c\')};5 e=q;4(c.1n(\'s-U\')){e=c.1n(\'s-U\')}y 4(c.I(\'U\')&&c.I(\'U\').J){e=c.I(\'U\')};f.G[i]={1N:c.I(\'1K\'),W:b,2d:q,1p:q,1o:d,U:e,1q:q,1x:a}});5 l=2e(8(){4(k==h){f.V.E(\'.s-1N-3E\').u(\'v\',g+\'z\');1Q(l)}},3F)},2V:8(){5 a=3;$(1L).31(8(e){4(e.2f==39){a.1I();a.t.M()}y 4(e.2f==37){a.2g();a.t.M()}})},2S:8(){3.1i=$(\'<A H="s-2h"><A H="s-2h-W"></A></A>\');3.1j=$(\'<A H="s-32"><A H="s-32-W"></A></A>\');3.T.F(3.1i);3.T.F(3.1j);5 a=3;3.1j.33(3.1i).3G(8(e){$(3).u(\'x\',a.D);$(3).E(\'A\').1l()}).3H(8(e){$(3).E(\'A\').15()}).1v(8(){4($(3).1w(\'.s-2h\')){a.1I();a.t.M()}y{a.2g();a.t.M()}}).E(\'A\').u(\'S\',0.7)},2U:8(){5 c=3;3.1F=$(\'<A H="s-2i"></A>\');3.1E=$(\'<A H="s-3I"></A>\');3.V.F(3.1F);3.V.34(3.1E);5 d=0;5 e=q;$(3.1E).33(3.1F).1v(8(){5 a=c.1G-3J;4(c.r.1Y>0){5 a=c.r.1Y};4($(3).1w(\'.s-2i\')){5 b=c.N.1a()+a}y{5 b=c.N.1a()-a};4(c.r.t.20){c.t.M()};c.N.13({1a:b+\'z\'});w q}).u(\'S\',0.6).2Z(8(){5 b=\'C\';4($(3).1w(\'.s-2i\')){b=\'2j\'};e=2e(8(){d++;4(d>30&&c.r.t.20){c.t.M()};5 a=c.N.1a()+1;4(b==\'C\'){a=c.N.1a()-1};c.N.1a(a)},10);$(3).u(\'S\',1)},8(){d=0;1Q(e);$(3).u(\'S\',0.6)})},2k:8(){3.1D.2l((3.O+1)+\' / \'+3.G.J);4(!3.r.1z){3.1j.1l().u(\'x\',3.D);3.1i.1l().u(\'x\',3.D);4(3.O==(3.G.J-1)){3.1i.15()};4(3.O==0){3.1j.15()}};3.P(3.r.1A.2F)},35:8(a,b){4(b>3.D){5 c=a/b;b=3.D;a=3.D*c};4(a>3.K){5 c=b/a;a=3.K;b=3.K*c};w{v:a,x:b}},36:8(a,b,c){a.u(\'Q\',\'38\');4(c<3.D){5 d=3.D-c;a.u(\'Q\',(d/2)+\'z\')};a.u(\'C\',\'38\');4(b<3.K){5 d=3.K-b;a.u(\'C\',(d/2)+\'z\')}},3a:8(a){5 b=q;4(a.1o.J||a.U.J){5 c=\'\';4(a.U.J){c=\'<3b H="s-3c-U">\'+a.U+\'</3b>\'};5 b=\'\';4(a.1o.J){b=\'<16>\'+a.1o+\'</16>\'};b=$(\'<p H="s-W-3c">\'+c+b+\'</p>\')};w b},1s:8(a,b){4(3.G[a]&&!3.1k){5 c=3;5 d=3.G[a];3.1k=B;4(!d.1p){3.1J(B);3.14(a,8(){c.1J(q);c.2m(a,b)})}y{3.2m(a,b)}}},2m:8(a,b){4(3.G[a]){5 c=3;5 d=3.G[a];5 e=$(1L.3K(\'A\')).1M(\'s-W\');5 f=$(1B 3d()).I(\'1K\',d.W);4(d.1x){5 g=$(\'<a 2X="\'+d.1x+\'" 3L="3M"></a>\');g.F(f);e.F(g)}y{e.F(f)}3.T.34(e);5 h=3.35(d.1q.v,d.1q.x);f.I(\'v\',h.v);f.I(\'x\',h.x);e.u({v:h.v+\'z\',x:h.x+\'z\'});3.36(e,h.v,h.x);5 i=3.3a(d,e);4(i){4(!3.r.1X){e.F(i);5 j=h.v-12(i.u(\'3e-C\'),10)-12(i.u(\'3e-2j\'),10);i.u(\'v\',j+\'z\')}y{3.r.1X.F(i)}};3.3f(3.V.E(\'.s-1N\'+a));5 k=\'2j\';4(3.O<a){k=\'C\'};3.P(3.r.1A.2G);4(3.18||3.r.2t){5 l=3.r.1b;5 m=\'3N\';5 n=3.1H[3.r.2C].2n(3,e,k,i);4(1R n.1d!=\'1S\'){l=n.1d};4(1R n.3g!=\'1S\'){m=n.3g};4(3.18){5 o=3.18;5 p=3.R;o.13(n.1g,l,m,8(){o.3h();4(p)p.3h()})};e.13(n.1h,l,m,8(){c.O=a;c.18=e;c.R=i;c.1k=q;c.2k();c.P(b)})}y{3.O=a;3.18=e;c.R=i;3.1k=q;c.2k();3.P(b)}}},3i:8(){4(3.O==(3.G.J-1)){4(!3.r.1z){w q};5 a=0}y{5 a=3.O+1};w a},1I:8(a){5 b=3.3i();4(b===q)w q;3.14(b+1);3.1s(b,a);w B},3j:8(){4(3.O==0){4(!3.r.1z){w q};5 a=3.G.J-1}y{5 a=3.O-1};w a},2g:8(a){5 b=3.3j();4(b===q)w q;3.14(b-1);3.1s(b,a);w B},3O:8(){5 a=3;5 i=0;8 2o(){4(i<a.G.J){i++;a.14(i,2o)}};a.14(i,2o)},14:8(a,b){4(3.G[a]){5 c=3.G[a];4(!3.G[a].1p){5 d=$(1B 3d());d.I(\'1K\',c.W);4(!3.29(d[0])){3.1r.F(d);5 e=3;d.2Y(8(){c.1p=B;c.1q={v:3.v,x:3.x};e.P(b)}).2d(8(){c.2d=B;c.1p=q;c.1q=q})}y{c.1p=B;c.1q={v:d[0].v,x:d[0].x};3.P(b)}}y{3.P(b)}}},29:8(a){4(1R a.3k!=\'1S\'&&!a.3k){w q};4(1R a.3l!=\'1S\'&&a.3l==0){w q};w B},3f:8(a){3.N.E(\'.s-1m\').3m(\'s-1m\');a.1M(\'s-1m\');4(3.r.11<1){3.N.E(\'a:3P(.s-1m) 19\').1O(1P,3.r.11);a.E(\'19\').1O(1P,1)};5 b=a[0].1u.3Q;b-=(3.1G/2)-(a[0].2a/2);3.N.13({1a:b+\'z\'})},P:8(a){4($.28(a)){a.2n(3)}}};8 23(a,b){3.1e(a,b)};23.2O={1T:q,1U:q,X:q,L:q,r:q,2p:q,1y:q,Y:q,1V:q,1e:8(a,b){5 c=3;3.2p=a;3.r=b},2T:8(){3.1T=$(\'<16 H="s-t-1t">\'+3.r.2w+\'</16>\');3.1U=$(\'<16 H="s-t-M">\'+3.r.2x+\'</16>\');3.X=$(\'<16 H="s-t-X"></16>\');3.L=$(\'<A H="s-t-L"></A>\');3.L.F(3.1T).F(3.1U).F(3.X);3.X.15();5 a=3;3.1T.1v(8(){a.1t()});3.1U.1v(8(){a.M()});$(1L).31(8(e){4(e.2f==3R){4(a.Y){a.M()}y{a.1t()}}});w 3.L},24:8(){3.1y=q;3.M();3.L.15()},1c:8(){3.1y=B;3.L.1l()},3S:8(){4(3.1y){3.24()}y{3.1c()}},1t:8(){4(3.Y||!3.1y)w q;5 a=3;3.Y=B;3.L.1M(\'s-t-Y\');3.2q();3.P(3.r.2A);w B},M:8(){4(!3.Y)w q;3.Y=q;3.X.15();3.L.3m(\'s-t-Y\');1Q(3.1V);3.P(3.r.2B);w B},2q:8(){5 c=3;5 d=3.r.2y;5 e=3.r.2z;1Q(c.1V);3.X.1l().2l(d+(3.r.1d/2r)+e);5 f=0;3.1V=2e(8(){f+=2r;4(f>=c.r.1d){5 a=8(){4(c.Y){c.2q()};f=0};4(!c.2p(a)){c.M()};f=0};5 b=12(c.X.3T().2W(/[^0-9]/g,\'\'),10);b--;4(b>0){c.X.2l(d+b+e)}},2r)},P:8(a){4($.28(a)){a.2n(3)}}}})(3U);',62,243,'|||this|if|var|||function||||||||||||||||||false|settings|ad|slideshow|css|width|return|height|else|px|div|true|left|image_wrapper_height|find|append|images|class|attr|length|image_wrapper_width|controls|stop|thumbs_wrapper|current_index|fireCallback|top|current_description|opacity|image_wrapper|title|nav|image|countdown|running|loader||thumb_opacity|parseInt|animate|preloadImage|hide|span|wrapper|current_image|img|scrollLeft|animation_speed|enable|speed|init|bottom|old_image|new_image|next_link|prev_link|in_transition|show|active|data|desc|preloaded|size|preloads|showImage|start|parentNode|click|is|link|enabled|cycle|callbacks|new|offsetHeight|gallery_info|scroll_back|scroll_forward|nav_display_width|animations|nextImage|loading|src|document|addClass|thumb|fadeTo|300|clearInterval|typeof|undefined|start_link|stop_link|countdown_interval|start_at_index|description_wrapper|scroll_jump|autostart|stop_on_scroll|slide|AdGallery|AdGallerySlideshow|disable|window|location|hash|isFunction|isImageLoaded|offsetWidth|longdesc|alt|error|setInterval|keyCode|prevImage|next|forward|right|_afterShow|html|_showWhenLoaded|call|preloadNext|nextimage_callback|_next|1000|loader_image|animate_first_image|display_next_and_prev|display_back_and_forward|start_label|stop_label|countdown_prefix|countdown_sufix|onStart|onStop|effect|hori|enable_keyboard_move|afterImageVisible|beforeImageVisible|extend|each|VerticalSlideAnimation|HorizontalSlideAnimation|ResizeAnimation|FadeAnimation|NoneAnimation|prototype|setupElements|setupAnimations|findImages|initNextAndPrev|create|initBackAndForward|initKeyEvents|replace|href|load|hover||keydown|prev|add|prepend|_getContainedImageSize|_centerImage||0px||_getDescription|strong|description|Image|padding|highLightThumb|easing|remove|nextIndex|prevIndex|complete|naturalWidth|removeClass|fn|adGallery|gif|400|5000|Start|Stop|indexOf|vert|resize|fade|none|info|empty|thumbs|body|addAnimation|list|100|mouseover|mouseout|back|50|createElement|target|_blank|swing|preloadAll|not|offsetLeft|83|toggle|text|jQuery'.split('|'),0,{}))
\ No newline at end of file
diff --git a/site/seagullgallery.css b/site/seagullgallery.css
new file mode 100644
index 0000000..d902bfa
--- /dev/null
+++ b/site/seagullgallery.css
@@ -0,0 +1,1147 @@
+/* Type view: images */
+.b-image {
+	width: 640px;
+	margin: 0 auto 50px auto;
+}
+.b-image__img {
+	width: 100%;
+	border-radius: 7px;
+}
+.b-image__title {
+	font-size: 16px;
+	display: block;
+}
+.b-image__desc {
+	color: #888;
+}
+
+/* Type view: image_and_thumbs */
+.ad-gallery {
+  width: 600px;
+}
+.ad-gallery, .ad-gallery * {
+	margin: 0;
+	padding: 0;
+}
+.ad-gallery .ad-image-wrapper {
+	width: 100%;
+	height: 400px;
+	margin-bottom: 10px;
+	position: relative;
+	overflow: hidden;
+}
+.ad-gallery .ad-image-wrapper .ad-loader {
+	position: absolute;
+	z-index: 10;
+	top: 48%;
+	left: 48%;
+	border: 1px solid #CCC;
+}
+.ad-gallery .ad-image-wrapper .ad-next {
+	position: absolute;
+	right: 0;
+	top: 0;
+	width: 25%;
+	height: 100%;
+	cursor: pointer;
+	display: block;
+	z-index: 100;
+}
+.ad-gallery .ad-image-wrapper .ad-prev {
+	position: absolute;
+	left: 0;
+	top: 0;
+	width: 25%;
+	height: 100%;
+	cursor: pointer;
+	display: block;
+	z-index: 100;
+}
+.ad-gallery .ad-image-wrapper .ad-prev, .ad-gallery .ad-image-wrapper .ad-next {
+/* Or else IE will hide it */
+	background: url(non-existing.jpg);
+}
+.ad-gallery .ad-image-wrapper .ad-prev .ad-prev-image, .ad-gallery .ad-image-wrapper .ad-next .ad-next-image {
+	background: url('images/ad_prev.png');
+	width: 30px;
+	height: 30px;
+	display: none;
+	position: absolute;
+	top: 47%;
+	left: 0;
+	z-index: 101;
+}
+.ad-gallery .ad-image-wrapper .ad-next .ad-next-image {
+	background: url('images/ad_next.png');
+	width: 30px;
+	height: 30px;
+	right: 0;
+	left: auto;
+}
+.ad-gallery .ad-image-wrapper .ad-image {
+	position: absolute;
+	overflow: hidden;
+	top: 0;
+	left: 0;
+	z-index: 9;
+}
+.ad-gallery .ad-image-wrapper .ad-image a img {
+	border: 0;
+}
+.ad-gallery .ad-image-wrapper .ad-image .ad-image-description {
+	position: absolute;
+	bottom: 0px;
+	left: 0px;
+	padding: 7px;
+	text-align: left;
+	width: 100%;
+	z-index: 2;
+	background: url(opa75.png);
+	color: #000;
+}
+* html .ad-gallery .ad-image-wrapper .ad-image .ad-image-description {
+	background: none;
+	filter:progid:DXImageTransform.Microsoft.AlphaImageLoader (enabled=true, sizingMethod=scale, src='images/opa75.png');
+}
+.ad-gallery .ad-image-wrapper .ad-image .ad-image-description .ad-description-title {
+	display: block;
+}
+.ad-gallery .ad-controls {
+	height: 20px;
+}
+.ad-gallery .ad-info {
+	float: left;
+}
+.ad-gallery .ad-slideshow-controls {
+	float: right;
+}
+.ad-gallery .ad-slideshow-controls .ad-slideshow-start, .ad-gallery .ad-slideshow-controls .ad-slideshow-stop {
+	padding-left: 5px;
+	cursor: pointer;
+}
+.ad-gallery .ad-slideshow-controls .ad-slideshow-countdown {
+	padding-left: 5px;
+	font-size: 0.9em;
+}
+.ad-gallery .ad-slideshow-running .ad-slideshow-start {
+	cursor: default;
+	font-style: italic;
+}
+.ad-gallery .ad-nav {
+	width: 100%;
+	position: relative;
+}
+.ad-gallery .ad-forward, .ad-gallery .ad-back {
+	position: absolute;
+	top: 0;
+	height: 100%;
+	z-index: 10;
+}
+/* IE 6 doesn't like height: 100% */
+* html .ad-gallery .ad-forward, .ad-gallery .ad-back {
+	height: 100px;
+}
+.ad-gallery .ad-back {
+	cursor: pointer;
+	left: -20px;
+	width: 13px;
+	display: block;
+	background: url('images/ad_scroll_back.png') 0px 22px no-repeat;
+}
+.ad-gallery .ad-forward {
+	cursor: pointer;
+	display: block;
+	right: -20px;
+	width: 13px;
+	background: url('images/ad_scroll_forward.png') 0px 22px no-repeat;
+}
+.ad-gallery .ad-nav .ad-thumbs {
+	overflow: hidden;
+	width: 100%;
+}
+.ad-gallery .ad-thumbs .ad-thumb-list {
+	float: left;
+	width: 9000px;
+	list-style: none;
+}
+.ad-gallery .ad-thumbs li {
+	float: left;
+	padding-right: 5px;
+}
+.ad-gallery .ad-thumbs li a {
+	display: block;
+}
+.ad-gallery .ad-thumbs li a img {
+	border: 3px solid #CCC;
+	display: block;
+}
+.ad-gallery .ad-thumbs li a.ad-active img {
+	border: 3px solid #616161;
+}
+/* Can't do display none, since Opera won't load the images then */
+.ad-preloads {
+	position: absolute;
+	left: -9000px;
+	top: -9000px;
+}
+
+/* Type view: thumbs */
+.b-thumb {
+	float: left;
+}
+
+/**
+* @file: highslide.css 
+* @version: 4.1.13
+*/
+.highslide-container div {
+	font-family: Verdana, Helvetica;
+	font-size: 10pt;
+}
+.highslide-container table {
+	background: none;
+	table-layout: auto;
+}
+.highslide {
+	outline: none;
+	text-decoration: none;
+}
+.highslide img {
+	border: 2px solid silver;
+}
+.highslide:hover img {
+	border-color: gray;
+}
+.highslide-active-anchor img {
+	visibility: hidden;
+}
+.highslide-gallery .highslide-active-anchor img {
+	border-color: black;
+	visibility: visible;
+	cursor: default;
+}
+.highslide-image {
+	border-width: 2px;
+	border-style: solid;
+	border-color: white;
+}
+.highslide-wrapper, .highslide-outline {
+	background: white;
+}
+.glossy-dark {
+	background: #111;
+}
+
+.highslide-image-blur {
+}
+.highslide-number {
+	font-weight: bold;
+	color: gray;
+	font-size: .9em;
+}
+.highslide-caption {
+	display: none;
+	font-size: 1em;
+	padding: 5px;
+	/*background: white;*/
+}
+.highslide-heading {
+	display: none;
+	font-weight: bold;
+	margin: 0.4em;
+}
+.highslide-dimming {
+	/*position: absolute;*/
+	background: black;
+}
+a.highslide-full-expand {
+   background: url(graphics/fullexpand.gif) no-repeat;
+   display: block;
+   margin: 0 10px 10px 0;
+   width: 34px;
+   height: 34px;
+}
+.highslide-loading {
+	display: block;
+	color: black;
+	font-size: 9px;
+	font-weight: bold;
+	text-transform: uppercase;
+	text-decoration: none;
+	padding: 3px;
+	border: 1px solid white;
+	background-color: white;
+	padding-left: 22px;
+	background-image: url(graphics/loader.white.gif);
+	background-repeat: no-repeat;
+	background-position: 3px 1px;
+}
+a.highslide-credits,
+a.highslide-credits i {
+	padding: 2px;
+	color: silver;
+	text-decoration: none;
+	font-size: 10px;
+}
+a.highslide-credits:hover,
+a.highslide-credits:hover i {
+	color: white;
+	background-color: gray;
+}
+.highslide-move, .highslide-move * {
+	cursor: move;
+}
+
+.highslide-viewport {
+	display: none;
+	position: fixed;
+	width: 100%;
+	height: 100%;
+	z-index: 1;
+	background: none;
+	left: 0;
+	top: 0;
+}
+.highslide-overlay {
+	display: none;
+}
+.hidden-container {
+	display: none;
+}
+/* Example of a semitransparent, offset closebutton */
+.closebutton {
+	position: relative;
+	top: -15px;
+	left: 15px;
+	width: 30px;
+	height: 30px;
+	cursor: pointer;
+	background: url(graphics/close.png);
+	/* NOTE! For IE6, you also need to update the highslide-ie6.css file. */
+}
+
+/*****************************************************************************/
+/* Thumbnail boxes for the galleries.                                        */
+/* Remove these if you are not using a gallery.                              */
+/*****************************************************************************/
+.highslide-gallery ul {
+	list-style-type: none;
+	margin: 0;
+	padding: 0;
+}
+.highslide-gallery ul li {
+	display: block;
+	position: relative;
+	float: left;
+	width: 106px;
+	height: 106px;
+	border: 1px solid silver;
+	background: #ededed;
+	margin: 2px;
+	padding: 0;
+	line-height: 0;
+	overflow: hidden;
+}
+.highslide-gallery ul a {
+	position: absolute;
+	top: 50%;
+	left: 50%;
+}
+.highslide-gallery ul img {
+ 	position: relative;
+	top: -50%;
+	left: -50%;
+}
+html>/**/body .highslide-gallery ul li {
+	display: table;
+	text-align: center;
+}
+html>/**/body .highslide-gallery ul li {
+	text-align: center;
+}
+html>/**/body .highslide-gallery ul a {
+	position: static;
+	display: table-cell;
+	vertical-align: middle;
+}
+html>/**/body .highslide-gallery ul img {
+	position: static;
+}
+
+/*****************************************************************************/
+/* Controls for the galleries.											     */
+/* Remove these if you are not using a gallery							     */
+/*****************************************************************************/
+.highslide-controls {
+	width: 195px;
+	height: 40px;
+	background: url(graphics/controlbar-white.gif) 0 -90px no-repeat;
+	margin: 20px 15px 10px 0;
+}
+.highslide-controls ul {
+	position: relative;
+	left: 15px;
+	height: 40px;
+	list-style: none;
+	margin: 0;
+	padding: 0;
+	background: url(graphics/controlbar-white.gif) right -90px no-repeat;
+
+}
+.highslide-controls li {
+	float: left;
+	padding: 5px 0;
+	margin:0;
+	list-style: none;
+}
+.highslide-controls a {
+	background-image: url(graphics/controlbar-white.gif);
+	display: block;
+	float: left;
+	height: 30px;
+	width: 30px;
+	outline: none;
+}
+.highslide-controls a.disabled {
+	cursor: default;
+}
+.highslide-controls a.disabled span {
+	cursor: default;
+}
+.highslide-controls a span {
+	/* hide the text for these graphic buttons */
+	display: none;
+	cursor: pointer;
+}
+
+
+/* The CSS sprites for the controlbar - see http://www.google.com/search?q=css+sprites */
+.highslide-controls .highslide-previous a {
+	background-position: 0 0;
+}
+.highslide-controls .highslide-previous a:hover {
+	background-position: 0 -30px;
+}
+.highslide-controls .highslide-previous a.disabled {
+	background-position: 0 -60px !important;
+}
+.highslide-controls .highslide-play a {
+	background-position: -30px 0;
+}
+.highslide-controls .highslide-play a:hover {
+	background-position: -30px -30px;
+}
+.highslide-controls .highslide-play a.disabled {
+	background-position: -30px -60px !important;
+}
+.highslide-controls .highslide-pause a {
+	background-position: -60px 0;
+}
+.highslide-controls .highslide-pause a:hover {
+	background-position: -60px -30px;
+}
+.highslide-controls .highslide-next a {
+	background-position: -90px 0;
+}
+.highslide-controls .highslide-next a:hover {
+	background-position: -90px -30px;
+}
+.highslide-controls .highslide-next a.disabled {
+	background-position: -90px -60px !important;
+}
+.highslide-controls .highslide-move a {
+	background-position: -120px 0;
+}
+.highslide-controls .highslide-move a:hover {
+	background-position: -120px -30px;
+}
+.highslide-controls .highslide-full-expand a {
+	background-position: -150px 0;
+}
+.highslide-controls .highslide-full-expand a:hover {
+	background-position: -150px -30px;
+}
+.highslide-controls .highslide-full-expand a.disabled {
+	background-position: -150px -60px !important;
+}
+.highslide-controls .highslide-close a {
+	background-position: -180px 0;
+}
+.highslide-controls .highslide-close a:hover {
+	background-position: -180px -30px;
+}
+
+/*****************************************************************************/
+/* Styles for the HTML popups											     */
+/* Remove these if you are not using Highslide HTML						     */
+/*****************************************************************************/
+.highslide-maincontent {
+	display: none;
+}
+.highslide-html {
+	background-color: white;
+}
+.mobile .highslide-html {
+	border: 1px solid silver;
+}
+.highslide-html-content {
+	display: none;
+	width: 400px;
+	padding: 0 5px 5px 5px;
+}
+.highslide-header {
+	padding-bottom: 5px;
+}
+.highslide-header ul {
+	margin: 0;
+	padding: 0;
+	text-align: right;
+}
+.highslide-header ul li {
+	display: inline;
+	padding-left: 1em;
+}
+.highslide-header ul li.highslide-previous, .highslide-header ul li.highslide-next {
+	display: none;
+}
+.highslide-header a {
+	font-weight: bold;
+	color: gray;
+	text-transform: uppercase;
+	text-decoration: none;
+}
+.highslide-header a:hover {
+	color: black;
+}
+.highslide-header .highslide-move a {
+	cursor: move;
+}
+.highslide-footer {
+	height: 16px;
+}
+.highslide-footer .highslide-resize {
+	display: block;
+	float: right;
+	margin-top: 5px;
+	height: 11px;
+	width: 11px;
+	background: url(graphics/resize.gif) no-repeat;
+}
+.highslide-footer .highslide-resize span {
+	display: none;
+}
+.highslide-body {
+}
+.highslide-resize {
+	cursor: nw-resize;
+}
+
+/*****************************************************************************/
+/* Styles for the Individual wrapper class names.							 */
+/* See www.highslide.com/ref/hs.wrapperClassName							 */
+/* You can safely remove the class name themes you don't use				 */
+/*****************************************************************************/
+
+/* hs.wrapperClassName = 'draggable-header' */
+.draggable-header .highslide-header {
+	height: 18px;
+	border-bottom: 1px solid #dddddd;
+}
+.draggable-header .highslide-heading {
+	position: absolute;
+	margin: 2px 0.4em;
+}
+
+.draggable-header .highslide-header .highslide-move {
+	cursor: move;
+	display: block;
+	height: 16px;
+	position: absolute;
+	right: 24px;
+	top: 0;
+	width: 100%;
+	z-index: 1;
+}
+.draggable-header .highslide-header .highslide-move * {
+	display: none;
+}
+.draggable-header .highslide-header .highslide-close {
+	position: absolute;
+	right: 2px;
+	top: 2px;
+	z-index: 5;
+	padding: 0;
+}
+.draggable-header .highslide-header .highslide-close a {
+	display: block;
+	height: 16px;
+	width: 16px;
+	background-image: url(graphics/closeX.png);
+}
+.draggable-header .highslide-header .highslide-close a:hover {
+	background-position: 0 16px;
+}
+.draggable-header .highslide-header .highslide-close span {
+	display: none;
+}
+.draggable-header .highslide-maincontent {
+	padding-top: 1em;
+}
+
+/* hs.wrapperClassName = 'titlebar' */
+.titlebar .highslide-header {
+	height: 18px;
+	border-bottom: 1px solid #dddddd;
+}
+.titlebar .highslide-heading {
+	position: absolute;
+	width: 90%;
+	margin: 1px 0 1px 5px;
+	color: #666666;
+}
+
+.titlebar .highslide-header .highslide-move {
+	cursor: move;
+	display: block;
+	height: 16px;
+	position: absolute;
+	right: 24px;
+	top: 0;
+	width: 100%;
+	z-index: 1;
+}
+.titlebar .highslide-header .highslide-move * {
+	display: none;
+}
+.titlebar .highslide-header li {
+	position: relative;
+	top: 3px;
+	z-index: 2;
+	padding: 0 0 0 1em;
+}
+.titlebar .highslide-maincontent {
+	padding-top: 1em;
+}
+
+/* hs.wrapperClassName = 'no-footer' */
+.no-footer .highslide-footer {
+	display: none;
+}
+
+/* hs.wrapperClassName = 'wide-border' */
+.wide-border {
+	background: white;
+}
+.wide-border .highslide-image {
+	border-width: 10px;
+}
+.wide-border .highslide-caption {
+	padding: 0 10px 10px 10px;
+}
+
+/* hs.wrapperClassName = 'borderless' */
+.borderless .highslide-image {
+	border: none;
+}
+.borderless .highslide-caption {
+	border-bottom: 1px solid white;
+	border-top: 1px solid white;
+	background: silver;
+}
+
+/* hs.wrapperClassName = 'outer-glow' */
+.outer-glow {
+	background: #444;
+}
+.outer-glow .highslide-image {
+	border: 5px solid #444444;
+}
+.outer-glow .highslide-caption {
+	border: 5px solid #444444;
+	border-top: none;
+	padding: 5px;
+	background-color: gray;
+}
+
+/* hs.wrapperClassName = 'colored-border' */
+.colored-border {
+	background: white;
+}
+.colored-border .highslide-image {
+	border: 2px solid green;
+}
+.colored-border .highslide-caption {
+	border: 2px solid green;
+	border-top: none;
+}
+
+/* hs.wrapperClassName = 'dark' */
+.dark {
+	background: #111;
+}
+.dark .highslide-image {
+	border-color: black black #202020 black;
+	background: gray;
+}
+.dark .highslide-caption {
+	color: white;
+	background: #111;
+}
+.dark .highslide-controls,
+.dark .highslide-controls ul,
+.dark .highslide-controls a {
+	background-image: url(graphics/controlbar-black-border.gif);
+}
+
+/* hs.wrapperClassName = 'floating-caption' */
+.floating-caption .highslide-caption {
+	position: absolute;
+	padding: 1em 0 0 0;
+	background: none;
+	color: white;
+	border: none;
+	font-weight: bold;
+}
+
+/* hs.wrapperClassName = 'controls-in-heading' */
+.controls-in-heading .highslide-heading {
+	color: gray;
+	font-weight: bold;
+	height: 20px;
+	overflow: hidden;
+	cursor: default;
+	padding: 0 0 0 22px;
+	margin: 0;
+	background: url(graphics/icon.gif) no-repeat 0 1px;
+}
+.controls-in-heading .highslide-controls {
+	width: 105px;
+	height: 20px;
+	position: relative;
+	margin: 0;
+	top: -23px;
+	left: 7px;
+	background: none;
+}
+.controls-in-heading .highslide-controls ul {
+	position: static;
+	height: 20px;
+	background: none;
+}
+.controls-in-heading .highslide-controls li {
+	padding: 0;
+}
+.controls-in-heading .highslide-controls a {
+	background-image: url(graphics/controlbar-white-small.gif);
+	height: 20px;
+	width: 20px;
+}
+
+.controls-in-heading .highslide-controls .highslide-move {
+	display: none;
+}
+
+.controls-in-heading .highslide-controls .highslide-previous a {
+	background-position: 0 0;
+}
+.controls-in-heading .highslide-controls .highslide-previous a:hover {
+	background-position: 0 -20px;
+}
+.controls-in-heading .highslide-controls .highslide-previous a.disabled {
+	background-position: 0 -40px !important;
+}
+.controls-in-heading .highslide-controls .highslide-play a {
+	background-position: -20px 0;
+}
+.controls-in-heading .highslide-controls .highslide-play a:hover {
+	background-position: -20px -20px;
+}
+.controls-in-heading .highslide-controls .highslide-play a.disabled {
+	background-position: -20px -40px !important;
+}
+.controls-in-heading .highslide-controls .highslide-pause a {
+	background-position: -40px 0;
+}
+.controls-in-heading .highslide-controls .highslide-pause a:hover {
+	background-position: -40px -20px;
+}
+.controls-in-heading .highslide-controls .highslide-next a {
+	background-position: -60px 0;
+}
+.controls-in-heading .highslide-controls .highslide-next a:hover {
+	background-position: -60px -20px;
+}
+.controls-in-heading .highslide-controls .highslide-next a.disabled {
+	background-position: -60px -40px !important;
+}
+.controls-in-heading .highslide-controls .highslide-full-expand a {
+	background-position: -100px 0;
+}
+.controls-in-heading .highslide-controls .highslide-full-expand a:hover {
+	background-position: -100px -20px;
+}
+.controls-in-heading .highslide-controls .highslide-full-expand a.disabled {
+	background-position: -100px -40px !important;
+}
+.controls-in-heading .highslide-controls .highslide-close a {
+	background-position: -120px 0;
+}
+.controls-in-heading .highslide-controls .highslide-close a:hover {
+	background-position: -120px -20px;
+}
+
+/*****************************************************************************/
+/* Styles for text based controls.						                     */
+/* You can safely remove this if you don't use text based controls			 */
+/*****************************************************************************/
+
+.text-controls .highslide-controls {
+	width: auto;
+	height: auto;
+	margin: 0;
+	text-align: center;
+	background: none;
+}
+.text-controls ul {
+	position: static;
+	background: none;
+	height: auto;
+	left: 0;
+}
+.text-controls .highslide-move {
+	display: none;
+}
+.text-controls li {
+    background-image: url(graphics/controlbar-text-buttons.png);
+	background-position: right top !important;
+	padding: 0;
+	margin-left: 15px;
+	display: block;
+	width: auto;
+}
+.text-controls a {
+    background: url(graphics/controlbar-text-buttons.png) no-repeat;
+    background-position: left top !important;
+    position: relative;
+    left: -10px;
+	display: block;
+	width: auto;
+	height: auto;
+	text-decoration: none !important;
+}
+.text-controls a span {
+	background: url(graphics/controlbar-text-buttons.png) no-repeat;
+    margin: 1px 2px 1px 10px;
+	display: block;
+    min-width: 4em;
+    height: 18px;
+    line-height: 18px;
+	padding: 1px 0 1px 18px;
+    color: #333;
+	font-family: "Trebuchet MS", Arial, sans-serif;
+	font-size: 12px;
+	font-weight: bold;
+	white-space: nowrap;
+}
+.text-controls .highslide-next {
+	margin-right: 1em;
+}
+.text-controls .highslide-full-expand a span {
+	min-width: 0;
+	margin: 1px 0;
+	padding: 1px 0 1px 10px;
+}
+.text-controls .highslide-close a span {
+	min-width: 0;
+}
+.text-controls a:hover span {
+	color: black;
+}
+.text-controls a.disabled span {
+	color: #999;
+}
+
+.text-controls .highslide-previous span {
+	background-position: 0 -40px;
+}
+.text-controls .highslide-previous a.disabled {
+	background-position: left top !important;
+}
+.text-controls .highslide-previous a.disabled span {
+	background-position: 0 -140px;
+}
+.text-controls .highslide-play span {
+	background-position: 0 -60px;
+}
+.text-controls .highslide-play a.disabled {
+	background-position: left top !important;
+}
+.text-controls .highslide-play a.disabled span {
+	background-position: 0 -160px;
+}
+.text-controls .highslide-pause span {
+	background-position: 0 -80px;
+}
+.text-controls .highslide-next span {
+	background-position: 0 -100px;
+}
+.text-controls .highslide-next a.disabled {
+	background-position: left top !important;
+}
+.text-controls .highslide-next a.disabled span {
+	background-position: 0 -200px;
+}
+.text-controls .highslide-full-expand span {
+	background: none;
+}
+.text-controls .highslide-full-expand a.disabled {
+	background-position: left top !important;
+}
+.text-controls .highslide-close span {
+	background-position: 0 -120px;
+}
+
+
+/*****************************************************************************/
+/* Styles for the thumbstrip.							                     */
+/* See www.highslide.com/ref/hs.addSlideshow    							 */
+/* You can safely remove this if you don't use a thumbstrip 				 */
+/*****************************************************************************/
+
+.highslide-thumbstrip {
+	height: 100%;
+	direction: ltr;
+}
+.highslide-thumbstrip div {
+	overflow: hidden;
+}
+.highslide-thumbstrip table {
+	position: relative;
+	padding: 0;
+	border-collapse: collapse;
+}
+.highslide-thumbstrip td {
+	padding: 1px;
+	/*text-align: center;*/
+}
+.highslide-thumbstrip a {
+	outline: none;
+}
+.highslide-thumbstrip img {
+	display: block;
+	border: 1px solid gray;
+	margin: 0 auto;
+}
+.highslide-thumbstrip .highslide-active-anchor img {
+	visibility: visible;
+}
+.highslide-thumbstrip .highslide-marker {
+	position: absolute;
+	width: 0;
+	height: 0;
+	border-width: 0;
+	border-style: solid;
+	border-color: transparent; /* change this to actual background color in highslide-ie6.css */
+}
+.highslide-thumbstrip-horizontal div {
+	width: auto;
+	/* width: 100% breaks in small strips in IE */
+}
+.highslide-thumbstrip-horizontal .highslide-scroll-up {
+	display: none;
+	position: absolute;
+	top: 3px;
+	left: 3px;
+	width: 25px;
+	height: 42px;
+}
+.highslide-thumbstrip-horizontal .highslide-scroll-up div {
+	margin-bottom: 10px;
+	cursor: pointer;
+	background: url(graphics/scrollarrows.png) left center no-repeat;
+	height: 42px;
+}
+.highslide-thumbstrip-horizontal .highslide-scroll-down {
+	display: none;
+	position: absolute;
+	top: 3px;
+	right: 3px;
+	width: 25px;
+	height: 42px;
+}
+.highslide-thumbstrip-horizontal .highslide-scroll-down div {
+	margin-bottom: 10px;
+	cursor: pointer;
+	background: url(graphics/scrollarrows.png) center right no-repeat;
+	height: 42px;
+}
+.highslide-thumbstrip-horizontal table {
+	margin: 2px 0 10px 0;
+}
+.highslide-viewport .highslide-thumbstrip-horizontal table {
+	margin-left: 10px;
+}
+.highslide-thumbstrip-horizontal img {
+	width: auto;
+	height: 40px;
+}
+.highslide-thumbstrip-horizontal .highslide-marker {
+	top: 47px;
+	border-left-width: 6px;
+	border-right-width: 6px;
+	border-bottom: 6px solid gray;
+}
+.highslide-viewport .highslide-thumbstrip-horizontal .highslide-marker {
+	margin-left: 10px;
+}
+.dark .highslide-thumbstrip-horizontal .highslide-marker, .highslide-viewport .highslide-thumbstrip-horizontal .highslide-marker {
+	border-bottom-color: white !important;
+}
+
+.highslide-thumbstrip-vertical-overlay {
+	overflow: hidden !important;
+}
+.highslide-thumbstrip-vertical div {
+	height: 100%;
+}
+.highslide-thumbstrip-vertical a {
+	display: block;
+}
+.highslide-thumbstrip-vertical .highslide-scroll-up {
+	display: none;
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 25px;
+}
+.highslide-thumbstrip-vertical .highslide-scroll-up div {
+	margin-left: 10px;
+	cursor: pointer;
+	background: url(graphics/scrollarrows.png) top center no-repeat;
+	height: 25px;
+}
+.highslide-thumbstrip-vertical .highslide-scroll-down {
+	display: none;
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	width: 100%;
+	height: 25px;
+}
+.highslide-thumbstrip-vertical .highslide-scroll-down div {
+	margin-left: 10px;
+	cursor: pointer;
+	background: url(graphics/scrollarrows.png) bottom center no-repeat;
+	height: 25px;
+}
+.highslide-thumbstrip-vertical table {
+	margin: 10px 0 0 10px;
+}
+.highslide-thumbstrip-vertical img {
+	width: 60px; /* t=5481 */
+}
+.highslide-thumbstrip-vertical .highslide-marker {
+	left: 0;
+	margin-top: 8px;
+	border-top-width: 6px;
+	border-bottom-width: 6px;
+	border-left: 6px solid gray;
+}
+.dark .highslide-thumbstrip-vertical .highslide-marker, .highslide-viewport .highslide-thumbstrip-vertical .highslide-marker {
+	border-left-color: white;
+}
+
+.highslide-viewport .highslide-thumbstrip-float {
+	overflow: auto;
+}
+.highslide-thumbstrip-float ul {
+	margin: 2px 0;
+	padding: 0;
+}
+.highslide-thumbstrip-float li {
+	display: block;
+	height: 60px;
+	margin: 0 2px;
+	list-style: none;
+	float: left;
+}
+.highslide-thumbstrip-float img {
+	display: inline;
+	border-color: silver;
+	max-height: 56px;
+}
+.highslide-thumbstrip-float .highslide-active-anchor img {
+	border-color: black;
+}
+.highslide-thumbstrip-float .highslide-scroll-up div, .highslide-thumbstrip-float .highslide-scroll-down div {
+	display: none;
+}
+.highslide-thumbstrip-float .highslide-marker {
+	display: none;
+}
+
+
+/*****************************************************************************/
+/* The following styles are added by the Highslide Editor                    */
+/*****************************************************************************/
+.highslide-wrapper, .highslide-outline {
+	background: #111111;
+}
+.highslide img {
+	border: 1px solid #D0D0D0;
+}
+.highslide:hover img {
+	border-color: #A0A0A0;
+}
+.highslide-active-anchor img {
+	visibility: visible;
+	border-color: #808080 !important;
+}
+.highslide-dimming {
+	background: #000000;
+}
+.highslide-image {
+	border: none;
+}
+.highslide-caption {
+	position: absolute;
+	width: 100%;
+	color: #FFFFFF;
+	font-weight: bold;
+	padding: 5px;
+	padding-right: 0px;
+	padding-bottom: 0px;
+	padding-left: 0px;
+}
+.highslide-loading {
+	color: black;
+	border: 1px solid black;
+	background-color: white;
+	background-image: url(graphics/loader.white.gif);
+}
+
+.highslide-controls {
+	position: static !important;
+	margin-bottom: 0;
+	width: 135px !important;
+}
+.large-dark .highslide-controls, .large-dark .highslide-controls ul, .large-dark .highslide-controls a {
+	background-image: url(graphics/controlbar-black-border.gif);
+}
+.highslide-controls .highslide-play {
+	display: none;
+}
+.highslide-controls .highslide-pause {
+	display: none;
+}
+.highslide-controls .highslide-move {
+	display: none;
+}
+.highslide-gallery ul li {
+	width: 106px;
+	height: 106px;
+	border: 1px solid #D0D0D0;
+	background: #EDEDED;
+	margin: 2px;
+}
\ No newline at end of file
diff --git a/templates/addgallery.html b/templates/addgallery.html
new file mode 100644
index 0000000..48bf114
--- /dev/null
+++ b/templates/addgallery.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>[+title+]</title>
+	[+css+]
+	<link rel="stylesheet" href="../assets/plugins/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/ui.css">
+</head>
+<body>
+	<h1>[+title+]</h1>
+	<div id="js-msg" class="msg [+msgType+]"><div class="msg__text">[+msg+]</div></div>
+	<form id="f-add-gallery" style="padding:10px;" name="module" method="post">
+		[+form_gallery+]
+		<input name="cmd" type="hidden" value="addGallery" />
+		<input name="gid" type="hidden" value="[+row_id+]" />
+	</form>
+
+	<ul class="actionButtons" style="margin-left: 10px;">
+		<li id="addNews"><a href="#" onclick="$('#f-add-gallery').submit(); return false;">Сохранить</a></li>
+		<li id="addNews"><a href="#" onclick="postForm(); return false;">Отменить</a></li>
+	</ul>
+	[+js+]
+	<script type="text/javascript" src="../assets/modules/[+nameModule+]/js/[+nameModule+]_config.js"></script>
+	<script type="text/javascript" src="../assets/modules/seagulllibrary/js/jpicker-1.1.6.min.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/templates/config.html b/templates/config.html
new file mode 100644
index 0000000..49dd5a6
--- /dev/null
+++ b/templates/config.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>[+title+]</title>
+	[+css+]
+	<link rel="stylesheet" type="text/css" href="../assets/modules/seagulllibrary/css/jPicker-1.1.6.min.css" />
+</head>
+<body>
+	<div id="js-msg" class="msg [+msgType+]"><div class="msg__text">[+msg+]</div></div>
+	<h1>[+title+]</h1>
+	<ul class="actionButtons" style="right: 0pt; top: 10px;">
+		<li><a href="#" onclick="postForm(); return false;"><img alt="icons_delete_document" src="/assets/modules/seagulllibrary/css/images/back.png" /> назад</a></li>
+		<li><a href="#" onclick="$('#f-config').submit(); return false;"><img src="media/style/MODxCarbon/images/icons/save.png" alt="icons_save" /> Сохранить</a></li>
+		<li><a id="btn-clear-tables" href="#"><img alt="icons_delete_document" src="media/style/MODxCarbon/images/icons/delete.png" /> Очистить все таблицы</a></li>
+	</ul>
+
+	<form id="f-config" class="b-form" method="post">
+		[+config+]
+		<ul class="actionButtons" style="right: 0pt; top: 10px;">
+			<li><a href="#" onclick="postForm(); return false;"><img alt="icons_delete_document" src="/assets/modules/seagulllibrary/css/images/back.png" /> назад</a></li>
+			<li><a href="#" onclick="$('#f-config').submit(); return false;"><img src="media/style/MODxCarbon/images/icons/save.png" alt="icons_save" /> Сохранить</a></li>
+		</ul>
+	</form>
+	<a id="create-variable" style="margin:7px 0 0 10px; float:right" href="#" onclick="return false;">Добавить переменную</a>
+
+	<form name="module" method="post">
+		<input name="cmd" type="hidden" value="" />
+		<input name="itemID" type="hidden" value="" />
+	</form>
+	[+addvariable+]
+	[+js+]
+	<script type="text/javascript" src="../assets/modules/[+nameModule+]/js/[+nameModule+]_config.js"></script>
+	<script type="text/javascript" src="../assets/modules/seagulllibrary/js/jpicker-1.1.6.min.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/templates/configgallery.html b/templates/configgallery.html
new file mode 100644
index 0000000..5dcb1ae
--- /dev/null
+++ b/templates/configgallery.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>[+title+]</title>
+	[+css+]
+	<link rel="stylesheet" type="text/css" href="../assets/modules/seagulllibrary/css/jPicker-1.1.6.min.css" />
+</head>
+<body>
+	<div id="js-msg" class="msg [+msgType+]"><div class="msg__text">[+msg+]</div></div>
+	<h1><a href="#" onclick="postForm(); return false;">[+title+]</a> > <a href="#" onclick="postForm('editGallery'); return false;">Галерея #[+gallery_id+]</a> > Настройки</h1>
+	<ul class="actionButtons" style="right: 0pt; top: 10px;">
+		<li><a href="#" onclick="postForm('editGallery'); return false;"><img alt="icons_delete_document" src="/assets/modules/seagulllibrary/css/images/back.png" /> назад</a></li>
+		<li><a href="#" onclick="$('#f-gallery-config').submit(); return false;"><img src="media/style/MODxCarbon/images/icons/save.png" alt="icons_save" /> Сохранить настройки</a></li>
+		<li><a id="btn-resize-thumbs" href="#"><img src="media/style/MODxCarbon/images/icons/save.png" alt="icons_save" /> Пересчитать миниатюры</a></li>
+	</ul>
+	<form id="f-gallery-config" class="ajaxform" method="post">
+		[+form_gallery+]
+		<input name="itemID" type="hidden" value="[+gallery_id+]" />
+	</form>
+	<form name="module" method="post">
+		<input name="cmd" type="hidden" value="" />
+		<input id="ff-gid" name="itemID" type="hidden" value="[+gallery_id+]" />
+	</form>
+
+	<a id="create-variable" style="margin:7px 0 0 10px; float:right" href="#" onclick="return false;">Добавить переменную</a>
+
+	[+addvariable+]
+	[+js+]
+	<script type="text/javascript" src="../assets/modules/[+nameModule+]/js/[+nameModule+]_config.js"></script>
+	<script type="text/javascript" src="../assets/modules/seagulllibrary/js/jpicker-1.1.6.min.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/templates/editgallery.html b/templates/editgallery.html
new file mode 100644
index 0000000..9a3ba15
--- /dev/null
+++ b/templates/editgallery.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>[+title+]</title>
+	[+css+]
+</head>
+<body>
+	<div id="js-msg" class="msg [+msgType+]"><div class="msg__text">[+msg+]</div></div>
+	<h1><a href="#" onclick="postForm(); return false;">[+title+]</a> > Галерея #[+gallery_id+]</h1>
+	[+paginator_links+]
+	<ul class="actionButtons">
+		<li><a href="#" onclick="postForm(); return false;"><img alt="icons_delete_document" src="/assets/modules/seagulllibrary/css/images/back.png" /> назад</a></li>
+		<li class="actionButtons-left"><a id="btn-add-imgs" href="#"><img src="media/style[+theme+]/images/icons/add.png" /> Добавить изображения</a></li>
+		<li class="actionButtons-right"><a id="btn-del-imgs" href="#"><img alt="icons_delete_document" src="media/style/MODxCarbon/images/icons/delete.png" /> Удалить изображения</a></li>
+		<li class="actionButtons-left"><a href="#" onclick="postForm('configGallery'); return false;"><img src="../assets/modules/seagulllibrary/css/images/config.png" /> Настройки</a></li>
+		<li class="actionButtons-right"><a href="#" onclick="ajaxDel('delGallery', [+gallery_id+]); return false;"><img alt="icons_delete_document" src="media/style/MODxCarbon/images/icons/delete.png" /> Удалить галерею</a></li>
+	</ul>
+
+	<form id="f-upload" action="" method="post" enctype="multipart/form-data">
+		<input id="btn-selectfiles" style="position:absolute; z-index:-10" type="file" name="imgs[]" multiple />
+		<input type="hidden" name="cmd" value="addimgs" />
+		<input type="hidden" name="itemID" value="[+gallery_id+]" />
+	</form>
+	<div class="b-progress">
+		<div class="b-progress__bar"></div>
+		<div class="b-progress__percent">0%</div>
+	</div>
+	<div id="status"></div>
+
+	<form id="f-imgs-form" class="ajaxform" action="/assets/modules/[+nameModule+]/ajax.php" method="post">
+		[+images_list+]
+	</form>
+	[+paginator_links+]
+	<div id="form-container" style="display:none">
+		<form id="f-image" method="post" enctype="multipart/form-data">
+			<p>
+				<label style="display:inline-block;width:60px;">ID изобр.</label>
+				<input type="text" name="id" id="ff-img-id" readonly="readonly" />
+			</p>
+			<p>
+				<label style="display:inline-block;width:60px;" for="ff-img-title">Название</label>
+				<input type="text" name="title" id="ff-img-title" style="width:70%" />
+			</p>
+			<p>
+				<label style="display:inline-block;width:60px;" for="ff-img-description">Описание</label>
+				<textarea type="text" name="description" id="ff-img-description" style="width:70%"></textarea>
+			</p>
+			<p>
+				<label for="ff-img-file">Заменить изображение</label>
+				<input type="file" name="imgfile" id="ff-img-file" class="w100" />
+			</p>
+			<p>
+				<input type="hidden" name="cmd" value="saveimg" />
+				<input style="margin-left:60px" class="btn" type="submit" value="Сохранить" />
+				<input class="btn btn-cancel" type="button" value="Закрыть" />
+			</p>
+		</form>
+	</div>
+	<form name="module" method="post">
+		<input name="cmd" type="hidden" value="" />
+		<input id="ff-gid" name="itemID" type="hidden" value="[+gallery_id+]" />
+	</form>
+	[+js+]
+	<script type="text/javascript" src="../assets/modules/seagulllibrary/js/jquery.tablednd-0.5.1.js"></script>
+	<script type="text/javascript" src="../assets/modules/[+nameModule+]/js/[+nameModule+]_images.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/templates/fileuploader.css b/templates/fileuploader.css
new file mode 100644
index 0000000..5109592
--- /dev/null
+++ b/templates/fileuploader.css
@@ -0,0 +1,31 @@
+.qq-uploader { position:relative; width: 400px;}
+
+.qq-upload-button {
+    display:block; /* or inline-block */
+    width: 105px; padding: 7px 0; text-align:center;    
+    background:#880000; border-bottom:1px solid #ddd;color:#fff;
+}
+.qq-upload-button-hover {background:#cc0000;}
+.qq-upload-button-focus {outline:1px dotted black;}
+
+.qq-upload-drop-area {
+    position:absolute; top:0; left:0; width:100%; height:100%; min-height: 70px; z-index:2;
+    background:#FF9797; text-align:center; 
+}
+.qq-upload-drop-area span {
+    display:block; position:absolute; top: 50%; width:100%; margin-top:-8px; font-size:16px;
+}
+.qq-upload-drop-area-active {background:#FF7171;}
+
+.qq-upload-list {margin:15px 35px; padding:0; list-style:disc;}
+.qq-upload-list li { margin:0; padding:0; line-height:15px; font-size:12px;}
+.qq-upload-file, .qq-upload-spinner, .qq-upload-size, .qq-upload-cancel, .qq-upload-failed-text {
+    margin-right: 7px;
+}
+
+.qq-upload-file {}
+.qq-upload-spinner {display:inline-block; background: url("loading.gif"); width:15px; height:15px; vertical-align:text-bottom;}
+.qq-upload-size,.qq-upload-cancel {font-size:11px;}
+
+.qq-upload-failed-text {display:none;}
+.qq-upload-fail .qq-upload-failed-text {display:inline;}
\ No newline at end of file
diff --git a/templates/frontend/img.html b/templates/frontend/img.html
new file mode 100644
index 0000000..15821d2
--- /dev/null
+++ b/templates/frontend/img.html
@@ -0,0 +1 @@
+<a class="gallery__img" rel="gallery[+gallery_id+]" href="[+path+]" title="[+title+]"><img [+html_param+] src="[+path_thumb+]" alt="[+description+]" /></a>
\ No newline at end of file
diff --git a/templates/frontend/img_desc_bottom.html b/templates/frontend/img_desc_bottom.html
new file mode 100644
index 0000000..c66a929
--- /dev/null
+++ b/templates/frontend/img_desc_bottom.html
@@ -0,0 +1 @@
+<div class="thumb"><a class="gallery__img" href="[+path+]" title="[+title+]"><img [+html_param+] src="[+path_thumb+]" alt="[+description+]" /></a><div class="thumb__desc[+desc_align+]">[+description+]</div></div>
\ No newline at end of file
diff --git a/templates/frontend/img_desc_top.html b/templates/frontend/img_desc_top.html
new file mode 100644
index 0000000..ec4a899
--- /dev/null
+++ b/templates/frontend/img_desc_top.html
@@ -0,0 +1 @@
+<div class="thumb"><div class="thumb__desc[+desc_align+]">[+description+]</div><a class="gallery__img" href="[+path+]" title="[+title+]"><img [+html_param+] src="[+path_thumb+]" alt="[+description+]" /></a></div>
\ No newline at end of file
diff --git a/templates/frontend/img_highslide.html b/templates/frontend/img_highslide.html
new file mode 100644
index 0000000..a7cbd9f
--- /dev/null
+++ b/templates/frontend/img_highslide.html
@@ -0,0 +1 @@
+<a class="highslide" href="[+path+]" onclick="return hs.expand(this,{slideshowGroup:'gal[+gallery_id+]'})" title="[+title+]"><img [+html_param+] src="[+path_thumb+]" alt="[+description+]" /></a>
\ No newline at end of file
diff --git a/templates/install.html b/templates/install.html
new file mode 100644
index 0000000..330681f
--- /dev/null
+++ b/templates/install.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>[+title+]</title>
+	[+css+]
+</head>
+<body>
+	<h1>[+title+]</h1>
+<!--	<div id="js-msg" class="msg [+msgType+]"><div class="msg__text">[+msg+]</div></div>-->
+	<ul class="actionButtons" style="position: absolute; right: 0pt; top: 10px;">
+		<li id="installModule"><a href="#" onclick="postForm('install'); return false;">Установить модуль</a></li>
+		<li><a href="#" onclick="postForm(); return false;">Назад</a></li>
+	</ul>
+	<div>[+msg+]</div>
+	<form name="module" method="post">
+		<input name="cmd" type="hidden" value="" />
+		<input name="itemID" type="hidden" value="" />
+	</form>
+	[+js+]
+	<script type="text/javascript" src="/assets/modules/[+nameModule+]/js/[+nameModule+].js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/templates/jPicker-1.1.6.min.css b/templates/jPicker-1.1.6.min.css
new file mode 100644
index 0000000..c131616
--- /dev/null
+++ b/templates/jPicker-1.1.6.min.css
@@ -0,0 +1 @@
+.jPicker .Icon{display:inline-block;height:24px;position:relative;text-align:left;width:25px}.jPicker .Icon span.Color,.jPicker .Icon span.Alpha{background-position:2px 2px;display:block;height:100%;left:0;position:absolute;top:0;width:100%}.jPicker .Icon span.Image{background-repeat:no-repeat;cursor:pointer;display:block;height:100%;left:0;position:absolute;top:0;width:100%}.jPicker.Container{color:#000;z-index:10}table.jPicker{background-color:#efefef;border:1px outset #666;font-family:Arial,Helvetica,Sans-Serif;font-size:12px!important;margin:0;padding:5px;width:545px;z-index:20}.jPicker .Move{background-color:#ddd;border-color:#fff #666 #666 #fff;border-style:solid;border-width:1px;cursor:move;height:12px;padding:0}.jPicker .Title{font-size:11px!important;font-weight:bold;margin:-2px 0 0 0;padding:10px 0 0 0;text-align:center;width:100%}.jPicker div.Map{border-bottom:2px solid #fff;border-left:2px solid #9a9a9a;border-right:2px solid #fff;border-top:2px solid #9a9a9a;cursor:crosshair;height:260px;margin:0 10px 10px 10px;overflow:hidden;padding:0;position:relative;width:260px}.jPicker div[class="Map"]{height:256px;width:256px}.jPicker div.Bar{border-bottom:2px solid #fff;border-left:2px solid #9a9a9a;border-right:2px solid #fff;border-top:2px solid #9a9a9a;cursor:n-resize;height:260px;margin:12px 10px 0 5px;overflow:hidden;padding:0;position:relative;width:24px}.jPicker div[class="Bar"]{height:256px;width:20px}.jPicker .Map .Map1,.jPicker .Map .Map2,.jPicker .Map .Map3,.jPicker .Bar .Map1,.jPicker .Bar .Map2,.jPicker .Bar .Map3,.jPicker .Bar .Map4,.jPicker .Bar .Map5,.jPicker .Bar .Map6{background-color:transparent;background-image:none;display:block;left:0;position:absolute;top:0}.jPicker .Map .Map1,.jPicker .Map .Map2,.jPicker .Map .Map3{height:2596px;width:256px}.jPicker .Bar .Map1,.jPicker .Bar .Map2,.jPicker .Bar .Map3,.jPicker .Bar .Map4{height:3896px;width:20px}.jPicker .Bar .Map5,.jPicker .Bar .Map6{height:256px;width:20px}.jPicker .Map .Map1,.jPicker .Map .Map2,.jPicker .Bar .Map6{background-repeat:no-repeat}.jPicker .Map .Map3,.jPicker .Bar .Map5{background-repeat:repeat}.jPicker .Bar .Map1,.jPicker .Bar .Map2,.jPicker .Bar .Map3,.jPicker .Bar .Map4{background-repeat:repeat-x}.jPicker .Map .Arrow{display:block;position:absolute}.jPicker .Bar .Arrow{display:block;left:0;position:absolute}.jPicker .Preview{font-size:9px;padding:5px 0 0 0;text-align:center}.jPicker .Preview div{border:2px inset #eee;height:62px;margin:0 auto;padding:0;width:62px}.jPicker .Preview div span{border:1px solid #000;display:block;height:30px;margin:0 auto;padding:0;width:60px}.jPicker .Preview .Active{border-bottom-width:0}.jPicker .Preview .Current{border-top-width:0;cursor:pointer}.jPicker input{font-size:13px}.jPicker .Button{text-align:center;padding:0 4px;width:115px}.jPicker .Button input{padding:2px 0;width:100px}.jPicker .Button .Ok{margin:12px 0 5px 0}.jPicker td{margin:0;padding:0}.jPicker td.Radio{margin:0;padding:0;width:31px}.jPicker td.Radio input{margin:0 5px 0 0;padding:0}.jPicker td.Text{font-size:12px!important;height:22px;margin:0;padding:0;text-align:left;width:70px}.jPicker tr.Hex td.Text{width:100px}.jPicker td.Text input{background-color:#fff;border:1px inset #aaa;height:19px;margin:0 0 0 5px;text-align:left;width:30px}.jPicker td[class="Text"] input{height:15px}.jPicker tr.Hex td.Text input.Hex{width:50px}.jPicker tr.Hex td.Text input.AHex{width:20px}.jPicker .Grid{text-align:center;width:114px}.jPicker .Grid span.QuickColor{border:1px inset #aaa;cursor:pointer;display:inline-block;height:15px;line-height:15px;margin:0;padding:0;width:19px}.jPicker .Grid span[class="QuickColor"]{width:17px}
\ No newline at end of file
diff --git a/templates/main.html b/templates/main.html
new file mode 100644
index 0000000..0368d6c
--- /dev/null
+++ b/templates/main.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>[+title+]</title>
+	[+css+]
+</head>
+<body>
+	<h1>[+title+]</h1>
+	<div id="js-msg" class="msg [+msgType+]"><div class="msg__text">[+msg+]</div></div>
+	<ul class="actionButtons" style="position: absolute; right: 0pt; top: 10px;">
+		<li id="installModule"><a href="#" onclick="postForm('install'); return false;">Установить модуль</a></li>
+	</ul>
+	[+paginator_links+]
+	<ul class="actionButtons">
+		<li id="addNews"><a href="#" onclick="postForm('addGallery'); return false;"><img src="media/style[+theme+]/images/icons/add.png" /> Добавить галерею</a></li>
+		<li><a href="#" onclick="postForm('config'); return false;"><img src="../assets/modules/seagulllibrary/css/images/config.png" /> Настройки</a></li>
+	</ul>
+	[+galleries_list+]
+	[+paginator_links+]
+	<form name="module" method="post">
+		<input name="cmd" type="hidden" value="" />
+		<input name="itemID" type="hidden" value="" />
+	</form>
+	[+js+]
+	<script type="text/javascript" src="/assets/modules/[+nameModule+]/js/[+nameModule+].js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/templates/style.css b/templates/style.css
new file mode 100644
index 0000000..6ce8b0d
--- /dev/null
+++ b/templates/style.css
@@ -0,0 +1,97 @@
+/*
+ * Seagull Gallery
+ */
+
+body {
+	font-family: Helvetica,Arial,sans-serif !important;
+	font-size: 75%;
+	background: #F7F7F7;
+	padding: 0 10px;
+}
+h1 {
+	margin-left: 0;
+	font-size: 150%;
+}
+
+form input:read-only, form select:read-only, form textarea:read-only {
+	background-image: none;
+	background: #EEE;
+}
+
+.b-td__title {
+	font-weight: bold;
+}
+.col-edit {
+	cursor: pointer;
+	vertical-align: top;
+}
+
+/* tablesort */
+.tsort .tsort__dragHandle {
+	padding: 0 5px;
+	cursor: move;
+}
+.b-table tbody tr:hover .tsort__dragHandle {
+	background: transparent url('../../seagulllibrary/css/images/move.png') no-repeat center center;
+}
+.tsort .tsort__col-edit {
+	background: url('../../seagulllibrary/css/images/gtk-edit.png') no-repeat center center;
+	cursor: pointer;
+}
+.tsort .tsort__dragClass td {
+/*	background: #FFEEB2;*/
+}
+.tsort .showDragHandle {
+	background: transparent url('../../seagulllibrary/css/images/move.png') no-repeat center center;
+}
+.b-table tbody tr:hover .img-download {
+	display: block;
+	width: 16px;
+	height: 16px;
+	position: absolute;
+	margin: 4px;
+	background: url('../../seagulllibrary/css/images/save_16.gif') no-repeat center center;
+}
+
+/* upload images */
+.b-progress {
+	position: relative;
+	display: none;
+	width: 300px;
+	margin: 5px 0;
+	padding: 1px;
+	border: 1px solid #ddd;
+	border-radius: 3px;
+}
+.b-progress__bar {
+	background: url('../../seagulllibrary/css/images/upload.gif') repeat-x 0 0;
+	width: 70%;
+	height: 18px;
+	border-radius: 3px;
+}
+.b-progress__percent {
+	position: absolute;
+	display: block;
+	text-align: center;
+	top: 3px;
+	width: 100%;
+}
+
+/* timepicker */
+.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
+.ui-timepicker-div dl { text-align: left; }
+.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }
+.ui-timepicker-div dl dd { margin: 0 10px 10px 65px; }
+.ui-timepicker-div td { font-size: 90%; }
+.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
+
+.b-btn-imgs-del {
+	color: #888;
+}
+
+.tc {
+	text-align: center;
+}
+.tr {
+	text-align: right;
+}
\ No newline at end of file