+ ' . $title . '';
+ }
+ else {
+ echo '
';
+ $armory_news = Utils::GetArmoryNews(true);
+ if(is_array($armory_news)) {
+ $count = count($armory_news);
+ echo '
';
+ for($i = 0; $i < $count; ++$i) {
+ echo sprintf('%s (%s) ', $armory_news[$i]['id'], $armory_news[$i]['title'], $armory_news[$i]['date']);
+ }
+ echo ' ';
+ }
+ }
+ ?>
+
+
+
* ID:
+
+
+
* Date (in day.moth.year hour:minute:second format):
+
+
Title (deDE):
+
+
* Title (enGB):
+
+
Title (esES):
+
+
Title (frFR):
+
+
Title (ruRU):
+
+
Text (deDE):
+
+
* Text (enGB):
+
+
Text (esES:)
+
+
Text (frFR):
+
+
Text (ruRU):
+
+
+
Display on main
+
+
Submit
+
Clear
+ ', $news_item['id'], $news_item['id'], date('d.m.Y H:i:s', $news_item['date']),
+ $news_item['title_de_de'], $news_item['title_en_gb'],
+ $news_item['title_es_es'], $news_item['title_fr_fr'], $news_item['title_ru_ru'],
+ $news_item['text_de_de'], $news_item['text_en_gb'],
+ $news_item['text_es_es'], $news_item['text_fr_fr'], $news_item['text_ru_ru'],
+ $news_item['display'] == 1 ? ' checked' : null
+ );
+ }
+ ?>
+
+
+
+
+
diff --git a/admin/template/content_news_redirect.php b/admin/template/content_news_redirect.php
new file mode 100644
index 000000000..524c34acf
--- /dev/null
+++ b/admin/template/content_news_redirect.php
@@ -0,0 +1,14 @@
+
+
+
+
+
News Manager
+
+
+
+
News were successfully updated.
+
Go back
+
+
+
+
diff --git a/admin/template/css/960.css b/admin/template/css/960.css
new file mode 100644
index 000000000..7618d4842
--- /dev/null
+++ b/admin/template/css/960.css
@@ -0,0 +1 @@
+.container_12,.container_16{margin-left:auto;margin-right:auto;width:960px}.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12,.grid_13,.grid_14,.grid_15,.grid_16{display:inline;float:left;margin-left:10px;margin-right:10px}.container_12 .grid_3,.container_16 .grid_4{width:220px}.container_12 .grid_6,.container_16 .grid_8{width:460px}.container_12 .grid_9,.container_16 .grid_12{width:700px}.container_12 .grid_12,.container_16 .grid_16{width:940px}.alpha{margin-left:0}.omega{margin-right:0}.container_12 .grid_1{width:60px}.container_12 .grid_2{width:140px}.container_12 .grid_4{width:300px}.container_12 .grid_5{width:380px}.container_12 .grid_7{width:540px}.container_12 .grid_8{width:620px}.container_12 .grid_10{width:780px}.container_12 .grid_11{width:860px}.container_16 .grid_1{width:40px}.container_16 .grid_2{width:100px}.container_16 .grid_3{width:160px}.container_16 .grid_5{width:280px}.container_16 .grid_6{width:340px}.container_16 .grid_7{width:400px}.container_16 .grid_9{width:520px}.container_16 .grid_10{width:580px}.container_16 .grid_11{width:640px}.container_16 .grid_13{width:760px}.container_16 .grid_14{width:820px}.container_16 .grid_15{width:880px}.container_12 .prefix_3,.container_16 .prefix_4{padding-left:240px}.container_12 .prefix_6,.container_16 .prefix_8{padding-left:480px}.container_12 .prefix_9,.container_16 .prefix_12{padding-left:720px}.container_12 .prefix_1{padding-left:80px}.container_12 .prefix_2{padding-left:160px}.container_12 .prefix_4{padding-left:320px}.container_12 .prefix_5{padding-left:400px}.container_12 .prefix_7{padding-left:560px}.container_12 .prefix_8{padding-left:640px}.container_12 .prefix_10{padding-left:800px}.container_12 .prefix_11{padding-left:880px}.container_16 .prefix_1{padding-left:60px}.container_16 .prefix_2{padding-left:120px}.container_16 .prefix_3{padding-left:180px}.container_16 .prefix_5{padding-left:300px}.container_16 .prefix_6{padding-left:360px}.container_16 .prefix_7{padding-left:420px}.container_16 .prefix_9{padding-left:540px}.container_16 .prefix_10{padding-left:600px}.container_16 .prefix_11{padding-left:660px}.container_16 .prefix_13{padding-left:780px}.container_16 .prefix_14{padding-left:840px}.container_16 .prefix_15{padding-left:900px}.container_12 .suffix_3,.container_16 .suffix_4{padding-right:240px}.container_12 .suffix_6,.container_16 .suffix_8{padding-right:480px}.container_12 .suffix_9,.container_16 .suffix_12{padding-right:720px}.container_12 .suffix_1{padding-right:80px}.container_12 .suffix_2{padding-right:160px}.container_12 .suffix_4{padding-right:320px}.container_12 .suffix_5{padding-right:400px}.container_12 .suffix_7{padding-right:560px}.container_12 .suffix_8{padding-right:640px}.container_12 .suffix_10{padding-right:800px}.container_12 .suffix_11{padding-right:880px}.container_16 .suffix_1{padding-right:60px}.container_16 .suffix_2{padding-right:120px}.container_16 .suffix_3{padding-right:180px}.container_16 .suffix_5{padding-right:300px}.container_16 .suffix_6{padding-right:360px}.container_16 .suffix_7{padding-right:420px}.container_16 .suffix_9{padding-right:540px}.container_16 .suffix_10{padding-right:600px}.container_16 .suffix_11{padding-right:660px}.container_16 .suffix_13{padding-right:780px}.container_16 .suffix_14{padding-right:840px}.container_16 .suffix_15{padding-right:900px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.clearfix:after{clear:both;content:' ';display:block;font-size:0;line-height:0;visibility:hidden;width:0;height:0}.clearfix{display:inline-block}* html .clearfix{height:1%}.clearfix{display:block}
\ No newline at end of file
diff --git a/admin/template/css/blue.css b/admin/template/css/blue.css
new file mode 100644
index 000000000..0be6cba26
--- /dev/null
+++ b/admin/template/css/blue.css
@@ -0,0 +1,611 @@
+body { background:url(../images/bg.gif) repeat-x left top #d4d3d3; font-family:"Trebuchet MS", Arial, Helvetica, sans-serif; font-size: 13px; color: #333; }
+a, a:active, a:link, a:visited { text-decoration:none; color: #069; }
+a:hover { text-decoration: underline; color: #C00; }
+#logo { font-size:24px; font-style:italic; font-weight:normal; color:white; line-height:69px; }
+#header { background:url(../images/bg_header_blue.gif) left top no-repeat; height:123px; }
+#content { background:url(../images/bg_content.gif) left top repeat-x #FFFFFF; width:938px !important; border-left:1px solid #9c9c9c; border-right:1px solid #9c9c9c; padding: 10px 0px;}
+#textcontent { padding:10px !important; width:900px !important; }
+#wrapper { padding-bottom:10px !important; background:url(../images/bg_content_bottom.gif) center bottom no-repeat; }
+#footer { text-align:center; padding:15px 0px; color: #666; font-size:11px; }
+.hidden { display:none; }
+.text { padding:10px 15px; }
+.nopadding { padding:0px !important; }
+.floatLeft { float:left; }
+.floatRight { float:right; }
+a.edit_icon { background:url(../images/icons/edit.gif) no-repeat left top; display:inline-block; width: 16px; height:16px; }
+a.delete_icon { background:url(../images/icons/action_delete.gif) no-repeat left top; display:inline-block; width: 16px; height:16px; }
+a.approve_icon { background:url(../images/icons/action_check.gif) no-repeat left top; display:inline-block; width: 16px; height:16px; }
+a.reject_icon { background:url(../images/icons/action_remove.gif) no-repeat left top; display:inline-block; width: 16px; height:16px; }
+a.edit_inline { background:url(../images/icons/edit.gif) no-repeat left top; display:inline-block; line-height:16px; color: #069 !important; font-size:10px; padding-left:20px; margin-right:5px; }
+a.delete_inline { background:url(../images/icons/action_delete.gif) no-repeat left top; display:inline-block; line-height:16px; color: #D23333 !important; font-size:10px; padding-left:20px; margin-right:5px; }
+a.reject_inline { background:url(../images/icons/action_remove.gif) no-repeat left top; display:inline-block; line-height:16px; color: #D23333 !important; font-size:10px; padding-left:20px; margin-right:5px; }
+a.approve_inline { background:url(../images/icons/action_check.gif) no-repeat left top; display:inline-block; line-height:16px; color: #5a801b !important; font-size:10px; padding-left:20px; margin-right:5px; }
+.news_items li { margin-left:15px; }
+/*******************************************************************************
+ HEADING CLASSES
+*******************************************************************************/
+h1 { font-size:22px; color: #1b486a; display: block; margin-top: 10px;}
+h1.dashboard { background:url(../images/icon_dashboard.png) left 3px no-repeat; padding-left:35px;}
+h1.content_edit { background:url(../images/icon_content_small.gif) left 3px no-repeat; padding-left:35px;}
+h2 { font-size:18px !important; }
+h3 { font-size: 13px !important; }
+/*******************************************************************************
+ EVENTBOX (title -> rightbox)
+*******************************************************************************/
+#eventbox {
+ font-size:11px;
+ text-align:right;
+ margin-top: 10px;
+ line-height:35px;
+ width: 375px !important;
+ position:relative;
+}
+a.inline_calendar { padding-left:21px; background:url(../images/icons/calendar.gif) no-repeat left top; }
+a.inline_tip { padding-left:21px; background:url(../images/icons/lightbulb_off.gif) no-repeat left top; }
+.hidden_calendar { position:absolute; top:35px; right:20px; width:200px; height:200px; display:none; }
+.hidden_calendar { line-height:normal !important;}
+.hidden_calendar .ui-datepicker .ui-datepicker-prev span, .hidden_calendar .ui-datepicker .ui-datepicker-next span {
+ text-indent:-99999px !important;
+}
+/*******************************************************************************
+ USER TOOLS
+*******************************************************************************/
+#user_tools {
+ background:url(../images/bg_usertools_right.gif) right top no-repeat;
+ height:34px;
+ padding-right:9px;
+ float:right;
+}
+#user_tools span {
+ background:url(../images/bg_usertools_left.gif) left top no-repeat #000000;
+ height:34px;
+ padding-left:9px;
+ line-height: 34px;
+ font-size:10px;
+ color: #b0b0b0;
+ display:block;
+ float:right;
+}
+#user_tools a { color: #FFF; text-decoration:none; }
+#user_tools a:hover { text-decoration:underline; }
+#user_tools a.mail { background: url(../images/icon_mail_small.gif) left 2px no-repeat; padding-left:17px; margin-right:5px; }
+#user_tools a.mail:hover { text-decoration:none !important; }
+.dropdown { background:url(../images/arrow_mini_down.gif) no-repeat right 3px; padding-right:13px; }
+#colorchanger { z-index: 8; display: none; position:absolute; color: white; top:33px; right:35px; border-left:1px solid #333; border-right: 1px solid #333; background:black; width:100px;}
+#colorchanger a { padding:5px; border-bottom:1px solid #333; color: #FFF; display: block; font-size: 10px; text-decoration:none; }
+#colorchanger a:hover { background: #222; }
+#colorchanger span.redtheme { background: url(../images/bullet_red.gif) left 0px no-repeat; padding-left:16px; }
+#colorchanger span.bluetheme { background: url(../images/bullet_blue.gif) left 0px no-repeat; padding-left:16px; }
+#colorchanger span.greentheme { background: url(../images/bullet_green.gif) left 0px no-repeat; padding-left:16px; }
+/*******************************************************************************
+ MENU
+*******************************************************************************/
+#menu {
+ float: left;
+}
+#menu ul.group {
+ margin: 12px 0px 0px 14px;
+ padding: 0px 0px 0px;
+ list-style: none;
+ float: left;
+ z-index:4;
+}
+#menu ul.group li {
+ display: inline;
+ float: left;
+ position: static;
+ z-index: 5;
+ margin-left:0px !important;
+}
+#menu ul.group li a {
+ display: block;
+ float: left;
+ height: 100px;
+ width: 114px;
+ overflow:hidden;
+ font-size: 12px;
+ font-weight: bold;
+ font-style: italic;
+ color: white;
+ text-decoration:none;
+ text-align:center;
+ z-index:6;
+}
+#menu ul.group li a * {
+ cursor: pointer;
+}
+#menu ul.group li a span.outer {
+ display: block;
+ height: 90px;
+ padding-top: 10px
+}
+#menu ul.group li a span.inner {
+ display: block;
+ padding: 55px 10px 9px 10px;
+ white-space: nowrap;
+ background-repeat: no-repeat;
+ background-position: 50% 3px;
+}
+#menu ul.group li a {
+ background:url('../images/navigation_background_blue.gif') repeat-x top left;
+}
+#menu ul.group li.first a {
+ background:url('../images/navigation_first_blue.gif') no-repeat top left;
+}
+#menu ul.group li.last a {
+ background:url('../images/navigation_last_blue.gif') no-repeat top right;
+}
+#menu ul.group li.last a span.inner {
+ border: none !important;
+}
+
+#menu ul.group li a:hover, #menu ul.group li a.hover {
+ background-position: bottom left;
+ text-decoration: none;
+}
+#menu ul.group li.last a:hover, #menu ul.group li.last a.hover {
+ background-position: bottom right;
+}
+#menu ul.group li a.current {
+ background-position: bottom left;
+ text-decoration: none;
+}
+#menu ul.group li.last a.current {
+ background-position: bottom right;
+}
+#menu ul.group li.first a.current {
+ background-position: bottom left;
+}
+
+#menu ul.group li a span.inner {
+ border-right: 1px solid #4985b2;
+}
+#menu ul.group li a:hover span.inner {
+ border-right: 1px solid #4985b2;
+}
+#menu ul.group li a.more {
+}
+#menu .additional a span {
+ border-right:1px solid #DFDCBB;
+}
+#menu .dashboard { background-image: url(../images/icon_dashboard.png); background-repeat: no-repeat; }
+#menu .content { background-image: url(../images/icon_edit.png); background-repeat: no-repeat; }
+#menu .reports { background-image: url(../images/icon_reports.png); background-repeat: no-repeat; }
+#menu .users { background-image: url(../images/icon_users.png); background-repeat: no-repeat; }
+#menu .media_library { background-image: url(../images/icon_media.png); background-repeat: no-repeat; }
+#menu .event_manager { background-image: url(../images/icon_clock.png); background-repeat: no-repeat; }
+#menu .newsletter { background-image: url(../images/icon_news.png); background-repeat: no-repeat; }
+#menu .settings { background-image: url(../images/icon_settings.png); background-repeat: no-repeat; }
+#menu .updates { background-image: url(../images/icon_updates.png); background-repeat: no-repeat; }
+#menu .help { background-image: url(../images/icon_help.png); background-repeat: no-repeat; }
+#menu .database { background-image: url(../images/icon_database.png); background-repeat: no-repeat; }
+#hidden_submenu {
+ background:#FFF;
+ padding:10px;
+ display:none;
+ width:918px !important;
+ border-left: 1px solid #9C9C9C;
+ border-right: 1px solid #9C9C9C;
+ border-bottom: 1px solid #CCC;
+}
+#hidden_submenu .more_menu { float:left; margin: 10px 5px; }
+#hidden_submenu .more_menu li { margin-left: 30px; }
+/*******************************************************************************
+ TABS
+*******************************************************************************/
+
+#tabs {
+}
+
+#tabs .container {
+ height: 25px;
+ padding-top: 8px;
+ border-left: 1px solid #397cae;
+ border-right: 1px solid #397cae;
+ border-bottom: 1px solid #346a92;
+ width: 938px !important;
+ background: #eee;
+}
+
+#tabs ul {
+ margin: 0px 0px 0px 10px;
+ padding: 0px;
+ list-style: none;
+}
+
+#tabs ul li {
+ display: inline;
+}
+
+#tabs ul li a {
+ font-family:Arial, Helvetica, sans-serif;
+ display: block;
+ float: left;
+ height: 25px;
+ margin-right: 3px;
+ font-size: 11px;
+ font-weight: bold;
+ overflow: hidden;
+ border-bottom: 0px;
+ background: #DEDEDE;
+ text-decoration:none;
+ color: #1b486a;
+}
+
+#tabs ul li a:hover {
+ text-decoration: underline;
+ background-color: #FFFFFF;
+}
+
+#tabs ul li a span {
+ height: 20px;
+ padding: 0px 10px;
+ display: block;
+ padding-top: 5px;
+ cursor: pointer;
+ white-space: nowrap;
+}
+
+#tabs ul li a.current {
+ background-color: #FFFFFF;
+}
+#tabs ul li.first a span {
+ padding-left: 15px;
+ padding-right: 15px;
+}
+#tabs {
+ background: #639ecb;
+}
+
+#tabs .container {
+ background:url('../images/tabs_bg.gif') repeat-x left top;
+ border-bottom: none;
+}
+
+#tabs ul li a {
+ background: url('../images/tabs_left.gif') no-repeat left top;
+ border: 0px;
+}
+
+#tabs ul li a span {
+ background: url('../images/tabs_right.gif') no-repeat right top;
+}
+
+#tabs ul li a.current {
+ background-position: left bottom;
+}
+
+#tabs ul li a.current span {
+ background-position: right bottom;
+}
+#tabs ul li a.tempoff {
+ background-position: left top;
+}
+
+#tabs ul li a.tempoff span {
+ background-position: right top;
+}
+
+#tabs ul li.first a{
+ color: #1b486a !important;
+}
+/*******************************************************************************
+ PORTLETS AND GRID
+*******************************************************************************/
+#portlets { padding:0px 10px; }
+.column { width: 450px; float: left; padding-bottom: 0px; }
+.column#left { margin-right:17px; }
+.portlet { margin: 0 0em 1em 0; }
+.portlet-header { margin: 0em; padding-bottom: 5px; padding-left: 6px; padding-top:4px; padding-right:6px; font-size:12px; border: none !important; color: #333 !important; font-family:"Trebuchet MS", Arial, Helvetica, sans-serif; cursor:move; }
+.portlet-header .ui-icon { float: right; cursor:pointer; }
+.portlet-header img { float:left; margin-right:5px; }
+#portlets .fixed { cursor:auto; }
+.portlet-content { padding: 0.8em; font-size:12px !important; color: #333; border-top:1px solid #999 !important; font-family:"Trebuchet MS", Arial, Helvetica, sans-serif; }
+.ui-sortable-placeholder { border: 1px dashed #999 !important; visibility: visible !important; height: 100px !important; background: #EBEBEB;}
+.ui-sortable-placeholder * { visibility: hidden; }
+
+/*******************************************************************************
+ Informational Messages
+*******************************************************************************/
+.info {
+ display: block;
+ background: url('../images/informationbar_right.gif') no-repeat right top;
+ height: 30px;
+ overflow: hidden;
+ margin-top: 5px;
+ margin-bottom:10px !important;
+ padding: 0px !important;
+ font-size: 12px !important;
+ font-weight: bold;
+ cursor: pointer;
+ border: 0px;
+ font-style: italic;
+}
+.info .info_inner {
+ display: block;
+ height: 30px;
+ padding: 6px 10px 0px 35px;
+}
+#success .info_inner {
+ color: #5a801b;
+ background: url('../images/icon_success.gif') no-repeat left top;
+ border: 0px;
+}
+#warning .info_inner {
+ color: #E89326;
+ background: url('../images/icon_warning.gif') no-repeat left top;
+ border: 0px;
+}
+#error .info_inner {
+ color: #C00;
+ background: url('../images/icon_error.gif') no-repeat left top;
+ border: 0px;
+}
+#info .info_inner {
+ color: #4985B2;
+ background: url('../images/icon_info.gif') no-repeat left top;
+ border: 0px;
+}
+/*******************************************************************************
+ TABLE DESIGN
+*******************************************************************************/
+#box-table-a {
+ font-size: 12px;
+ margin: 0px;
+ text-align: left;
+ border-collapse: separate;
+ border-bottom:none;
+}
+#box-table-a th {
+ font-size: 13px;
+ font-weight: normal;
+ padding: 8px;
+ background: #EFEFEF;
+ border-top: 1px solid #FFF;
+ color: #333;
+ text-align: left;
+}
+#box-table-a td {
+ padding: 8px;
+ background: none;
+ border-top: 1px solid #CCC;
+ color: #666;
+ border-bottom: none !important;
+}
+#box-table-a tr:hover td {
+ background: #FBFBFB;
+ color: #333;
+}
+#box-table-a tr.footer { background: none !important; }
+#box-table-a tr.footer:hover td { background: none !important; }
+
+
+/*******************************************************************************
+ PAGINATION
+*******************************************************************************/
+.pagination { border:0; margin:0; padding:0; font-size:10px; }
+.pagination a { border:solid 1px #DEDEDE; margin-right:2px; }
+.pagination .previous-off, .pagination .next-off { color:#888888; display:inline-block; font-weight:normal; padding:3px 4px; }
+.pagination .next a,.pagination .previous a { font-weight:bold; border:solid 1px #FFFFFF; }
+.pagination .active{ color:#000000; font-weight:bold; display:inline-block; padding:4px 6px; }
+.pagination a:link, .pagination a:visited { display:inline-block; padding:3px 6px; text-decoration:none; }
+.pagination a:hover{ text-decoration:none; border: 1px solid #999; }
+
+/*******************************************************************************
+ FORMS
+*******************************************************************************/
+form label { display:block !important; line-height:normal !important; margin: 5px 0px; font-size:12px; font-weight:bold; }
+input[type=text] { display:block !important; }
+textarea { display:block; }
+.smallInput { padding:3px 3px; border:1px solid #999; background:#FFFFE6; font-size:12px !important; font-family:"Trebuchet MS", Arial, Helvetica, sans-serif !important; color: #333 !important; font-style:italic; }
+.largeInput { padding:6px 5px; border:1px solid #999; background:#FFFFE6; font-size:15px !important; font-family:"Trebuchet MS", Arial, Helvetica, sans-serif !important; color: #333 !important; }
+form .small { width:150px; }
+form .medium { width:350px; }
+form .wide { width:890px; }
+.button {
+ margin: 0px;
+ padding: 0px !important;
+ border: 0px;
+ background: transparent url('../images/but_right_blue.gif') no-repeat scroll top right;
+ color: #1b486a;
+ display: block;
+ float: left;
+ height: 29px;
+ margin-right: 6px;
+ margin-top:10px;
+ padding-right: 12px !important;
+ text-decoration: none;
+ overflow: hidden;
+ font-size: 12px;
+ outline: none !important;
+ cursor: pointer;
+ font-weight: bold;
+}
+.button span {
+ background: url('../images/but_left_blue.gif') no-repeat left top;
+ display: block;
+ line-height: 29px;
+ padding: 0px 0px 0px 12px;
+ outline: none !important;
+ float:left;
+}
+.button:hover {
+ background-position: right bottom;
+ text-decoration:none !important
+}
+.button:hover span {
+ background-position: left bottom;
+ color: #1b486a;
+}
+.button_grey {
+ margin: 0px;
+ padding: 0px !important;
+ border: 0px;
+ background: transparent url('../images/but_right_grey.gif') no-repeat scroll top right;
+ color: #555;
+ display: block;
+ float: left;
+ height: 30px;
+ margin-right: 6px;
+ margin-top:10px;
+ padding-right: 12px !important;
+ text-decoration: none;
+ overflow: hidden;
+ font-size: 12px;
+ outline: none !important;
+ cursor: pointer;
+ font-weight: bold;
+}
+.button_grey span {
+ background: url('../images/but_left_grey.gif') no-repeat left top;
+ display: block;
+ line-height: 30px;
+ padding: 0px 0px 0px 12px;
+ outline: none !important;
+ float:left;
+}
+.button_grey:hover {
+ background-position: right bottom;
+ text-decoration:none !important
+}
+.button_grey:hover span {
+ background-position: left bottom;
+ color: #333;
+}
+.button_ok {
+ margin: 0px;
+ padding: 0px !important;
+ border: 0px;
+ background: transparent url('../images/but_round_span_blue.gif') no-repeat scroll top right;
+ color: #1b486a;
+ display: block;
+ float: left;
+ height: 30px;
+ margin-right: 6px;
+ margin-top:10px;
+ padding-right: 15px !important;
+ text-decoration: none;
+ overflow: hidden;
+ font-size: 12px;
+ outline: none !important;
+ cursor: pointer;
+ font-weight: bold;
+}
+.button_ok span {
+ background: url('../images/but_round_ok_blue.gif') no-repeat left top;
+ display: block;
+ line-height: 30px;
+ padding: 0px 0px 0px 35px;
+ outline: none !important;
+ float:left;
+}
+.button_ok:hover {
+ background-position: right bottom;
+ text-decoration:none !important
+}
+.button_ok:hover span {
+ background-position: left bottom;
+ color: #1b486a;
+}
+.button_notok {
+ margin: 0px;
+ padding: 0px !important;
+ border: 0px;
+ background: transparent url('../images/but_round_span_blue.gif') no-repeat scroll top right;
+ color: #1b486a;
+ display: block;
+ float: left;
+ height: 30px;
+ margin-right: 6px;
+ margin-top:10px;
+ padding-right: 15px !important;
+ text-decoration: none;
+ overflow: hidden;
+ font-size: 12px;
+ outline: none !important;
+ cursor: pointer;
+ font-weight: bold;
+}
+.button_notok span {
+ background: url('../images/but_round_del_blue.gif') no-repeat left top;
+ display: block;
+ line-height: 30px;
+ padding: 0px 0px 0px 35px;
+ outline: none !important;
+ float:left;
+ font-style: italic;
+}
+.button_notok:hover {
+ background-position: right bottom;
+ text-decoration:none !important
+}
+.button_notok:hover span {
+ background-position: left bottom;
+ color: #1b486a;
+}
+.button_grey_round {
+ margin: 0px;
+ padding: 0px !important;
+ border: 0px;
+ background: transparent url('../images/but_round_span_grey.gif') no-repeat scroll top right;
+ color: #555;
+ display: block;
+ float: left;
+ height: 30px;
+ margin-right: 6px;
+ margin-top:10px;
+ padding-right: 12px !important;
+ text-decoration: none;
+ overflow: hidden;
+ font-size: 12px;
+ outline: none !important;
+ cursor: pointer;
+ font-weight: bold;
+}
+.button_grey_round span {
+ background: url('../images/but_round_left_grey.gif') no-repeat left top;
+ display: block;
+ line-height: 30px;
+ padding: 0px 0px 0px 12px;
+ outline: none !important;
+ float:left;
+}
+.button_grey_round:hover {
+ background-position: right bottom;
+ text-decoration:none !important
+}
+.button_grey_round:hover span {
+ background-position: left bottom;
+ color: #333;
+}
+/*******************************************************************************
+ MODAL BOX OVERRIDE
+*******************************************************************************/
+.ui-dialog {
+padding:0px !important;
+border: none 0 !important;
+font-size: 12px !important;
+font-family: "Trebuchet MS", Arial, Helvetica, sans-serif !important;
+}
+.ui-dialog .ui-dialog-titlebar {
+padding-left:5px !important;
+padding-top:3px !important;
+padding-bottom:3px !important;
+padding-right:5px !important;
+position:relative;
+border-bottom: none !important;
+font-size:13px !important;
+}
+.ui-dialog .ui-corner-all {
+-moz-border-radius-bottomleft:0px !important;
+-moz-border-radius-bottomright:0px !important;
+-moz-border-radius-topleft:4px;
+-moz-border-radius-topright:4px;
+}
+.ui-dialog .ui-dialog-content {
+border: 1px solid #AAAAAA !important;
+}
+.ui-widget-overlay {
+background:#000 !important;
+opacity:0.7 !important;
+}
diff --git a/admin/template/css/iefix.css b/admin/template/css/iefix.css
new file mode 100644
index 000000000..29b1238d3
--- /dev/null
+++ b/admin/template/css/iefix.css
@@ -0,0 +1,20 @@
+* html #tabs ul li a span {
+ width: 1px !important;
+ position:static !important;
+ }
+* html #tabs ul li a.current {
+ position: relative;
+ top: 1px;
+}
+.group { margin-left:6px !important; }
+#hidden_submenu { margin-left:5px !important; }
+#wrapper { z-index: 0 !important; }
+#user_tools { z-index: 1 !important; }
+#header { z-index:2 !important; }
+#menu { z-index:3 !important; }
+.group { z-index:4 !important; }
+.item {z-index:5 !important; }
+.item span { z-index:6 !important; }
+#colorchanger { z-index:7 !important; }
+#colorchanger a { z-index:8 !important; }
+#colorchanger a span { z-index:9 !important; }
\ No newline at end of file
diff --git a/admin/template/css/login.css b/admin/template/css/login.css
new file mode 100644
index 000000000..12b248b3d
--- /dev/null
+++ b/admin/template/css/login.css
@@ -0,0 +1,115 @@
+body { background:url(../images/bg.gif) repeat-x left top #d4d3d3; font-family:"Trebuchet MS", Arial, Helvetica, sans-serif; font-size: 13px; color: #333; }
+a, a:active, a:link, a:visited { text-decoration:none; color: #FFF; }
+a:hover { text-decoration: underline; color: #CCC; }
+h1 {
+ font-size:24px;
+ font-style:italic;
+ font-weight:normal;
+ color:white;
+ line-height:35px;
+ margin-bottom:0px;
+ margin-top:80px;
+ text-align: center;
+}
+#login {
+ margin:10px 0px 0px 0px;
+ border:1px solid #666;
+ background:url(../images/bg_login.gif) repeat-x left top #f6f5f5;
+ padding:20px;
+}
+#forgot {
+ margin:0px auto 30px auto;
+ width:235px;
+ text-align: center;
+}
+p.tip {
+ padding-left:20px;
+ display:block;
+ background-image: url(../images/icons/lightbulb.gif);
+ background-repeat: no-repeat;
+ background-position: 0 0;
+}
+p.error {
+ padding-left:20px;
+ display:block;
+ background-image: url(../images/icons/exclamation.gif);
+ background-repeat: no-repeat;
+ background-position: 0 0;
+ color: #900;
+}
+.black_button {
+ margin: 0px;
+ padding: 0px !important;
+ border: 0px;
+ background: transparent url('../images/but_login_span.gif') no-repeat scroll top right;
+ color: #FFF;
+ display:block;
+ float: right;
+ width:105px;
+ height: 30px;
+ margin-right: 6px;
+ margin-top:10px;
+ padding-right: 12px !important;
+ text-decoration: none;
+ overflow: hidden;
+ font-size: 12px;
+ outline: none !important;
+ cursor: pointer;
+ font-weight: bold;
+}
+.black_button span {
+ background: url('../images/but_login_left.gif') no-repeat left top;
+ display: block;
+ line-height: 30px;
+ padding: 0px 0px 0px 12px;
+ outline: none !important;
+ float:right;
+}
+.inputText {
+ padding:7px;
+ border:1px solid #999;
+ font-size:16px;
+ font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
+ color: #333;
+ width:270px;
+ margin:5px;
+ background:#FFFFF8;
+}
+.forgotlink {
+ margin: 0px;
+ padding: 0px !important;
+ border: 0px;
+ background: transparent url('../images/forgot_bg_span.gif') no-repeat scroll top right;
+ color: #888 !important;
+ display:block;
+ float: left;
+ height: 30px;
+ margin-right: 6px;
+ padding-right: 15px !important;
+ text-decoration: none;
+ overflow: hidden;
+ font-size: 11px;
+ outline: none !important;
+ cursor: pointer;
+ font-weight: bold;
+}
+.forgotlink:hover {
+ color: #666 !important;
+}
+.forgotlink span {
+ background: url('../images/forgot_bg_left.gif') no-repeat left top;
+ display: block;
+ line-height: 25px;
+ padding: 0px 0px 0px 15px;
+ outline: none !important;
+ float:left;
+ height:30px;
+}
+#forgotform {
+ margin:0px auto;
+ width:280px;
+ padding:10px;
+ border:1px solid #666;
+ background:#CCC;
+ display:none;
+}
diff --git a/admin/template/css/reset.css b/admin/template/css/reset.css
new file mode 100644
index 000000000..006e11b4d
--- /dev/null
+++ b/admin/template/css/reset.css
@@ -0,0 +1 @@
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';}:focus{outline:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0}
\ No newline at end of file
diff --git a/admin/template/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png b/admin/template/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 000000000..5b5dab2ab
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/admin/template/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/admin/template/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 000000000..ac8b229af
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/admin/template/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/admin/template/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100644
index 000000000..ad3d6346e
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png differ
diff --git a/admin/template/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/admin/template/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 000000000..42ccba269
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/admin/template/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png b/admin/template/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100644
index 000000000..5a46b47cb
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png differ
diff --git a/admin/template/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png b/admin/template/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100644
index 000000000..86c2baa65
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png differ
diff --git a/admin/template/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png b/admin/template/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644
index 000000000..4443fdc1a
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png differ
diff --git a/admin/template/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/admin/template/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100644
index 000000000..7c9fa6c6e
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ
diff --git a/admin/template/css/smoothness/images/ui-icons_222222_256x240.png b/admin/template/css/smoothness/images/ui-icons_222222_256x240.png
new file mode 100644
index 000000000..ee039dc09
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-icons_222222_256x240.png differ
diff --git a/admin/template/css/smoothness/images/ui-icons_2e83ff_256x240.png b/admin/template/css/smoothness/images/ui-icons_2e83ff_256x240.png
new file mode 100644
index 000000000..45e8928e5
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-icons_2e83ff_256x240.png differ
diff --git a/admin/template/css/smoothness/images/ui-icons_454545_256x240.png b/admin/template/css/smoothness/images/ui-icons_454545_256x240.png
new file mode 100644
index 000000000..7ec70d11b
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-icons_454545_256x240.png differ
diff --git a/admin/template/css/smoothness/images/ui-icons_888888_256x240.png b/admin/template/css/smoothness/images/ui-icons_888888_256x240.png
new file mode 100644
index 000000000..5ba708c39
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-icons_888888_256x240.png differ
diff --git a/admin/template/css/smoothness/images/ui-icons_cd0a0a_256x240.png b/admin/template/css/smoothness/images/ui-icons_cd0a0a_256x240.png
new file mode 100644
index 000000000..7930a5580
Binary files /dev/null and b/admin/template/css/smoothness/images/ui-icons_cd0a0a_256x240.png differ
diff --git a/admin/template/css/smoothness/ui.css b/admin/template/css/smoothness/ui.css
new file mode 100644
index 000000000..245ff03dd
--- /dev/null
+++ b/admin/template/css/smoothness/ui.css
@@ -0,0 +1,395 @@
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+*/
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
+/*.ui-widget-content a { color: #222222; }*/
+.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
+.ui-widget-header a { color: #222222; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; outline: none; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; outline: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; outline: none; }
+.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; outline: none; text-decoration: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; }
+.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
+.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
+.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
+.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
+.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
+.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }/* Accordion
+----------------------------------*/
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
+.ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker
+----------------------------------*/
+.ui-datepicker { width: 17em; padding: .2em .2em 0; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+ display: none; /*sorry for IE5*/
+ display/**/: block; /*sorry for IE5*/
+ position: absolute; /*must have*/
+ z-index: -1; /*must have*/
+ filter: mask(); /*must have*/
+ top: -4px; /*must have*/
+ left: -4px; /*must have*/
+ width: 200px; /*must have*/
+ height: 200px; /*must have*/
+}/* Dialog
+----------------------------------*/
+.ui-dialog { position: relative; padding: .2em; width: 300px; }
+.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/* Progressbar
+----------------------------------*/
+.ui-progressbar { height:2em; text-align: left; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable
+----------------------------------*/
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider
+----------------------------------*/
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
+----------------------------------*/
+.ui-tabs { padding: .2em; zoom: 1; }
+.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
+.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
diff --git a/admin/template/css/text.css b/admin/template/css/text.css
new file mode 100644
index 000000000..b6fa301aa
--- /dev/null
+++ b/admin/template/css/text.css
@@ -0,0 +1 @@
+body{font:13px/1.5 "Trebuchet MS", Arial, Helvetica, sans-serif}a:focus{outline:1px dotted invert}hr{border:0 #ccc solid;border-top-width:1px;clear:both;height:0}h1{font-size:25px}h2{font-size:23px}h3{font-size:21px}h4{font-size:19px}h5{font-size:17px}h6{font-size:15px}ol{list-style:decimal}ul{list-style:disc}li{margin-left:0px}p,dl,hr,h1,h2,h3,h4,h5,h6,ol,ul,pre,table,address,fieldset{margin-bottom:20px}
\ No newline at end of file
diff --git a/admin/template/images/arrow_mini_down.gif b/admin/template/images/arrow_mini_down.gif
new file mode 100644
index 000000000..d00d03852
Binary files /dev/null and b/admin/template/images/arrow_mini_down.gif differ
diff --git a/admin/template/images/bg.gif b/admin/template/images/bg.gif
new file mode 100644
index 000000000..05771c4d8
Binary files /dev/null and b/admin/template/images/bg.gif differ
diff --git a/admin/template/images/bg_content.gif b/admin/template/images/bg_content.gif
new file mode 100644
index 000000000..9f934df33
Binary files /dev/null and b/admin/template/images/bg_content.gif differ
diff --git a/admin/template/images/bg_content_bottom.gif b/admin/template/images/bg_content_bottom.gif
new file mode 100644
index 000000000..c7ed667b4
Binary files /dev/null and b/admin/template/images/bg_content_bottom.gif differ
diff --git a/admin/template/images/bg_header_blue.gif b/admin/template/images/bg_header_blue.gif
new file mode 100644
index 000000000..69804a695
Binary files /dev/null and b/admin/template/images/bg_header_blue.gif differ
diff --git a/admin/template/images/bg_login.gif b/admin/template/images/bg_login.gif
new file mode 100644
index 000000000..d36be0297
Binary files /dev/null and b/admin/template/images/bg_login.gif differ
diff --git a/admin/template/images/bg_usertools_left.gif b/admin/template/images/bg_usertools_left.gif
new file mode 100644
index 000000000..d92e3733c
Binary files /dev/null and b/admin/template/images/bg_usertools_left.gif differ
diff --git a/admin/template/images/bg_usertools_right.gif b/admin/template/images/bg_usertools_right.gif
new file mode 100644
index 000000000..b05cbec87
Binary files /dev/null and b/admin/template/images/bg_usertools_right.gif differ
diff --git a/admin/template/images/bullet_blue.gif b/admin/template/images/bullet_blue.gif
new file mode 100644
index 000000000..6c6e4a499
Binary files /dev/null and b/admin/template/images/bullet_blue.gif differ
diff --git a/admin/template/images/bullet_green.gif b/admin/template/images/bullet_green.gif
new file mode 100644
index 000000000..e0f8fb63a
Binary files /dev/null and b/admin/template/images/bullet_green.gif differ
diff --git a/admin/template/images/bullet_red.gif b/admin/template/images/bullet_red.gif
new file mode 100644
index 000000000..a677fa9a3
Binary files /dev/null and b/admin/template/images/bullet_red.gif differ
diff --git a/admin/template/images/but_left_blue.gif b/admin/template/images/but_left_blue.gif
new file mode 100644
index 000000000..99a10156c
Binary files /dev/null and b/admin/template/images/but_left_blue.gif differ
diff --git a/admin/template/images/but_left_grey.gif b/admin/template/images/but_left_grey.gif
new file mode 100644
index 000000000..756e3d528
Binary files /dev/null and b/admin/template/images/but_left_grey.gif differ
diff --git a/admin/template/images/but_login_left.gif b/admin/template/images/but_login_left.gif
new file mode 100644
index 000000000..0adfac95d
Binary files /dev/null and b/admin/template/images/but_login_left.gif differ
diff --git a/admin/template/images/but_login_span.gif b/admin/template/images/but_login_span.gif
new file mode 100644
index 000000000..4c4808fc2
Binary files /dev/null and b/admin/template/images/but_login_span.gif differ
diff --git a/admin/template/images/but_right_blue.gif b/admin/template/images/but_right_blue.gif
new file mode 100644
index 000000000..eee482d39
Binary files /dev/null and b/admin/template/images/but_right_blue.gif differ
diff --git a/admin/template/images/but_right_grey.gif b/admin/template/images/but_right_grey.gif
new file mode 100644
index 000000000..748cdbb96
Binary files /dev/null and b/admin/template/images/but_right_grey.gif differ
diff --git a/admin/template/images/but_round_del_blue.gif b/admin/template/images/but_round_del_blue.gif
new file mode 100644
index 000000000..c42bedba3
Binary files /dev/null and b/admin/template/images/but_round_del_blue.gif differ
diff --git a/admin/template/images/but_round_left_grey.gif b/admin/template/images/but_round_left_grey.gif
new file mode 100644
index 000000000..d2dedfb09
Binary files /dev/null and b/admin/template/images/but_round_left_grey.gif differ
diff --git a/admin/template/images/but_round_ok_blue.gif b/admin/template/images/but_round_ok_blue.gif
new file mode 100644
index 000000000..f2e2d9d2f
Binary files /dev/null and b/admin/template/images/but_round_ok_blue.gif differ
diff --git a/admin/template/images/but_round_span_blue.gif b/admin/template/images/but_round_span_blue.gif
new file mode 100644
index 000000000..fd1726c76
Binary files /dev/null and b/admin/template/images/but_round_span_blue.gif differ
diff --git a/admin/template/images/but_round_span_grey.gif b/admin/template/images/but_round_span_grey.gif
new file mode 100644
index 000000000..166e3ce02
Binary files /dev/null and b/admin/template/images/but_round_span_grey.gif differ
diff --git a/admin/template/images/forgot_bg_left.gif b/admin/template/images/forgot_bg_left.gif
new file mode 100644
index 000000000..f5daa75f8
Binary files /dev/null and b/admin/template/images/forgot_bg_left.gif differ
diff --git a/admin/template/images/forgot_bg_span.gif b/admin/template/images/forgot_bg_span.gif
new file mode 100644
index 000000000..9e4770bfc
Binary files /dev/null and b/admin/template/images/forgot_bg_span.gif differ
diff --git a/admin/template/images/icon_clock.png b/admin/template/images/icon_clock.png
new file mode 100644
index 000000000..8d64bb5a0
Binary files /dev/null and b/admin/template/images/icon_clock.png differ
diff --git a/admin/template/images/icon_content_small.gif b/admin/template/images/icon_content_small.gif
new file mode 100644
index 000000000..b3d47f8e1
Binary files /dev/null and b/admin/template/images/icon_content_small.gif differ
diff --git a/admin/template/images/icon_dashboard.png b/admin/template/images/icon_dashboard.png
new file mode 100644
index 000000000..757d5c1c0
Binary files /dev/null and b/admin/template/images/icon_dashboard.png differ
diff --git a/admin/template/images/icon_dashboard_small.gif b/admin/template/images/icon_dashboard_small.gif
new file mode 100644
index 000000000..1b93297d6
Binary files /dev/null and b/admin/template/images/icon_dashboard_small.gif differ
diff --git a/admin/template/images/icon_database.png b/admin/template/images/icon_database.png
new file mode 100644
index 000000000..634c31377
Binary files /dev/null and b/admin/template/images/icon_database.png differ
diff --git a/admin/template/images/icon_edit.png b/admin/template/images/icon_edit.png
new file mode 100644
index 000000000..a4d9bd986
Binary files /dev/null and b/admin/template/images/icon_edit.png differ
diff --git a/admin/template/images/icon_error.gif b/admin/template/images/icon_error.gif
new file mode 100644
index 000000000..9ba798b3c
Binary files /dev/null and b/admin/template/images/icon_error.gif differ
diff --git a/admin/template/images/icon_help.png b/admin/template/images/icon_help.png
new file mode 100644
index 000000000..f4a943c4f
Binary files /dev/null and b/admin/template/images/icon_help.png differ
diff --git a/admin/template/images/icon_info.gif b/admin/template/images/icon_info.gif
new file mode 100644
index 000000000..87e4a349f
Binary files /dev/null and b/admin/template/images/icon_info.gif differ
diff --git a/admin/template/images/icon_mail_small.gif b/admin/template/images/icon_mail_small.gif
new file mode 100644
index 000000000..d26276d19
Binary files /dev/null and b/admin/template/images/icon_mail_small.gif differ
diff --git a/admin/template/images/icon_media.png b/admin/template/images/icon_media.png
new file mode 100644
index 000000000..613969a6e
Binary files /dev/null and b/admin/template/images/icon_media.png differ
diff --git a/admin/template/images/icon_news.png b/admin/template/images/icon_news.png
new file mode 100644
index 000000000..ad73c81e5
Binary files /dev/null and b/admin/template/images/icon_news.png differ
diff --git a/admin/template/images/icon_reports.png b/admin/template/images/icon_reports.png
new file mode 100644
index 000000000..fb6443942
Binary files /dev/null and b/admin/template/images/icon_reports.png differ
diff --git a/admin/template/images/icon_settings.png b/admin/template/images/icon_settings.png
new file mode 100644
index 000000000..83ce6c186
Binary files /dev/null and b/admin/template/images/icon_settings.png differ
diff --git a/admin/template/images/icon_success.gif b/admin/template/images/icon_success.gif
new file mode 100644
index 000000000..502a17346
Binary files /dev/null and b/admin/template/images/icon_success.gif differ
diff --git a/admin/template/images/icon_updates.png b/admin/template/images/icon_updates.png
new file mode 100644
index 000000000..06664beca
Binary files /dev/null and b/admin/template/images/icon_updates.png differ
diff --git a/admin/template/images/icon_users.png b/admin/template/images/icon_users.png
new file mode 100644
index 000000000..e246c8975
Binary files /dev/null and b/admin/template/images/icon_users.png differ
diff --git a/admin/template/images/icon_warning.gif b/admin/template/images/icon_warning.gif
new file mode 100644
index 000000000..05f3bbd24
Binary files /dev/null and b/admin/template/images/icon_warning.gif differ
diff --git a/admin/template/images/icons/action_check.gif b/admin/template/images/icons/action_check.gif
new file mode 100644
index 000000000..ab828a363
Binary files /dev/null and b/admin/template/images/icons/action_check.gif differ
diff --git a/admin/template/images/icons/action_delete.gif b/admin/template/images/icons/action_delete.gif
new file mode 100644
index 000000000..dfdce81af
Binary files /dev/null and b/admin/template/images/icons/action_delete.gif differ
diff --git a/admin/template/images/icons/action_remove.gif b/admin/template/images/icons/action_remove.gif
new file mode 100644
index 000000000..5f20f5600
Binary files /dev/null and b/admin/template/images/icons/action_remove.gif differ
diff --git a/admin/template/images/icons/calendar.gif b/admin/template/images/icons/calendar.gif
new file mode 100644
index 000000000..96a8bd14f
Binary files /dev/null and b/admin/template/images/icons/calendar.gif differ
diff --git a/admin/template/images/icons/chart_bar.gif b/admin/template/images/icons/chart_bar.gif
new file mode 100644
index 000000000..9032e8360
Binary files /dev/null and b/admin/template/images/icons/chart_bar.gif differ
diff --git a/admin/template/images/icons/comments.gif b/admin/template/images/icons/comments.gif
new file mode 100644
index 000000000..6ab591571
Binary files /dev/null and b/admin/template/images/icons/comments.gif differ
diff --git a/admin/template/images/icons/edit.gif b/admin/template/images/icons/edit.gif
new file mode 100644
index 000000000..9660fe2f3
Binary files /dev/null and b/admin/template/images/icons/edit.gif differ
diff --git a/admin/template/images/icons/exclamation.gif b/admin/template/images/icons/exclamation.gif
new file mode 100644
index 000000000..c7800791d
Binary files /dev/null and b/admin/template/images/icons/exclamation.gif differ
diff --git a/admin/template/images/icons/feed.gif b/admin/template/images/icons/feed.gif
new file mode 100644
index 000000000..87e97b686
Binary files /dev/null and b/admin/template/images/icons/feed.gif differ
diff --git a/admin/template/images/icons/lightbulb.gif b/admin/template/images/icons/lightbulb.gif
new file mode 100644
index 000000000..9a1566245
Binary files /dev/null and b/admin/template/images/icons/lightbulb.gif differ
diff --git a/admin/template/images/icons/lightbulb_off.gif b/admin/template/images/icons/lightbulb_off.gif
new file mode 100644
index 000000000..dea57836e
Binary files /dev/null and b/admin/template/images/icons/lightbulb_off.gif differ
diff --git a/admin/template/images/icons/user.gif b/admin/template/images/icons/user.gif
new file mode 100644
index 000000000..95c0aaafe
Binary files /dev/null and b/admin/template/images/icons/user.gif differ
diff --git a/admin/template/images/informationbar_right.gif b/admin/template/images/informationbar_right.gif
new file mode 100644
index 000000000..66711e280
Binary files /dev/null and b/admin/template/images/informationbar_right.gif differ
diff --git a/admin/template/images/navigation_background_blue.gif b/admin/template/images/navigation_background_blue.gif
new file mode 100644
index 000000000..98e71b97d
Binary files /dev/null and b/admin/template/images/navigation_background_blue.gif differ
diff --git a/admin/template/images/navigation_first_blue.gif b/admin/template/images/navigation_first_blue.gif
new file mode 100644
index 000000000..98b7e8558
Binary files /dev/null and b/admin/template/images/navigation_first_blue.gif differ
diff --git a/admin/template/images/navigation_last_blue.gif b/admin/template/images/navigation_last_blue.gif
new file mode 100644
index 000000000..1b0688e9f
Binary files /dev/null and b/admin/template/images/navigation_last_blue.gif differ
diff --git a/admin/template/images/tabs_bg.gif b/admin/template/images/tabs_bg.gif
new file mode 100644
index 000000000..4c605c9ed
Binary files /dev/null and b/admin/template/images/tabs_bg.gif differ
diff --git a/admin/template/images/tabs_left.gif b/admin/template/images/tabs_left.gif
new file mode 100644
index 000000000..8fbddb78d
Binary files /dev/null and b/admin/template/images/tabs_left.gif differ
diff --git a/admin/template/images/tabs_right.gif b/admin/template/images/tabs_right.gif
new file mode 100644
index 000000000..a80cbc40c
Binary files /dev/null and b/admin/template/images/tabs_right.gif differ
diff --git a/admin/template/js/blend/jquery.blend.js b/admin/template/js/blend/jquery.blend.js
new file mode 100644
index 000000000..1a6bd8159
--- /dev/null
+++ b/admin/template/js/blend/jquery.blend.js
@@ -0,0 +1,133 @@
+/*
+ jQuery Blend v1.1
+ (c) 2009 Jack Moore - www.colorpowered.com - jack@colorpowered.com
+ Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
+*/
+(function($){
+ /*
+ Blend creates a 2nd layer on top of the target element.
+ This layer is faded in and out to create the effect. The orignal, bottom layer
+ has it's class set to 'hover' and remains that way for the duration to
+ keep the CSS :hover state from being apparent when the object is moused-over.
+ */
+
+ $.fn.blend = function(options, callback) {
+
+ var settings = $.extend({}, $.fn.blend.settings, options);
+
+ $(this).each(function(){
+
+ var $this = $(this),
+ $target = $(settings.target ? settings.target : this),
+ $hover,
+ target = [],
+ i,
+ length,
+ style = {},
+ active = false,
+ out = 0,
+ opacity = settings.opacity,
+ properties = [
+ 'background-color',
+ 'background-image',
+ 'background-repeat',
+ 'background-attachment',
+ 'background-position',
+ 'background-position-x',
+ 'background-position-y'
+ ];
+
+ length = properties.length;
+
+ if($target[0].style.position != 'absolute'){
+ $target.css({position:'relative'});
+ }
+
+ if(!$target.hasClass('hover')){
+ $target.wrapInner('
');
+ }
+
+ for (i=0; i
').css(style);
+
+ if(settings.top){
+ $hover.appendTo($target);
+ } else {
+ $hover.prependTo($target);
+ }
+ } else {
+ $hover = $target.find(".jsblend");
+ }
+
+ style = {};
+ for (i=0; i
0 ) {
+
+// We make the .column divs sortable //
+ $(".column").sortable({
+ connectWith: '.column',
+ // We make the .portlet-header to act as a handle for moving portlets //
+ handle: '.portlet-header'
+ });
+ // We create the protlets and style them accordingly by script //
+ $(".portlet").addClass("ui-widget ui-widget-content ui-helper-clearfix ui-corner-all")
+ .find(".portlet-header")
+ .addClass("ui-widget-header ui-corner-top")
+ .prepend(' ')
+ .end()
+ .find(".portlet-content");
+ // We make arrow button on any portlet header to act as a switch for sliding up and down the portlet content //
+ $(".portlet-header .ui-icon").click(function() {
+ $(this).parents(".portlet:first").find(".portlet-content").slideToggle("fast");
+ $(this).toggleClass("ui-icon-triangle-1-s");
+ return false;
+ });
+ // We disable the mouse selection on .column divs //
+ $(".column").disableSelection();
+}
+ // This function is making the info messages to slide up when the X is clicked //
+ $(".info").click(function() {
+ $(this).slideUp("fast");
+ });
+ // This is creating a modal box from a hidden element on the page with id #inline_example1 //
+ $("#inline_example1").dialog({
+ bgiframe: true,
+ autoOpen: false,
+ modal: true
+ });
+ // This is creating a modal box from a hidden element on the page with id #inline_example2 //
+ $("#inline_example2").dialog({
+ bgiframe: false,
+ autoOpen: false,
+ modal: true
+ });
+ // This triggers the modal dialog box //
+ $('.mail').click(function() {
+ $('#inline_example1').dialog('open');
+ })
+ // This toggles the color changer menu //
+ $(".dropdown").click(function() {
+ $("#colorchanger").slideToggle("fast");
+ });
+
+// The functions below are made as FX for table operations //
+if ( $(".approve_icon").length > 0 ) {
+ $(".approve_icon").click(function() {
+ $(this).parents("tr").css({ "background-color" : "#e1fbcd" }, 'fast');
+ // THE ALERT BELOW CAN BE REMOVED - you can put any function here linked to the approve icon link in the table //
+ alert('this is approved');
+ });
+}
+if ( $(".reject_icon").length > 0 ) {
+ $(".reject_icon").click(function() {
+ $(this).parents("tr").css({ "background-color" : "#fbcdcd" }, 'fast');
+ // THE ALERT BELOW CAN BE REMOVED - you can put any function here linked to the reject icon link in the table //
+ alert('this is rejected');
+ });
+}
+
+// This function serves the More submenu ideea - you can attach the class .more to any tabbed link and you will trigger the hidden sub-sub menu to appear when clicked - this can be developed in a nice way if you have an enormous amount of links //
+if ( $(".more").length > 0 ) {
+ $("#tabs .more").click(function() {
+ $("#hidden_submenu").slideToggle("fast");
+ $(this).toggleClass("current"); return false;
+ });
+}
+// This triggers the calendar when clicked on the event tip on the right of the title - dashboard.html - it can be used anywhere in the page //
+if ( $(".hidden_calendar").length > 0 ) {
+ $(".hidden_calendar").datepicker();
+ $(".inline_calendar").click(function() {
+ $(".hidden_calendar").toggle("fast");
+ });
+}
+// This triggers the 2nd modal box when clicked on the TIP link on the right of the title - forms.html //
+if ( $(".inline_tip").length > 0 ) {
+ $(".inline_tip").click(function() {
+ $("#inline_example2").dialog('open');
+ });
+}
+});
+// THE jQuery scripts end here //
+
+// Below is the "allbox" script for selecting all checkboxes in a table by clicking one of them - usualy the on in the table heading //
+
+if ( $("#allbox").length > 0 ) {
+ function checkAll(){
+ for (var i=0;i',' ","");this.element_.insertAdjacentHTML("BeforeEnd",AA.join(""))};J.stroke=function(AF){var k=[];var l=false;var AQ=C(AF?this.fillStyle:this.strokeStyle);var AB=AQ.color;var AL=AQ.alpha*this.globalAlpha;var g=10;var n=10;k.push("x.x){x.x=AJ.x}if(AP.y==null||AJ.yx.y){x.y=AJ.y}}}k.push(' ">');if(!AF){var w=this.lineScale_*this.lineWidth;if(w<1){AL*=w}k.push(" ')}else{if(typeof this.fillStyle=="object"){var o=this.fillStyle;var u=0;var AI={x:0,y:0};var AC=0;var s=1;if(o.type_=="gradient"){var r=o.x0_/this.arcScaleX_;var e=o.y0_/this.arcScaleY_;var q=o.x1_/this.arcScaleX_;var AR=o.y1_/this.arcScaleY_;var AN=this.getCoords_(r,e);var AM=this.getCoords_(q,AR);var j=AM.x-AN.x;var h=AM.y-AN.y;u=Math.atan2(j,h)*180/Math.PI;if(u<0){u+=360}if(u<0.000001){u=0}}else{var AN=this.getCoords_(o.x0_,o.y0_);var Z=x.x-AP.x;var f=x.y-AP.y;AI={x:(AN.x-AP.x)/Z,y:(AN.y-AP.y)/f};Z/=this.arcScaleX_*A;f/=this.arcScaleY_*A;var AH=S.max(Z,f);AC=2*o.r0_/AH;s=2*o.r1_/AH-AC}var AA=o.colors_;AA.sort(function(p,i){return p.offset-i.offset});var v=AA.length;var z=AA[0].color;var y=AA[v-1].color;var AE=AA[0].alpha*this.globalAlpha;var AD=AA[v-1].alpha*this.globalAlpha;var AG=[];for(var AK=0;AK ')}else{k.push(' ')}}k.push(" ");this.element_.insertAdjacentHTML("beforeEnd",k.join(""))};J.fill=function(){this.stroke(true)};J.closePath=function(){this.currentPath_.push({type:"close"})};J.getCoords_=function(f,e){var Z=this.m_;return{x:A*(f*Z[0][0]+e*Z[1][0]+Z[2][0])-L,y:A*(f*Z[0][1]+e*Z[1][1]+Z[2][1])-L}};J.save=function(){var Z={};U(this,Z);this.aStack_.push(Z);this.mStack_.push(this.m_);this.m_=D(O(),this.m_)};J.restore=function(){U(this.aStack_.pop(),this);this.m_=this.mStack_.pop()};function G(Z){for(var f=0;f<3;f++){for(var e=0;e<2;e++){if(!isFinite(Z[f][e])||isNaN(Z[f][e])){return false}}}return true}function Y(e,Z,f){if(!G(Z)){return }e.m_=Z;if(f){var g=Z[0][0]*Z[1][1]-Z[0][1]*Z[1][0];e.lineScale_=b(K(g))}}J.translate=function(f,e){var Z=[[1,0,0],[0,1,0],[f,e,1]];Y(this,D(Z,this.m_),false)};J.rotate=function(e){var g=c(e);var f=P(e);var Z=[[g,f,0],[-f,g,0],[0,0,1]];Y(this,D(Z,this.m_),false)};J.scale=function(f,e){this.arcScaleX_*=f;this.arcScaleY_*=e;var Z=[[f,0,0],[0,e,0],[0,0,1]];Y(this,D(Z,this.m_),true)};J.transform=function(h,g,j,i,e,Z){var f=[[h,g,0],[j,i,0],[e,Z,1]];Y(this,D(f,this.m_),true)};J.setTransform=function(h,g,j,i,f,e){var Z=[[h,g,0],[j,i,0],[f,e,1]];Y(this,Z,true)};J.clip=function(){};J.arcTo=function(){};J.createPattern=function(){return new F};function X(Z){this.type_=Z;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}X.prototype.addColorStop=function(e,Z){Z=C(Z);this.colors_.push({offset:e,color:Z.color,alpha:Z.alpha})};function F(){}G_vmlCanvasManager=I;CanvasRenderingContext2D=N;CanvasGradient=X;CanvasPattern=F})()};
\ No newline at end of file
diff --git a/admin/template/js/flot/jquery.flot.pack.js b/admin/template/js/flot/jquery.flot.pack.js
new file mode 100644
index 000000000..105ed5e57
--- /dev/null
+++ b/admin/template/js/flot/jquery.flot.pack.js
@@ -0,0 +1,2396 @@
+/* Javascript plotting library for jQuery, v. 0.5.
+ *
+ * Released under the MIT license by IOLA, December 2007.
+ *
+ */
+
+(function($) {
+ function Plot(target, data_, options_, plugins) {
+ // data is on the form:
+ // [ series1, series2 ... ]
+ // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
+ // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
+
+ var series = [],
+ options = {
+ // the color theme used for graphs
+ colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
+ legend: {
+ show: true,
+ noColumns: 1, // number of colums in legend table
+ labelFormatter: null, // fn: string -> string
+ labelBoxBorderColor: "#ccc", // border color for the little label boxes
+ container: null, // container (as jQuery object) to put legend in, null means default on top of graph
+ position: "ne", // position of default legend container within plot
+ margin: 5, // distance from grid edge to default legend container within plot
+ backgroundColor: null, // null means auto-detect
+ backgroundOpacity: 0.85 // set to 0 to avoid background
+ },
+ xaxis: {
+ mode: null, // null or "time"
+ min: null, // min. value to show, null means set automatically
+ max: null, // max. value to show, null means set automatically
+ autoscaleMargin: null, // margin in % to add if auto-setting min/max
+ ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
+ tickFormatter: null, // fn: number -> string
+ labelWidth: null, // size of tick labels in pixels
+ labelHeight: null,
+
+ // mode specific options
+ tickDecimals: null, // no. of decimals, null means auto
+ tickSize: null, // number or [number, "unit"]
+ minTickSize: null, // number or [number, "unit"]
+ monthNames: null, // list of names of months
+ timeformat: null // format string to use
+ },
+ yaxis: {
+ autoscaleMargin: 0.02
+ },
+ x2axis: {
+ autoscaleMargin: null
+ },
+ y2axis: {
+ autoscaleMargin: 0.02
+ },
+ series: {
+ points: {
+ show: false,
+ radius: 3,
+ lineWidth: 2, // in pixels
+ fill: true,
+ fillColor: "#ffffff"
+ },
+ lines: {
+ // we don't put in show: false so we can see
+ // whether lines were actively disabled
+ lineWidth: 2, // in pixels
+ fill: false,
+ fillColor: null,
+ steps: false
+ },
+ bars: {
+ show: false,
+ lineWidth: 2, // in pixels
+ barWidth: 1, // in units of the x axis
+ fill: true,
+ fillColor: null,
+ align: "left", // or "center"
+ horizontal: false // when horizontal, left is now top
+ },
+ shadowSize: 3
+ },
+ grid: {
+ show: true,
+ color: "#545454", // primary color used for outline and labels
+ backgroundColor: null, // null for transparent, else color
+ tickColor: "#dddddd", // color used for the ticks
+ labelMargin: 5, // in pixels
+ borderWidth: 2, // in pixels
+ borderColor: null, // set if different from the grid color
+ markings: null, // array of ranges or fn: axes -> array of ranges
+ markingsColor: "#f4f4f4",
+ markingsLineWidth: 2,
+ // interactive stuff
+ clickable: false,
+ hoverable: false,
+ autoHighlight: true, // highlight in case mouse is near
+ mouseActiveRadius: 10 // how far the mouse can be away to activate an item
+ },
+ selection: {
+ mode: null, // one of null, "x", "y" or "xy"
+ color: "#e8cfac"
+ }
+ },
+ canvas = null, // the canvas for the plot itself
+ overlay = null, // canvas for interactive stuff on top of plot
+ eventHolder = null, // jQuery object that events should be bound to
+ ctx = null, octx = null,
+ axes = { xaxis: {}, yaxis: {}, x2axis: {}, y2axis: {} },
+ plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
+ canvasWidth = 0, canvasHeight = 0,
+ plotWidth = 0, plotHeight = 0,
+ hooks = {
+ processOptions: [],
+ processRawData: [],
+ processDatapoints: [],
+ draw: [],
+ bindEvents: [],
+ drawOverlay: []
+ },
+ plot = this,
+ // dedicated to storing data for buggy standard compliance cases
+ workarounds = {};
+
+ // public functions
+ plot.setData = setData;
+ plot.setupGrid = setupGrid;
+ plot.draw = draw;
+ plot.clearSelection = clearSelection;
+ plot.setSelection = setSelection;
+ plot.getSelection = getSelection;
+ plot.getCanvas = function() { return canvas; };
+ plot.getPlotOffset = function() { return plotOffset; };
+ plot.width = function () { return plotWidth; }
+ plot.height = function () { return plotHeight; }
+ plot.offset = function () {
+ var o = eventHolder.offset();
+ o.left += plotOffset.left;
+ o.top += plotOffset.top;
+ return o;
+ };
+ plot.getData = function() { return series; };
+ plot.getAxes = function() { return axes; };
+ plot.getOptions = function() { return options; };
+ plot.highlight = highlight;
+ plot.unhighlight = unhighlight;
+ plot.triggerRedrawOverlay = triggerRedrawOverlay;
+ plot.pointOffset = function(point) {
+ return { left: parseInt(axisSpecToRealAxis(point, "xaxis").p2c(+point.x) + plotOffset.left),
+ top: parseInt(axisSpecToRealAxis(point, "yaxis").p2c(+point.y) + plotOffset.top) };
+ }
+
+
+ // public attributes
+ plot.hooks = hooks;
+
+ // initialize
+ initPlugins(plot);
+ parseOptions(options_);
+ constructCanvas();
+ setData(data_);
+ setupGrid();
+ draw();
+ bindEvents();
+
+
+ function executeHooks(hook, args) {
+ args = [plot].concat(args);
+ for (var i = 0; i < hook.length; ++i)
+ hook[i].apply(this, args);
+ }
+
+ function initPlugins() {
+ for (var i = 0; i < plugins.length; ++i) {
+ var p = plugins[i];
+ p.init(plot);
+ if (p.options)
+ $.extend(true, options, p.options);
+ }
+ }
+
+ function parseOptions(opts) {
+ $.extend(true, options, opts);
+ if (options.grid.borderColor == null)
+ options.grid.borderColor = options.grid.color
+ // backwards compatibility, to be removed in future
+ if (options.xaxis.noTicks && options.xaxis.ticks == null)
+ options.xaxis.ticks = options.xaxis.noTicks;
+ if (options.yaxis.noTicks && options.yaxis.ticks == null)
+ options.yaxis.ticks = options.yaxis.noTicks;
+ if (options.grid.coloredAreas)
+ options.grid.markings = options.grid.coloredAreas;
+ if (options.grid.coloredAreasColor)
+ options.grid.markingsColor = options.grid.coloredAreasColor;
+ if (options.lines)
+ $.extend(true, options.series.lines, options.lines);
+ if (options.points)
+ $.extend(true, options.series.points, options.points);
+ if (options.bars)
+ $.extend(true, options.series.bars, options.bars);
+ if (options.shadowSize)
+ options.series.shadowSize = options.shadowSize;
+
+ executeHooks(hooks.processOptions, [options]);
+ }
+
+ function setData(d) {
+ series = parseData(d);
+ fillInSeriesOptions();
+ processData();
+ }
+
+ function parseData(d) {
+ var res = [];
+ for (var i = 0; i < d.length; ++i) {
+ var s = $.extend(true, {}, options.series);
+
+ if (d[i].data) {
+ s.data = d[i].data; // move the data instead of deep-copy
+ delete d[i].data;
+
+ $.extend(true, s, d[i]);
+
+ d[i].data = s.data;
+ }
+ else
+ s.data = d[i];
+ res.push(s);
+ }
+
+ return res;
+ }
+
+ function axisSpecToRealAxis(obj, attr) {
+ var a = obj[attr];
+ if (!a || a == 1)
+ return axes[attr];
+ if (typeof a == "number")
+ return axes[attr.charAt(0) + a + attr.slice(1)];
+ return a; // assume it's OK
+ }
+
+ function fillInSeriesOptions() {
+ var i;
+
+ // collect what we already got of colors
+ var neededColors = series.length,
+ usedColors = [],
+ assignedColors = [];
+ for (i = 0; i < series.length; ++i) {
+ var sc = series[i].color;
+ if (sc != null) {
+ --neededColors;
+ if (typeof sc == "number")
+ assignedColors.push(sc);
+ else
+ usedColors.push(parseColor(series[i].color));
+ }
+ }
+
+ // we might need to generate more colors if higher indices
+ // are assigned
+ for (i = 0; i < assignedColors.length; ++i) {
+ neededColors = Math.max(neededColors, assignedColors[i] + 1);
+ }
+
+ // produce colors as needed
+ var colors = [], variation = 0;
+ i = 0;
+ while (colors.length < neededColors) {
+ var c;
+ if (options.colors.length == i) // check degenerate case
+ c = new Color(100, 100, 100);
+ else
+ c = parseColor(options.colors[i]);
+
+ // vary color if needed
+ var sign = variation % 2 == 1 ? -1 : 1;
+ var factor = 1 + sign * Math.ceil(variation / 2) * 0.2;
+ c.scale(factor, factor, factor);
+
+ // FIXME: if we're getting to close to something else,
+ // we should probably skip this one
+ colors.push(c);
+
+ ++i;
+ if (i >= options.colors.length) {
+ i = 0;
+ ++variation;
+ }
+ }
+
+ // fill in the options
+ var colori = 0, s;
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+
+ // assign colors
+ if (s.color == null) {
+ s.color = colors[colori].toString();
+ ++colori;
+ }
+ else if (typeof s.color == "number")
+ s.color = colors[s.color].toString();
+
+ // turn on lines automatically in case nothing is set
+ if (s.lines.show == null && !s.bars.show && !s.points.show)
+ s.lines.show = true;
+
+ // setup axes
+ s.xaxis = axisSpecToRealAxis(s, "xaxis");
+ s.yaxis = axisSpecToRealAxis(s, "yaxis");
+ }
+ }
+
+ function processData() {
+ var topSentry = Number.POSITIVE_INFINITY,
+ bottomSentry = Number.NEGATIVE_INFINITY,
+ i, j, k, m, length,
+ s, points, ps, x, y, axis;
+
+ for (axis in axes) {
+ axes[axis].datamin = topSentry;
+ axes[axis].datamax = bottomSentry;
+ axes[axis].min = options[axis].min;
+ axes[axis].max = options[axis].max;
+ axes[axis].used = false;
+ }
+
+ function updateAxis(axis, min, max) {
+ if (min < axis.datamin)
+ axis.datamin = min;
+ if (max > axis.datamax)
+ axis.datamax = max;
+ }
+
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+ s.datapoints = { points: [] };
+
+ executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
+ }
+
+ // first pass: clean and copy data
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+
+ if (s.datapoints.pointsize != null)
+ continue; // already filled in
+
+ var data = s.data, format = [], p;
+
+ // determine the point size
+ if (s.bars.show) {
+ s.datapoints.pointsize = 3;
+ format.push({ d: 0 });
+ }
+ else
+ s.datapoints.pointsize = 2;
+
+ /*
+ // examine data to find out how to copy
+ for (j = 0; j < data.length; ++j) {
+ }*/
+
+ ps = s.datapoints.pointsize;
+ points = s.datapoints.points;
+
+ insertSteps = s.lines.show && s.lines.steps;
+ s.xaxis.used = s.yaxis.used = true;
+
+ for (j = k = 0; j < data.length; ++j, k += ps) {
+ p = data[j];
+
+ if (p != null) {
+ x = p[0];
+ y = p[1];
+ }
+ else
+ y = x = null;
+
+ if (x != null) {
+ x = +x; // convert to number
+ if (isNaN(x))
+ x = null;
+ }
+
+ if (y != null) {
+ y = +y; // convert to number
+ if (isNaN(y))
+ y = null;
+ }
+
+ // check validity of point, making sure both are cleared
+ if (x == null && y != null) {
+ // extract min/max info before we whack
+ updateAxis(s.yaxis, y, y);
+ y = null;
+ }
+
+ if (y == null && x != null) {
+ updateAxis(s.xaxis, x, x);
+ x = null;
+ }
+
+ if (insertSteps && x != null && k > 0
+ && points[k - ps] != null
+ && points[k - ps] != x && points[k - ps + 1] != y) {
+ points[k + 1] = points[k - ps + 1];
+ points[k] = x;
+
+ // copy the remainding from real point
+ for (m = 2; m < ps; ++m)
+ points[k + m] = p[m] == null ? format[m-2].d : p[m];
+ k += ps;
+ }
+
+ for (m = 2; m < ps; ++m)
+ points[k + m] = p == null || p[m] == null ? format[m-2].d : p[m];
+
+ points[k] = x;
+ points[k + 1] = y;
+ }
+ }
+
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+
+ executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
+ }
+
+ // second pass: find datamax/datamin for auto-scaling
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+ points = s.datapoints.points,
+ ps = s.datapoints.pointsize;
+
+ var xmin = topSentry, ymin = topSentry,
+ xmax = bottomSentry, ymax = bottomSentry;
+
+ for (j = 0; j < points.length; j += ps) {
+ x = points[j];
+
+ if (x == null)
+ continue;
+
+ if (x < xmin)
+ xmin = x;
+ if (x > xmax)
+ xmax = x;
+
+ y = points[j + 1];
+
+ if (y < ymin)
+ ymin = y;
+ if (y > ymax)
+ ymax = y;
+ }
+
+ if (s.bars.show) {
+ // make sure we got room for the bar on the dancing floor
+ var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2;
+ if (s.bars.horizontal) {
+ ymin += delta;
+ ymax += delta + s.bars.barWidth;
+ }
+ else {
+ xmin += delta;
+ xmax += delta + s.bars.barWidth;
+ }
+ }
+
+ updateAxis(s.xaxis, xmin, xmax);
+ updateAxis(s.yaxis, ymin, ymax);
+ }
+
+ for (axis in axes) {
+ if (axes[axis].datamin == topSentry)
+ axes[axis].datamin = null;
+ if (axes[axis].datamax == bottomSentry)
+ axes[axis].datamax = null;
+ }
+ }
+
+ function constructCanvas() {
+ function makeCanvas(width, height) {
+ var c = document.createElement('canvas');
+ c.width = width;
+ c.height = height;
+ if ($.browser.msie) // excanvas hack
+ c = window.G_vmlCanvasManager.initElement(c);
+ return c;
+ }
+
+ canvasWidth = target.width();
+ canvasHeight = target.height();
+ target.html(""); // clear target
+ if (target.css("position") == 'static')
+ target.css("position", "relative"); // for positioning labels and overlay
+
+ if (canvasWidth <= 0 || canvasHeight <= 0)
+ throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;
+
+ if ($.browser.msie) // excanvas hack
+ window.G_vmlCanvasManager.init_(document); // make sure everything is setup
+
+ // the canvas
+ canvas = $(makeCanvas(canvasWidth, canvasHeight)).appendTo(target).get(0);
+ ctx = canvas.getContext("2d");
+
+ // overlay canvas for interactive features
+ overlay = $(makeCanvas(canvasWidth, canvasHeight)).css({ position: 'absolute', left: 0, top: 0 }).appendTo(target).get(0);
+ octx = overlay.getContext("2d");
+ octx.stroke();
+ }
+
+ function bindEvents() {
+ // we include the canvas in the event holder too, because IE 7
+ // sometimes has trouble with the stacking order
+ eventHolder = $([overlay, canvas]);
+
+ // bind events
+ if (options.selection.mode != null
+ || options.grid.hoverable)
+ eventHolder.mousemove(onMouseMove);
+
+ if (options.selection.mode != null)
+ eventHolder.mousedown(onMouseDown);
+
+ if (options.grid.clickable)
+ eventHolder.click(onClick);
+
+ executeHooks(hooks.bindEvents, [eventHolder]);
+ }
+
+ function setupGrid() {
+ function setTransformationHelpers(axis) {
+ var s, m;
+
+ // add transformation helpers
+ if (axis == axes.xaxis || axis == axes.x2axis) {
+ // precompute how much the axis is scaling a point
+ // in canvas space
+ s = axis.scale = plotWidth / (axis.max - axis.min);
+ m = axis.min;
+
+ // data point to canvas coordinate
+ axis.p2c = function (p) { return (p - m) * s; };
+ // canvas coordinate to data point
+ axis.c2p = function (c) { return m + c / s; };
+ }
+ else {
+ s = axis.scale = plotHeight / (axis.max - axis.min)
+ m = axis.max;
+
+ axis.p2c = function (p) { return (m - p) * s; };
+ axis.c2p = function (p) { return m - p / s; };
+ }
+ }
+
+ var axis;
+ for (axis in axes)
+ setRange(axes[axis], options[axis]);
+
+ if (options.grid.show) {
+ for (axis in axes) {
+ prepareTickGeneration(axes[axis], options[axis]);
+ setTicks(axes[axis], options[axis]);
+ }
+
+ setGridSpacing();
+ }
+ else {
+ plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = 0;
+ plotWidth = canvasWidth;
+ plotHeight = canvasHeight;
+ }
+
+ for (axis in axes)
+ setTransformationHelpers(axes[axis]);
+
+ if (options.grid.show)
+ insertLabels();
+
+ insertLegend();
+ }
+
+ function setRange(axis, axisOptions) {
+ var min = +(axisOptions.min != null ? axisOptions.min : axis.datamin),
+ max = +(axisOptions.max != null ? axisOptions.max : axis.datamax);
+
+ if (max - min == 0.0) {
+ // degenerate case
+ var widen = max == 0 ? 1 : 0.01;
+
+ if (axisOptions.min == null)
+ min -= widen;
+ // alway widen max if we couldn't widen min to ensure we
+ // don't fall into min == max which doesn't work
+ if (axisOptions.max == null || axisOptions.min != null)
+ max += widen;
+ }
+ else {
+ // consider autoscaling
+ var margin = axisOptions.autoscaleMargin;
+ if (margin != null) {
+ if (axisOptions.min == null) {
+ min -= (max - min) * margin;
+ // make sure we don't go below zero if all values
+ // are positive
+ if (min < 0 && axis.datamin != null && axis.datamin >= 0)
+ min = 0;
+ }
+ if (axisOptions.max == null) {
+ max += (max - min) * margin;
+ if (max > 0 && axis.datamax != null && axis.datamax <= 0)
+ max = 0;
+ }
+ }
+ }
+ axis.min = min;
+ axis.max = max;
+ }
+
+ function prepareTickGeneration(axis, axisOptions) {
+ // estimate number of ticks
+ var noTicks;
+ if (typeof axisOptions.ticks == "number" && axisOptions.ticks > 0)
+ noTicks = axisOptions.ticks;
+ else if (axis == axes.xaxis || axis == axes.x2axis)
+ noTicks = canvasWidth / 100;
+ else
+ noTicks = canvasHeight / 60;
+
+ var delta = (axis.max - axis.min) / noTicks;
+ var size, generator, unit, formatter, i, magn, norm;
+
+ if (axisOptions.mode == "time") {
+ // pretty handling of time
+
+ // map of app. size of time units in milliseconds
+ var timeUnitSize = {
+ "second": 1000,
+ "minute": 60 * 1000,
+ "hour": 60 * 60 * 1000,
+ "day": 24 * 60 * 60 * 1000,
+ "month": 30 * 24 * 60 * 60 * 1000,
+ "year": 365.2425 * 24 * 60 * 60 * 1000
+ };
+
+
+ // the allowed tick sizes, after 1 year we use
+ // an integer algorithm
+ var spec = [
+ [1, "second"], [2, "second"], [5, "second"], [10, "second"],
+ [30, "second"],
+ [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
+ [30, "minute"],
+ [1, "hour"], [2, "hour"], [4, "hour"],
+ [8, "hour"], [12, "hour"],
+ [1, "day"], [2, "day"], [3, "day"],
+ [0.25, "month"], [0.5, "month"], [1, "month"],
+ [2, "month"], [3, "month"], [6, "month"],
+ [1, "year"]
+ ];
+
+ var minSize = 0;
+ if (axisOptions.minTickSize != null) {
+ if (typeof axisOptions.tickSize == "number")
+ minSize = axisOptions.tickSize;
+ else
+ minSize = axisOptions.minTickSize[0] * timeUnitSize[axisOptions.minTickSize[1]];
+ }
+
+ for (i = 0; i < spec.length - 1; ++i)
+ if (delta < (spec[i][0] * timeUnitSize[spec[i][1]]
+ + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
+ && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize)
+ break;
+ size = spec[i][0];
+ unit = spec[i][1];
+
+ // special-case the possibility of several years
+ if (unit == "year") {
+ magn = Math.pow(10, Math.floor(Math.log(delta / timeUnitSize.year) / Math.LN10));
+ norm = (delta / timeUnitSize.year) / magn;
+ if (norm < 1.5)
+ size = 1;
+ else if (norm < 3)
+ size = 2;
+ else if (norm < 7.5)
+ size = 5;
+ else
+ size = 10;
+
+ size *= magn;
+ }
+
+ if (axisOptions.tickSize) {
+ size = axisOptions.tickSize[0];
+ unit = axisOptions.tickSize[1];
+ }
+
+ generator = function(axis) {
+ var ticks = [],
+ tickSize = axis.tickSize[0], unit = axis.tickSize[1],
+ d = new Date(axis.min);
+
+ var step = tickSize * timeUnitSize[unit];
+
+ if (unit == "second")
+ d.setUTCSeconds(floorInBase(d.getUTCSeconds(), tickSize));
+ if (unit == "minute")
+ d.setUTCMinutes(floorInBase(d.getUTCMinutes(), tickSize));
+ if (unit == "hour")
+ d.setUTCHours(floorInBase(d.getUTCHours(), tickSize));
+ if (unit == "month")
+ d.setUTCMonth(floorInBase(d.getUTCMonth(), tickSize));
+ if (unit == "year")
+ d.setUTCFullYear(floorInBase(d.getUTCFullYear(), tickSize));
+
+ // reset smaller components
+ d.setUTCMilliseconds(0);
+ if (step >= timeUnitSize.minute)
+ d.setUTCSeconds(0);
+ if (step >= timeUnitSize.hour)
+ d.setUTCMinutes(0);
+ if (step >= timeUnitSize.day)
+ d.setUTCHours(0);
+ if (step >= timeUnitSize.day * 4)
+ d.setUTCDate(1);
+ if (step >= timeUnitSize.year)
+ d.setUTCMonth(0);
+
+
+ var carry = 0, v = Number.NaN, prev;
+ do {
+ prev = v;
+ v = d.getTime();
+ ticks.push({ v: v, label: axis.tickFormatter(v, axis) });
+ if (unit == "month") {
+ if (tickSize < 1) {
+ // a bit complicated - we'll divide the month
+ // up but we need to take care of fractions
+ // so we don't end up in the middle of a day
+ d.setUTCDate(1);
+ var start = d.getTime();
+ d.setUTCMonth(d.getUTCMonth() + 1);
+ var end = d.getTime();
+ d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
+ carry = d.getUTCHours();
+ d.setUTCHours(0);
+ }
+ else
+ d.setUTCMonth(d.getUTCMonth() + tickSize);
+ }
+ else if (unit == "year") {
+ d.setUTCFullYear(d.getUTCFullYear() + tickSize);
+ }
+ else
+ d.setTime(v + step);
+ } while (v < axis.max && v != prev);
+
+ return ticks;
+ };
+
+ formatter = function (v, axis) {
+ var d = new Date(v);
+
+ // first check global format
+ if (axisOptions.timeformat != null)
+ return $.plot.formatDate(d, axisOptions.timeformat, axisOptions.monthNames);
+
+ var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
+ var span = axis.max - axis.min;
+
+ if (t < timeUnitSize.minute)
+ fmt = "%h:%M:%S";
+ else if (t < timeUnitSize.day) {
+ if (span < 2 * timeUnitSize.day)
+ fmt = "%h:%M";
+ else
+ fmt = "%b %d %h:%M";
+ }
+ else if (t < timeUnitSize.month)
+ fmt = "%b %d";
+ else if (t < timeUnitSize.year) {
+ if (span < timeUnitSize.year)
+ fmt = "%b";
+ else
+ fmt = "%b %y";
+ }
+ else
+ fmt = "%y";
+
+ return $.plot.formatDate(d, fmt, axisOptions.monthNames);
+ };
+ }
+ else {
+ // pretty rounding of base-10 numbers
+ var maxDec = axisOptions.tickDecimals;
+ var dec = -Math.floor(Math.log(delta) / Math.LN10);
+ if (maxDec != null && dec > maxDec)
+ dec = maxDec;
+
+ magn = Math.pow(10, -dec);
+ norm = delta / magn; // norm is between 1.0 and 10.0
+
+ if (norm < 1.5)
+ size = 1;
+ else if (norm < 3) {
+ size = 2;
+ // special case for 2.5, requires an extra decimal
+ if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
+ size = 2.5;
+ ++dec;
+ }
+ }
+ else if (norm < 7.5)
+ size = 5;
+ else
+ size = 10;
+
+ size *= magn;
+
+ if (axisOptions.minTickSize != null && size < axisOptions.minTickSize)
+ size = axisOptions.minTickSize;
+
+ if (axisOptions.tickSize != null)
+ size = axisOptions.tickSize;
+
+ axis.tickDecimals = Math.max(0, (maxDec != null) ? maxDec : dec);
+
+ generator = function (axis) {
+ var ticks = [];
+
+ // spew out all possible ticks
+ var start = floorInBase(axis.min, axis.tickSize),
+ i = 0, v = Number.NaN, prev;
+ do {
+ prev = v;
+ v = start + i * axis.tickSize;
+ ticks.push({ v: v, label: axis.tickFormatter(v, axis) });
+ ++i;
+ } while (v < axis.max && v != prev);
+ return ticks;
+ };
+
+ formatter = function (v, axis) {
+ return v.toFixed(axis.tickDecimals);
+ };
+ }
+
+ axis.tickSize = unit ? [size, unit] : size;
+ axis.tickGenerator = generator;
+ if ($.isFunction(axisOptions.tickFormatter))
+ axis.tickFormatter = function (v, axis) { return "" + axisOptions.tickFormatter(v, axis); };
+ else
+ axis.tickFormatter = formatter;
+ if (axisOptions.labelWidth != null)
+ axis.labelWidth = axisOptions.labelWidth;
+ if (axisOptions.labelHeight != null)
+ axis.labelHeight = axisOptions.labelHeight;
+ }
+
+ function setTicks(axis, axisOptions) {
+ axis.ticks = [];
+
+ if (!axis.used)
+ return;
+
+ if (axisOptions.ticks == null)
+ axis.ticks = axis.tickGenerator(axis);
+ else if (typeof axisOptions.ticks == "number") {
+ if (axisOptions.ticks > 0)
+ axis.ticks = axis.tickGenerator(axis);
+ }
+ else if (axisOptions.ticks) {
+ var ticks = axisOptions.ticks;
+
+ if ($.isFunction(ticks))
+ // generate the ticks
+ ticks = ticks({ min: axis.min, max: axis.max });
+
+ // clean up the user-supplied ticks, copy them over
+ var i, v;
+ for (i = 0; i < ticks.length; ++i) {
+ var label = null;
+ var t = ticks[i];
+ if (typeof t == "object") {
+ v = t[0];
+ if (t.length > 1)
+ label = t[1];
+ }
+ else
+ v = t;
+ if (label == null)
+ label = axis.tickFormatter(v, axis);
+ axis.ticks[i] = { v: v, label: label };
+ }
+ }
+
+ if (axisOptions.autoscaleMargin != null && axis.ticks.length > 0) {
+ // snap to ticks
+ if (axisOptions.min == null)
+ axis.min = Math.min(axis.min, axis.ticks[0].v);
+ if (axisOptions.max == null && axis.ticks.length > 1)
+ axis.max = Math.min(axis.max, axis.ticks[axis.ticks.length - 1].v);
+ }
+ }
+
+ function setGridSpacing() {
+ function measureXLabels(axis) {
+ // to avoid measuring the widths of the labels, we
+ // construct fixed-size boxes and put the labels inside
+ // them, we don't need the exact figures and the
+ // fixed-size box content is easy to center
+ if (axis.labelWidth == null)
+ axis.labelWidth = canvasWidth / 6;
+
+ // measure x label heights
+ if (axis.labelHeight == null) {
+ labels = [];
+ for (i = 0; i < axis.ticks.length; ++i) {
+ l = axis.ticks[i].label;
+ if (l)
+ labels.push('' + l + '
');
+ }
+
+ axis.labelHeight = 0;
+ if (labels.length > 0) {
+ var dummyDiv = $(''
+ + labels.join("") + '
').appendTo(target);
+ axis.labelHeight = dummyDiv.height();
+ dummyDiv.remove();
+ }
+ }
+ }
+
+ function measureYLabels(axis) {
+ if (axis.labelWidth == null || axis.labelHeight == null) {
+ var i, labels = [], l;
+ // calculate y label dimensions
+ for (i = 0; i < axis.ticks.length; ++i) {
+ l = axis.ticks[i].label;
+ if (l)
+ labels.push('' + l + '
');
+ }
+
+ if (labels.length > 0) {
+ var dummyDiv = $(''
+ + labels.join("") + '
').appendTo(target);
+ if (axis.labelWidth == null)
+ axis.labelWidth = dummyDiv.width();
+ if (axis.labelHeight == null)
+ axis.labelHeight = dummyDiv.find("div").height();
+ dummyDiv.remove();
+ }
+
+ if (axis.labelWidth == null)
+ axis.labelWidth = 0;
+ if (axis.labelHeight == null)
+ axis.labelHeight = 0;
+ }
+ }
+
+ // get the most space needed around the grid for things
+ // that may stick out
+ var maxOutset = options.grid.borderWidth;
+ for (i = 0; i < series.length; ++i)
+ maxOutset = Math.max(maxOutset, 2 * (series[i].points.radius + series[i].points.lineWidth/2));
+
+ plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = maxOutset;
+
+ var margin = options.grid.labelMargin + options.grid.borderWidth;
+
+ measureXLabels(axes.xaxis);
+ measureYLabels(axes.yaxis);
+ measureXLabels(axes.x2axis);
+ measureYLabels(axes.y2axis);
+
+ if (axes.xaxis.labelHeight > 0)
+ plotOffset.bottom = Math.max(maxOutset, axes.xaxis.labelHeight + margin);
+ if (axes.yaxis.labelWidth > 0)
+ plotOffset.left = Math.max(maxOutset, axes.yaxis.labelWidth + margin);
+
+ if (axes.x2axis.labelHeight > 0)
+ plotOffset.top = Math.max(maxOutset, axes.x2axis.labelHeight + margin);
+
+ if (axes.y2axis.labelWidth > 0)
+ plotOffset.right = Math.max(maxOutset, axes.y2axis.labelWidth + margin);
+
+ plotWidth = canvasWidth - plotOffset.left - plotOffset.right;
+ plotHeight = canvasHeight - plotOffset.bottom - plotOffset.top;
+ }
+
+ function draw() {
+ if (options.grid.show)
+ drawGrid();
+
+ for (var i = 0; i < series.length; ++i)
+ drawSeries(series[i]);
+
+ executeHooks(hooks.draw, [ctx]);
+ }
+
+ function extractRange(ranges, coord) {
+ var firstAxis = coord + "axis",
+ secondaryAxis = coord + "2axis",
+ axis, from, to, reverse;
+
+ if (ranges[firstAxis]) {
+ axis = axes[firstAxis];
+ from = ranges[firstAxis].from;
+ to = ranges[firstAxis].to;
+ }
+ else if (ranges[secondaryAxis]) {
+ axis = axes[secondaryAxis];
+ from = ranges[secondaryAxis].from;
+ to = ranges[secondaryAxis].to;
+ }
+ else {
+ // backwards-compat stuff - to be removed in future
+ axis = axes[firstAxis];
+ from = ranges[coord + "1"];
+ to = ranges[coord + "2"];
+ }
+
+ // auto-reverse as an added bonus
+ if (from != null && to != null && from > to)
+ return { from: to, to: from, axis: axis };
+
+ return { from: from, to: to, axis: axis };
+ }
+
+ function drawGrid() {
+ var i;
+
+ ctx.save();
+ ctx.clearRect(0, 0, canvasWidth, canvasHeight);
+ ctx.translate(plotOffset.left, plotOffset.top);
+
+ // draw background, if any
+ if (options.grid.backgroundColor) {
+ ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
+ ctx.fillRect(0, 0, plotWidth, plotHeight);
+ }
+
+ // draw markings
+ var markings = options.grid.markings;
+ if (markings) {
+ if ($.isFunction(markings))
+ // xmin etc. are backwards-compatible, to be removed in future
+ markings = markings({ xmin: axes.xaxis.min, xmax: axes.xaxis.max, ymin: axes.yaxis.min, ymax: axes.yaxis.max, xaxis: axes.xaxis, yaxis: axes.yaxis, x2axis: axes.x2axis, y2axis: axes.y2axis });
+
+ for (i = 0; i < markings.length; ++i) {
+ var m = markings[i],
+ xrange = extractRange(m, "x"),
+ yrange = extractRange(m, "y");
+
+ // fill in missing
+ if (xrange.from == null)
+ xrange.from = xrange.axis.min;
+ if (xrange.to == null)
+ xrange.to = xrange.axis.max;
+ if (yrange.from == null)
+ yrange.from = yrange.axis.min;
+ if (yrange.to == null)
+ yrange.to = yrange.axis.max;
+
+ // clip
+ if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
+ yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
+ continue;
+
+ xrange.from = Math.max(xrange.from, xrange.axis.min);
+ xrange.to = Math.min(xrange.to, xrange.axis.max);
+ yrange.from = Math.max(yrange.from, yrange.axis.min);
+ yrange.to = Math.min(yrange.to, yrange.axis.max);
+
+ if (xrange.from == xrange.to && yrange.from == yrange.to)
+ continue;
+
+ // then draw
+ xrange.from = xrange.axis.p2c(xrange.from);
+ xrange.to = xrange.axis.p2c(xrange.to);
+ yrange.from = yrange.axis.p2c(yrange.from);
+ yrange.to = yrange.axis.p2c(yrange.to);
+
+ if (xrange.from == xrange.to || yrange.from == yrange.to) {
+ // draw line
+ ctx.strokeStyle = m.color || options.grid.markingsColor;
+ ctx.beginPath();
+ ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth;
+ //ctx.moveTo(Math.floor(xrange.from), yrange.from);
+ //ctx.lineTo(Math.floor(xrange.to), yrange.to);
+ ctx.moveTo(xrange.from, yrange.from);
+ ctx.lineTo(xrange.to, yrange.to);
+ ctx.stroke();
+ }
+ else {
+ // fill area
+ ctx.fillStyle = m.color || options.grid.markingsColor;
+ ctx.fillRect(xrange.from, yrange.to,
+ xrange.to - xrange.from,
+ yrange.from - yrange.to);
+ }
+ }
+ }
+
+ // draw the inner grid
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = options.grid.tickColor;
+ ctx.beginPath();
+ var v, axis = axes.xaxis;
+ for (i = 0; i < axis.ticks.length; ++i) {
+ v = axis.ticks[i].v;
+ if (v <= axis.min || v >= axes.xaxis.max)
+ continue; // skip those lying on the axes
+
+ ctx.moveTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, 0);
+ ctx.lineTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, plotHeight);
+ }
+
+ axis = axes.yaxis;
+ for (i = 0; i < axis.ticks.length; ++i) {
+ v = axis.ticks[i].v;
+ if (v <= axis.min || v >= axis.max)
+ continue;
+
+ ctx.moveTo(0, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
+ ctx.lineTo(plotWidth, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
+ }
+
+ axis = axes.x2axis;
+ for (i = 0; i < axis.ticks.length; ++i) {
+ v = axis.ticks[i].v;
+ if (v <= axis.min || v >= axis.max)
+ continue;
+
+ ctx.moveTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, -5);
+ ctx.lineTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, 5);
+ }
+
+ axis = axes.y2axis;
+ for (i = 0; i < axis.ticks.length; ++i) {
+ v = axis.ticks[i].v;
+ if (v <= axis.min || v >= axis.max)
+ continue;
+
+ ctx.moveTo(plotWidth-5, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
+ ctx.lineTo(plotWidth+5, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
+ }
+
+ ctx.stroke();
+
+ if (options.grid.borderWidth) {
+ // draw border
+ var bw = options.grid.borderWidth;
+ ctx.lineWidth = bw;
+ ctx.strokeStyle = options.grid.borderColor;
+ ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
+ }
+
+ ctx.restore();
+ }
+
+ function insertLabels() {
+ target.find(".tickLabels").remove();
+
+ var html = [''];
+
+ function addLabels(axis, labelGenerator) {
+ for (var i = 0; i < axis.ticks.length; ++i) {
+ var tick = axis.ticks[i];
+ if (!tick.label || tick.v < axis.min || tick.v > axis.max)
+ continue;
+ html.push(labelGenerator(tick, axis));
+ }
+ }
+
+ var margin = options.grid.labelMargin + options.grid.borderWidth;
+
+ addLabels(axes.xaxis, function (tick, axis) {
+ return '
' + tick.label + "
";
+ });
+
+
+ addLabels(axes.yaxis, function (tick, axis) {
+ return '
' + tick.label + "
";
+ });
+
+ addLabels(axes.x2axis, function (tick, axis) {
+ return '
' + tick.label + "
";
+ });
+
+ addLabels(axes.y2axis, function (tick, axis) {
+ return '
' + tick.label + "
";
+ });
+
+ html.push('
');
+
+ target.append(html.join(""));
+ }
+
+ function drawSeries(series) {
+ if (series.lines.show)
+ drawSeriesLines(series);
+ if (series.bars.show)
+ drawSeriesBars(series);
+ if (series.points.show)
+ drawSeriesPoints(series);
+ }
+
+ function drawSeriesLines(series) {
+ function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
+ var points = datapoints.points,
+ ps = datapoints.pointsize,
+ prevx = null, prevy = null;
+
+ ctx.beginPath();
+ for (var i = ps; i < points.length; i += ps) {
+ var x1 = points[i - ps], y1 = points[i - ps + 1],
+ x2 = points[i], y2 = points[i + 1];
+
+ if (x1 == null || x2 == null)
+ continue;
+
+ // clip with ymin
+ if (y1 <= y2 && y1 < axisy.min) {
+ if (y2 < axisy.min)
+ continue; // line segment is outside
+ // compute new intersection point
+ x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.min;
+ }
+ else if (y2 <= y1 && y2 < axisy.min) {
+ if (y1 < axisy.min)
+ continue;
+ x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.min;
+ }
+
+ // clip with ymax
+ if (y1 >= y2 && y1 > axisy.max) {
+ if (y2 > axisy.max)
+ continue;
+ x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.max;
+ }
+ else if (y2 >= y1 && y2 > axisy.max) {
+ if (y1 > axisy.max)
+ continue;
+ x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.max;
+ }
+
+ // clip with xmin
+ if (x1 <= x2 && x1 < axisx.min) {
+ if (x2 < axisx.min)
+ continue;
+ y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.min;
+ }
+ else if (x2 <= x1 && x2 < axisx.min) {
+ if (x1 < axisx.min)
+ continue;
+ y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.min;
+ }
+
+ // clip with xmax
+ if (x1 >= x2 && x1 > axisx.max) {
+ if (x2 > axisx.max)
+ continue;
+ y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.max;
+ }
+ else if (x2 >= x1 && x2 > axisx.max) {
+ if (x1 > axisx.max)
+ continue;
+ y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.max;
+ }
+
+ if (x1 != prevx || y1 != prevy)
+ ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
+
+ prevx = x2;
+ prevy = y2;
+ ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
+ }
+ ctx.stroke();
+ }
+
+ function plotLineArea(datapoints, axisx, axisy) {
+ var points = datapoints.points,
+ ps = datapoints.pointsize,
+ bottom = Math.min(Math.max(0, axisy.min), axisy.max),
+ top, lastX = 0, areaOpen = false;
+
+ for (var i = ps; i < points.length; i += ps) {
+ var x1 = points[i - ps], y1 = points[i - ps + 1],
+ x2 = points[i], y2 = points[i + 1];
+
+ if (areaOpen && x1 != null && x2 == null) {
+ // close area
+ ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom));
+ ctx.fill();
+ areaOpen = false;
+ continue;
+ }
+
+ if (x1 == null || x2 == null)
+ continue;
+
+ // clip x values
+
+ // clip with xmin
+ if (x1 <= x2 && x1 < axisx.min) {
+ if (x2 < axisx.min)
+ continue;
+ y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.min;
+ }
+ else if (x2 <= x1 && x2 < axisx.min) {
+ if (x1 < axisx.min)
+ continue;
+ y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.min;
+ }
+
+ // clip with xmax
+ if (x1 >= x2 && x1 > axisx.max) {
+ if (x2 > axisx.max)
+ continue;
+ y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.max;
+ }
+ else if (x2 >= x1 && x2 > axisx.max) {
+ if (x1 > axisx.max)
+ continue;
+ y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.max;
+ }
+
+ if (!areaOpen) {
+ // open area
+ ctx.beginPath();
+ ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
+ areaOpen = true;
+ }
+
+ // now first check the case where both is outside
+ if (y1 >= axisy.max && y2 >= axisy.max) {
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
+ lastX = x2;
+ continue;
+ }
+ else if (y1 <= axisy.min && y2 <= axisy.min) {
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
+ lastX = x2;
+ continue;
+ }
+
+ // else it's a bit more complicated, there might
+ // be two rectangles and two triangles we need to fill
+ // in; to find these keep track of the current x values
+ var x1old = x1, x2old = x2;
+
+ // and clip the y values, without shortcutting
+
+ // clip with ymin
+ if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
+ x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.min;
+ }
+ else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
+ x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.min;
+ }
+
+ // clip with ymax
+ if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
+ x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.max;
+ }
+ else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
+ x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.max;
+ }
+
+
+ // if the x value was changed we got a rectangle
+ // to fill
+ if (x1 != x1old) {
+ if (y1 <= axisy.min)
+ top = axisy.min;
+ else
+ top = axisy.max;
+
+ ctx.lineTo(axisx.p2c(x1old), axisy.p2c(top));
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(top));
+ }
+
+ // fill the triangles
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
+
+ // fill the other rectangle if it's there
+ if (x2 != x2old) {
+ if (y2 <= axisy.min)
+ top = axisy.min;
+ else
+ top = axisy.max;
+
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(top));
+ ctx.lineTo(axisx.p2c(x2old), axisy.p2c(top));
+ }
+
+ lastX = Math.max(x2, x2old);
+ }
+
+ if (areaOpen) {
+ ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom));
+ ctx.fill();
+ }
+ }
+
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+ ctx.lineJoin = "round";
+
+ var lw = series.lines.lineWidth,
+ sw = series.shadowSize;
+ // FIXME: consider another form of shadow when filling is turned on
+ if (lw > 0 && sw > 0) {
+ // draw shadow as a thick and thin line with transparency
+ ctx.lineWidth = sw;
+ ctx.strokeStyle = "rgba(0,0,0,0.1)";
+ // position shadow at angle from the mid of line
+ var angle = Math.PI/18;
+ plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);
+ ctx.lineWidth = sw/2;
+ plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);
+ }
+
+ ctx.lineWidth = lw;
+ ctx.strokeStyle = series.color;
+ var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
+ if (fillStyle) {
+ ctx.fillStyle = fillStyle;
+ plotLineArea(series.datapoints, series.xaxis, series.yaxis);
+ }
+
+ if (lw > 0)
+ plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
+ ctx.restore();
+ }
+
+ function drawSeriesPoints(series) {
+ function plotPoints(datapoints, radius, fillStyle, offset, circumference, axisx, axisy) {
+ var points = datapoints.points, ps = datapoints.pointsize;
+
+ for (var i = 0; i < points.length; i += ps) {
+ var x = points[i], y = points[i + 1];
+ if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
+ continue;
+
+ ctx.beginPath();
+ ctx.arc(axisx.p2c(x), axisy.p2c(y) + offset, radius, 0, circumference, false);
+ if (fillStyle) {
+ ctx.fillStyle = fillStyle;
+ ctx.fill();
+ }
+ ctx.stroke();
+ }
+ }
+
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+
+ var lw = series.lines.lineWidth,
+ sw = series.shadowSize,
+ radius = series.points.radius;
+ if (lw > 0 && sw > 0) {
+ // draw shadow in two steps
+ var w = sw / 2;
+ ctx.lineWidth = w;
+ ctx.strokeStyle = "rgba(0,0,0,0.1)";
+ plotPoints(series.datapoints, radius, null, w + w/2, Math.PI,
+ series.xaxis, series.yaxis);
+
+ ctx.strokeStyle = "rgba(0,0,0,0.2)";
+ plotPoints(series.datapoints, radius, null, w/2, Math.PI,
+ series.xaxis, series.yaxis);
+ }
+
+ ctx.lineWidth = lw;
+ ctx.strokeStyle = series.color;
+ plotPoints(series.datapoints, radius,
+ getFillStyle(series.points, series.color), 0, 2 * Math.PI,
+ series.xaxis, series.yaxis);
+ ctx.restore();
+ }
+
+ function drawBar(x, y, b, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c, horizontal) {
+ var left, right, bottom, top,
+ drawLeft, drawRight, drawTop, drawBottom,
+ tmp;
+
+ if (horizontal) {
+ drawBottom = drawRight = drawTop = true;
+ drawLeft = false;
+ left = b;
+ right = x;
+ top = y + barLeft;
+ bottom = y + barRight;
+
+ // account for negative bars
+ if (right < left) {
+ tmp = right;
+ right = left;
+ left = tmp;
+ drawLeft = true;
+ drawRight = false;
+ }
+ }
+ else {
+ drawLeft = drawRight = drawTop = true;
+ drawBottom = false;
+ left = x + barLeft;
+ right = x + barRight;
+ bottom = b;
+ top = y;
+
+ // account for negative bars
+ if (top < bottom) {
+ tmp = top;
+ top = bottom;
+ bottom = tmp;
+ drawBottom = true;
+ drawTop = false;
+ }
+ }
+
+ // clip
+ if (right < axisx.min || left > axisx.max ||
+ top < axisy.min || bottom > axisy.max)
+ return;
+
+ if (left < axisx.min) {
+ left = axisx.min;
+ drawLeft = false;
+ }
+
+ if (right > axisx.max) {
+ right = axisx.max;
+ drawRight = false;
+ }
+
+ if (bottom < axisy.min) {
+ bottom = axisy.min;
+ drawBottom = false;
+ }
+
+ if (top > axisy.max) {
+ top = axisy.max;
+ drawTop = false;
+ }
+
+ left = axisx.p2c(left);
+ bottom = axisy.p2c(bottom);
+ right = axisx.p2c(right);
+ top = axisy.p2c(top);
+
+ // fill the bar
+ if (fillStyleCallback) {
+ c.beginPath();
+ c.moveTo(left, bottom);
+ c.lineTo(left, top);
+ c.lineTo(right, top);
+ c.lineTo(right, bottom);
+ c.fillStyle = fillStyleCallback(bottom, top);
+ c.fill();
+ }
+
+ // draw outline
+ if (drawLeft || drawRight || drawTop || drawBottom) {
+ c.beginPath();
+
+ // FIXME: inline moveTo is buggy with excanvas
+ c.moveTo(left, bottom + offset);
+ if (drawLeft)
+ c.lineTo(left, top + offset);
+ else
+ c.moveTo(left, top + offset);
+ if (drawTop)
+ c.lineTo(right, top + offset);
+ else
+ c.moveTo(right, top + offset);
+ if (drawRight)
+ c.lineTo(right, bottom + offset);
+ else
+ c.moveTo(right, bottom + offset);
+ if (drawBottom)
+ c.lineTo(left, bottom + offset);
+ else
+ c.moveTo(left, bottom + offset);
+ c.stroke();
+ }
+ }
+
+ function drawSeriesBars(series) {
+ function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {
+ var points = datapoints.points, ps = datapoints.pointsize;
+
+ for (var i = 0; i < points.length; i += ps) {
+ if (points[i] == null)
+ continue;
+ drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal);
+ }
+ }
+
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+
+ // FIXME: figure out a way to add shadows (for instance along the right edge)
+ ctx.lineWidth = series.bars.lineWidth;
+ ctx.strokeStyle = series.color;
+ var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
+ var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
+ plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis);
+ ctx.restore();
+ }
+
+ function getFillStyle(filloptions, seriesColor, bottom, top) {
+ var fill = filloptions.fill;
+ if (!fill)
+ return null;
+
+ if (filloptions.fillColor)
+ return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
+
+ var c = parseColor(seriesColor);
+ c.a = typeof fill == "number" ? fill : 0.4;
+ c.normalize();
+ return c.toString();
+ }
+
+ function insertLegend() {
+ target.find(".legend").remove();
+
+ if (!options.legend.show)
+ return;
+
+ var fragments = [], rowStarted = false,
+ lf = options.legend.labelFormatter, s, label;
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+ label = s.label;
+ if (!label)
+ continue;
+
+ if (i % options.legend.noColumns == 0) {
+ if (rowStarted)
+ fragments.push('');
+ fragments.push('');
+ rowStarted = true;
+ }
+
+ if (lf)
+ label = lf(label, s);
+
+ fragments.push(
+ ' ' +
+ '' + label + ' ');
+ }
+ if (rowStarted)
+ fragments.push(' ');
+
+ if (fragments.length == 0)
+ return;
+
+ var table = '' + fragments.join("") + '
';
+ if (options.legend.container != null)
+ $(options.legend.container).html(table);
+ else {
+ var pos = "",
+ p = options.legend.position,
+ m = options.legend.margin;
+ if (m[0] == null)
+ m = [m, m];
+ if (p.charAt(0) == "n")
+ pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
+ else if (p.charAt(0) == "s")
+ pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
+ if (p.charAt(1) == "e")
+ pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
+ else if (p.charAt(1) == "w")
+ pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
+ var legend = $('' + table.replace('style="', 'style="position:absolute;' + pos +';') + '
').appendTo(target);
+ if (options.legend.backgroundOpacity != 0.0) {
+ // put in the transparent background
+ // separately to avoid blended labels and
+ // label boxes
+ var c = options.legend.backgroundColor;
+ if (c == null) {
+ var tmp;
+ if (options.grid.backgroundColor && typeof options.grid.backgroundColor == "string")
+ tmp = options.grid.backgroundColor;
+ else
+ tmp = extractColor(legend);
+ c = parseColor(tmp).adjust(null, null, null, 1).toString();
+ }
+ var div = legend.children();
+ $('
').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
+ }
+ }
+ }
+
+
+ // interactive features
+
+ var lastMousePos = { pageX: null, pageY: null },
+ selection = {
+ first: { x: -1, y: -1}, second: { x: -1, y: -1},
+ show: false,
+ active: false
+ },
+ highlights = [],
+ clickIsMouseUp = false,
+ redrawTimeout = null,
+ hoverTimeout = null;
+
+ // returns the data item the mouse is over, or null if none is found
+ function findNearbyItem(mouseX, mouseY, seriesFilter) {
+ var maxDistance = options.grid.mouseActiveRadius,
+ lowestDistance = maxDistance * maxDistance + 1,
+ item = null, foundPoint = false, i, j;
+
+ for (var i = 0; i < series.length; ++i) {
+ if (!seriesFilter(series[i]))
+ continue;
+
+ var s = series[i],
+ axisx = s.xaxis,
+ axisy = s.yaxis,
+ points = s.datapoints.points,
+ ps = s.datapoints.pointsize,
+ mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
+ my = axisy.c2p(mouseY),
+ maxx = maxDistance / axisx.scale,
+ maxy = maxDistance / axisy.scale;
+
+ if (s.lines.show || s.points.show) {
+ for (j = 0; j < points.length; j += ps) {
+ var x = points[j], y = points[j + 1];
+ if (x == null)
+ continue;
+
+ // For points and lines, the cursor must be within a
+ // certain distance to the data point
+ if (x - mx > maxx || x - mx < -maxx ||
+ y - my > maxy || y - my < -maxy)
+ continue;
+
+ // We have to calculate distances in pixels, not in
+ // data units, because the scales of the axes may be different
+ var dx = Math.abs(axisx.p2c(x) - mouseX),
+ dy = Math.abs(axisy.p2c(y) - mouseY),
+ dist = dx * dx + dy * dy; // no idea in taking sqrt
+ if (dist < lowestDistance) {
+ lowestDistance = dist;
+ item = [i, j / ps];
+ }
+ }
+ }
+
+ if (s.bars.show && !item) { // no other point can be nearby
+ var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2,
+ barRight = barLeft + s.bars.barWidth;
+
+ for (j = 0; j < points.length; j += ps) {
+ var x = points[j], y = points[j + 1], b = points[j + 2];
+ if (x == null)
+ continue;
+
+ // for a bar graph, the cursor must be inside the bar
+ if (series[i].bars.horizontal ?
+ (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&
+ my >= y + barLeft && my <= y + barRight) :
+ (mx >= x + barLeft && mx <= x + barRight &&
+ my >= Math.min(b, y) && my <= Math.max(b, y)))
+ item = [i, j / ps];
+ }
+ }
+ }
+
+ if (item) {
+ i = item[0];
+ j = item[1];
+
+ return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
+ dataIndex: j,
+ series: series[i],
+ seriesIndex: i };
+ }
+
+ return null;
+ }
+
+ function onMouseMove(e) {
+ lastMousePos.pageX = e.pageX;
+ lastMousePos.pageY = e.pageY;
+
+ if (options.grid.hoverable)
+ triggerClickHoverEvent("plothover", lastMousePos,
+ function (s) { return s["hoverable"] != false; });
+
+ if (selection.active) {
+ target.trigger("plotselecting", [ getSelection() ]);
+
+ updateSelection(lastMousePos);
+ }
+ }
+
+ function onMouseDown(e) {
+ if (e.which != 1) // only accept left-click
+ return;
+
+ // cancel out any text selections
+ document.body.focus();
+
+ // prevent text selection and drag in old-school browsers
+ if (document.onselectstart !== undefined && workarounds.onselectstart == null) {
+ workarounds.onselectstart = document.onselectstart;
+ document.onselectstart = function () { return false; };
+ }
+ if (document.ondrag !== undefined && workarounds.ondrag == null) {
+ workarounds.ondrag = document.ondrag;
+ document.ondrag = function () { return false; };
+ }
+
+ setSelectionPos(selection.first, e);
+
+ lastMousePos.pageX = null;
+ selection.active = true;
+ $(document).one("mouseup", onSelectionMouseUp);
+ }
+
+ function onClick(e) {
+ if (clickIsMouseUp) {
+ clickIsMouseUp = false;
+ return;
+ }
+
+ triggerClickHoverEvent("plotclick", e,
+ function (s) { return s["clickable"] != false; });
+ }
+
+ // trigger click or hover event (they send the same parameters
+ // so we share their code)
+ function triggerClickHoverEvent(eventname, event, seriesFilter) {
+ var offset = eventHolder.offset(),
+ pos = { pageX: event.pageX, pageY: event.pageY },
+ canvasX = event.pageX - offset.left - plotOffset.left,
+ canvasY = event.pageY - offset.top - plotOffset.top;
+
+ if (axes.xaxis.used)
+ pos.x = axes.xaxis.c2p(canvasX);
+ if (axes.yaxis.used)
+ pos.y = axes.yaxis.c2p(canvasY);
+ if (axes.x2axis.used)
+ pos.x2 = axes.x2axis.c2p(canvasX);
+ if (axes.y2axis.used)
+ pos.y2 = axes.y2axis.c2p(canvasY);
+
+ var item = findNearbyItem(canvasX, canvasY, seriesFilter);
+
+ if (item) {
+ // fill in mouse pos for any listeners out there
+ item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left);
+ item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top);
+ }
+
+ if (options.grid.autoHighlight) {
+ // clear auto-highlights
+ for (var i = 0; i < highlights.length; ++i) {
+ var h = highlights[i];
+ if (h.auto == eventname &&
+ !(item && h.series == item.series && h.point == item.datapoint))
+ unhighlight(h.series, h.point);
+ }
+
+ if (item)
+ highlight(item.series, item.datapoint, eventname);
+ }
+
+ target.trigger(eventname, [ pos, item ]);
+ }
+
+ function triggerRedrawOverlay() {
+ if (!redrawTimeout)
+ redrawTimeout = setTimeout(drawOverlay, 30);
+ }
+
+ function drawOverlay() {
+ redrawTimeout = null;
+
+ // draw highlights
+ octx.save();
+ octx.clearRect(0, 0, canvasWidth, canvasHeight);
+ octx.translate(plotOffset.left, plotOffset.top);
+
+ var i, hi;
+ for (i = 0; i < highlights.length; ++i) {
+ hi = highlights[i];
+
+ if (hi.series.bars.show)
+ drawBarHighlight(hi.series, hi.point);
+ else
+ drawPointHighlight(hi.series, hi.point);
+ }
+
+ // draw selection
+ if (selection.show && selectionIsSane()) {
+ octx.strokeStyle = parseColor(options.selection.color).scale(null, null, null, 0.8).toString();
+ octx.lineWidth = 1;
+ ctx.lineJoin = "round";
+ octx.fillStyle = parseColor(options.selection.color).scale(null, null, null, 0.4).toString();
+
+ var x = Math.min(selection.first.x, selection.second.x),
+ y = Math.min(selection.first.y, selection.second.y),
+ w = Math.abs(selection.second.x - selection.first.x),
+ h = Math.abs(selection.second.y - selection.first.y);
+
+ octx.fillRect(x, y, w, h);
+ octx.strokeRect(x, y, w, h);
+ }
+ octx.restore();
+
+ executeHooks(hooks.drawOverlay, [octx]);
+ }
+
+ function highlight(s, point, auto) {
+ if (typeof s == "number")
+ s = series[s];
+
+ if (typeof point == "number")
+ point = s.data[point];
+
+ var i = indexOfHighlight(s, point);
+ if (i == -1) {
+ highlights.push({ series: s, point: point, auto: auto });
+
+ triggerRedrawOverlay();
+ }
+ else if (!auto)
+ highlights[i].auto = false;
+ }
+
+ function unhighlight(s, point) {
+ if (s == null && point == null) {
+ highlights = [];
+ triggerRedrawOverlay();
+ }
+
+ if (typeof s == "number")
+ s = series[s];
+
+ if (typeof point == "number")
+ point = s.data[point];
+
+ var i = indexOfHighlight(s, point);
+ if (i != -1) {
+ highlights.splice(i, 1);
+
+ triggerRedrawOverlay();
+ }
+ }
+
+ function indexOfHighlight(s, p) {
+ for (var i = 0; i < highlights.length; ++i) {
+ var h = highlights[i];
+ if (h.series == s && h.point[0] == p[0]
+ && h.point[1] == p[1])
+ return i;
+ }
+ return -1;
+ }
+
+ function drawPointHighlight(series, point) {
+ var x = point[0], y = point[1],
+ axisx = series.xaxis, axisy = series.yaxis;
+
+ if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
+ return;
+
+ var pointRadius = series.points.radius + series.points.lineWidth / 2;
+ octx.lineWidth = pointRadius;
+ octx.strokeStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString();
+ var radius = 1.5 * pointRadius;
+ octx.beginPath();
+ octx.arc(axisx.p2c(x), axisy.p2c(y), radius, 0, 2 * Math.PI, false);
+ octx.stroke();
+ }
+
+ function drawBarHighlight(series, point) {
+ octx.lineWidth = series.bars.lineWidth;
+ octx.strokeStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString();
+ var fillStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString();
+ var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
+ drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
+ 0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal);
+ }
+
+ function getSelection() {
+ if (!selectionIsSane())
+ return null;
+
+ var x1 = Math.min(selection.first.x, selection.second.x),
+ x2 = Math.max(selection.first.x, selection.second.x),
+ y1 = Math.max(selection.first.y, selection.second.y),
+ y2 = Math.min(selection.first.y, selection.second.y);
+
+ var r = {};
+ if (axes.xaxis.used)
+ r.xaxis = { from: axes.xaxis.c2p(x1), to: axes.xaxis.c2p(x2) };
+ if (axes.x2axis.used)
+ r.x2axis = { from: axes.x2axis.c2p(x1), to: axes.x2axis.c2p(x2) };
+ if (axes.yaxis.used)
+ r.yaxis = { from: axes.yaxis.c2p(y1), to: axes.yaxis.c2p(y2) };
+ if (axes.y2axis.used)
+ r.y2axis = { from: axes.y2axis.c2p(y1), to: axes.y2axis.c2p(y2) };
+ return r;
+ }
+
+ function triggerSelectedEvent() {
+ var r = getSelection();
+
+ target.trigger("plotselected", [ r ]);
+
+ // backwards-compat stuff, to be removed in future
+ if (axes.xaxis.used && axes.yaxis.used)
+ target.trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
+ }
+
+ function onSelectionMouseUp(e) {
+ // revert drag stuff for old-school browsers
+ if (document.onselectstart !== undefined)
+ document.onselectstart = workarounds.onselectstart;
+ if (document.ondrag !== undefined)
+ document.ondrag = workarounds.ondrag;
+
+ // no more draggy-dee-drag
+ selection.active = false;
+ updateSelection(e);
+
+ if (selectionIsSane()) {
+ triggerSelectedEvent();
+ clickIsMouseUp = true;
+ }
+ else {
+ // this counts as a clear
+ target.trigger("plotunselected", [ ]);
+ target.trigger("plotselecting", [ null ]);
+ }
+
+ return false;
+ }
+
+ function setSelectionPos(pos, e) {
+ var offset = eventHolder.offset();
+ pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plotWidth);
+ pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plotHeight);
+
+ if (options.selection.mode == "y") {
+ if (pos == selection.first)
+ pos.x = 0;
+ else
+ pos.x = plotWidth;
+ }
+
+ if (options.selection.mode == "x") {
+ if (pos == selection.first)
+ pos.y = 0;
+ else
+ pos.y = plotHeight;
+ }
+ }
+
+ function updateSelection(pos) {
+ if (pos.pageX == null)
+ return;
+
+ setSelectionPos(selection.second, pos);
+ if (selectionIsSane()) {
+ selection.show = true;
+ triggerRedrawOverlay();
+ }
+ else
+ clearSelection(true);
+ }
+
+ function clearSelection(preventEvent) {
+ if (selection.show) {
+ selection.show = false;
+ triggerRedrawOverlay();
+ if (!preventEvent)
+ target.trigger("plotunselected", [ ]);
+ }
+ }
+
+ function setSelection(ranges, preventEvent) {
+ var range;
+
+ if (options.selection.mode == "y") {
+ selection.first.x = 0;
+ selection.second.x = plotWidth;
+ }
+ else {
+ range = extractRange(ranges, "x");
+
+ selection.first.x = range.axis.p2c(range.from);
+ selection.second.x = range.axis.p2c(range.to);
+ }
+
+ if (options.selection.mode == "x") {
+ selection.first.y = 0;
+ selection.second.y = plotHeight;
+ }
+ else {
+ range = extractRange(ranges, "y");
+
+ selection.first.y = range.axis.p2c(range.from);
+ selection.second.y = range.axis.p2c(range.to);
+ }
+
+ selection.show = true;
+ triggerRedrawOverlay();
+ if (!preventEvent)
+ triggerSelectedEvent();
+ }
+
+ function selectionIsSane() {
+ var minSize = 5;
+ return Math.abs(selection.second.x - selection.first.x) >= minSize &&
+ Math.abs(selection.second.y - selection.first.y) >= minSize;
+ }
+
+ function getColorOrGradient(spec, bottom, top, defaultColor) {
+ if (typeof spec == "string")
+ return spec;
+ else {
+ // assume this is a gradient spec; IE currently only
+ // supports a simple vertical gradient properly, so that's
+ // what we support too
+ var gradient = ctx.createLinearGradient(0, top, 0, bottom);
+
+ for (var i = 0, l = spec.colors.length; i < l; ++i) {
+ var c = spec.colors[i];
+ gradient.addColorStop(i / (l - 1), typeof c == "string" ? c : parseColor(defaultColor).scale(c.brightness, c.brightness, c.brightness, c.opacity));
+ }
+
+ return gradient;
+ }
+ }
+ }
+
+ $.plot = function(target, data, options) {
+ var plot = new Plot($(target), data, options, $.plot.plugins);
+ /*var t0 = new Date();
+ var t1 = new Date();
+ var tstr = "time used (msecs): " + (t1.getTime() - t0.getTime())
+ if (window.console)
+ console.log(tstr);
+ else
+ alert(tstr);*/
+ return plot;
+ };
+
+ $.plot.plugins = [];
+
+ // returns a string with the date d formatted according to fmt
+ $.plot.formatDate = function(d, fmt, monthNames) {
+ var leftPad = function(n) {
+ n = "" + n;
+ return n.length == 1 ? "0" + n : n;
+ };
+
+ var r = [];
+ var escape = false;
+ if (monthNames == null)
+ monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+ for (var i = 0; i < fmt.length; ++i) {
+ var c = fmt.charAt(i);
+
+ if (escape) {
+ switch (c) {
+ case 'h': c = "" + d.getUTCHours(); break;
+ case 'H': c = leftPad(d.getUTCHours()); break;
+ case 'M': c = leftPad(d.getUTCMinutes()); break;
+ case 'S': c = leftPad(d.getUTCSeconds()); break;
+ case 'd': c = "" + d.getUTCDate(); break;
+ case 'm': c = "" + (d.getUTCMonth() + 1); break;
+ case 'y': c = "" + d.getUTCFullYear(); break;
+ case 'b': c = "" + monthNames[d.getUTCMonth()]; break;
+ }
+ r.push(c);
+ escape = false;
+ }
+ else {
+ if (c == "%")
+ escape = true;
+ else
+ r.push(c);
+ }
+ }
+ return r.join("");
+ };
+
+ // round to nearby lower multiple of base
+ function floorInBase(n, base) {
+ return base * Math.floor(n / base);
+ }
+
+ function clamp(min, value, max) {
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ else
+ return value;
+ }
+
+ // color helpers, inspiration from the jquery color animation
+ // plugin by John Resig
+ function Color (r, g, b, a) {
+
+ var rgba = ['r','g','b','a'];
+ var x = 4; //rgba.length
+
+ while (-1<--x) {
+ this[rgba[x]] = arguments[x] || ((x==3) ? 1.0 : 0);
+ }
+
+ this.toString = function() {
+ if (this.a >= 1.0) {
+ return "rgb("+[this.r,this.g,this.b].join(",")+")";
+ } else {
+ return "rgba("+[this.r,this.g,this.b,this.a].join(",")+")";
+ }
+ };
+
+ this.scale = function(rf, gf, bf, af) {
+ x = 4; //rgba.length
+ while (-1<--x) {
+ if (arguments[x] != null)
+ this[rgba[x]] *= arguments[x];
+ }
+ return this.normalize();
+ };
+
+ this.adjust = function(rd, gd, bd, ad) {
+ x = 4; //rgba.length
+ while (-1<--x) {
+ if (arguments[x] != null)
+ this[rgba[x]] += arguments[x];
+ }
+ return this.normalize();
+ };
+
+ this.clone = function() {
+ return new Color(this.r, this.b, this.g, this.a);
+ };
+
+ var limit = function(val,minVal,maxVal) {
+ return Math.max(Math.min(val, maxVal), minVal);
+ };
+
+ this.normalize = function() {
+ this.r = clamp(0, parseInt(this.r), 255);
+ this.g = clamp(0, parseInt(this.g), 255);
+ this.b = clamp(0, parseInt(this.b), 255);
+ this.a = clamp(0, this.a, 1);
+ return this;
+ };
+
+ this.normalize();
+ }
+
+ var lookupColors = {
+ aqua:[0,255,255],
+ azure:[240,255,255],
+ beige:[245,245,220],
+ black:[0,0,0],
+ blue:[0,0,255],
+ brown:[165,42,42],
+ cyan:[0,255,255],
+ darkblue:[0,0,139],
+ darkcyan:[0,139,139],
+ darkgrey:[169,169,169],
+ darkgreen:[0,100,0],
+ darkkhaki:[189,183,107],
+ darkmagenta:[139,0,139],
+ darkolivegreen:[85,107,47],
+ darkorange:[255,140,0],
+ darkorchid:[153,50,204],
+ darkred:[139,0,0],
+ darksalmon:[233,150,122],
+ darkviolet:[148,0,211],
+ fuchsia:[255,0,255],
+ gold:[255,215,0],
+ green:[0,128,0],
+ indigo:[75,0,130],
+ khaki:[240,230,140],
+ lightblue:[173,216,230],
+ lightcyan:[224,255,255],
+ lightgreen:[144,238,144],
+ lightgrey:[211,211,211],
+ lightpink:[255,182,193],
+ lightyellow:[255,255,224],
+ lime:[0,255,0],
+ magenta:[255,0,255],
+ maroon:[128,0,0],
+ navy:[0,0,128],
+ olive:[128,128,0],
+ orange:[255,165,0],
+ pink:[255,192,203],
+ purple:[128,0,128],
+ violet:[128,0,128],
+ red:[255,0,0],
+ silver:[192,192,192],
+ white:[255,255,255],
+ yellow:[255,255,0]
+ };
+
+ function extractColor(element) {
+ var color, elem = element;
+ do {
+ color = elem.css("background-color").toLowerCase();
+ // keep going until we find an element that has color, or
+ // we hit the body
+ if (color != '' && color != 'transparent')
+ break;
+ elem = elem.parent();
+ } while (!$.nodeName(elem.get(0), "body"));
+
+ // catch Safari's way of signalling transparent
+ if (color == "rgba(0, 0, 0, 0)")
+ return "transparent";
+
+ return color;
+ }
+
+ // parse string, returns Color
+ function parseColor(str) {
+ var result;
+
+ // Look for rgb(num,num,num)
+ if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
+ return new Color(parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10));
+
+ // Look for rgba(num,num,num,num)
+ if (result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
+ return new Color(parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10), parseFloat(result[4]));
+
+ // Look for rgb(num%,num%,num%)
+ if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
+ return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55);
+
+ // Look for rgba(num%,num%,num%,num)
+ if (result = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
+ return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55, parseFloat(result[4]));
+
+ // Look for #a0b1c2
+ if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
+ return new Color(parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16));
+
+ // Look for #fff
+ if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
+ return new Color(parseInt(result[1]+result[1], 16), parseInt(result[2]+result[2], 16), parseInt(result[3]+result[3], 16));
+
+ // Otherwise, we're most likely dealing with a named color
+ var name = $.trim(str).toLowerCase();
+ if (name == "transparent")
+ return new Color(255, 255, 255, 0);
+ else {
+ result = lookupColors[name];
+ return new Color(result[0], result[1], result[2]);
+ }
+ }
+
+})(jQuery);
diff --git a/admin/template/js/graphs.js b/admin/template/js/graphs.js
new file mode 100644
index 000000000..a2ac95933
--- /dev/null
+++ b/admin/template/js/graphs.js
@@ -0,0 +1,77 @@
+// JavaScript Document
+$(function () {
+ var d = [[1201647600000, 1521], [1201734000000, 1477], [1201820400000, 1442], [1201906800000, 1252], [1201993200000, 1236], [1202079600000, 1525], [1202166000000, 1477], [1202252400000, 1386], [1202338800000, 1409], [1202425200000, 1408], [1202511600000, 1237], [1202598000000, 1193], [1202684400000, 1357], [1202770800000, 1414], [1202857200000, 1393], [1202943600000, 1353], [1203030000000, 1364], [1203116400000, 1215], [1203202800000, 1214], [1203289200000, 1456], [1203375600000, 1399], [1203462000000, 1434], [1203548400000, 1348], [1203634800000, 1243], [1203721200000, 1126], [1203807600000, 1500]];
+
+ // first correct the timestamps - they are recorded as the daily
+ // midnights in UTC+0100, but Flot always displays dates in UTC
+ // so we have to add one hour to hit the midnights in the plot
+ for (var i = 0; i < d.length; ++i)
+ d[i][0] += 60 * 60 * 1000;
+
+ // helper for returning the weekends in a period
+ function weekendAreas(axes) {
+ var markings = [];
+ var d = new Date(axes.xaxis.min);
+ // go to the first Saturday
+ d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 1) % 7))
+ d.setUTCSeconds(0);
+ d.setUTCMinutes(0);
+ d.setUTCHours(0);
+ var i = d.getTime();
+ do {
+ // when we don't set yaxis the rectangle automatically
+ // extends to infinity upwards and downwards
+ markings.push({ xaxis: { from: i, to: i + 2 * 24 * 60 * 60 * 1000 } });
+ i += 7 * 24 * 60 * 60 * 1000;
+ } while (i < axes.xaxis.max);
+
+ return markings;
+ }
+
+ var options = {
+ xaxis: { mode: "time" },
+ selection: { mode: "xy" },
+ lines: { show: true, fill: 0.5 },
+ points: { show: true },
+ yaxis: { min: 800, max: 2000 },
+ grid: { markings: weekendAreas, hoverable: true, clickable: true, labelMargin: 10 },
+ colors: ["#639ecb"], //639ecb //e03c42
+ shadowSize: 2
+ };
+ function showTooltip(x, y, contents) {
+ $('' + contents + '
').css( {
+ position: 'absolute',
+ display: 'none',
+ top: y - 35,
+ left: x + 0,
+ color: '#333',
+ border: '1px solid #999',
+ padding: '2px',
+ 'background-color': '#EFEFEF',
+ opacity: 0.80
+ }).appendTo("body").fadeIn(200);
+ }
+
+ var plot = $.plot($("#placeholder"), [d], options);
+ var previousPoint = null;
+ $("#placeholder").bind("plothover", function (event, pos, item) {
+ $("#x").text(pos.x.toFixed(2));
+ $("#y").text(pos.y.toFixed(2));
+ if (item) {
+ if (previousPoint != item.datapoint) {
+ previousPoint = item.datapoint;
+
+ $("#tooltip").remove();
+ var x = item.datapoint[0].toFixed(2),
+ y = item.datapoint[1].toFixed(2);
+
+ showTooltip(item.pageX, item.pageY,
+ y + "visitors");
+ }
+ }
+ else {
+ $("#tooltip").remove();
+ previousPoint = null;
+ }
+ });
+});
\ No newline at end of file
diff --git a/admin/template/js/jquery.min.js b/admin/template/js/jquery.min.js
new file mode 100644
index 000000000..b1ae21d8b
--- /dev/null
+++ b/admin/template/js/jquery.min.js
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,""]||!O.indexOf(""," "]||(!O.indexOf(""," "]||!O.indexOf(""," "]||!o.support.htmlSerialize&&[1,"div","
"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V ";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML=" ";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="
";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(Fa text ';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
").append(M.responseText.replace(/
+
+
+
+
+
+
+
+
+
+
+// JavaScript Document
+$(function () {
+ %s
+
+ // first correct the timestamps - they are recorded as the daily
+ // midnights in UTC+0100, but Flot always displays dates in UTC
+ // so we have to add one hour to hit the midnights in the plot
+ for (var i = 0; i < d.length; ++i)
+ d[i][0] += 60 * 60 * 1000;
+
+ // helper for returning the weekends in a period
+ function weekendAreas(axes) {
+ var markings = [];
+ var d = new Date(axes.xaxis.min);
+ // go to the first Saturday
+ d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 1) %% 7))
+ d.setUTCSeconds(0);
+ d.setUTCMinutes(0);
+ d.setUTCHours(0);
+ var i = d.getTime();
+ do {
+ // when we don\'t set yaxis the rectangle automatically
+ // extends to infinity upwards and downwards
+ markings.push({ xaxis: { from: i, to: i + 2 * 24 * 60 * 60 * 1000 } });
+ i += 7 * 24 * 60 * 60 * 1000;
+ } while (i < axes.xaxis.max);
+
+ return markings;
+ }
+
+ var options = {
+ xaxis: { mode: "time" },
+ selection: { mode: "xy" },
+ lines: { show: true, fill: 0.5 },
+ points: { show: true },
+ yaxis: { min: 1, max: 1000 },
+ grid: { markings: weekendAreas, hoverable: true, clickable: true, labelMargin: 10 },
+ colors: ["#639ecb"], //639ecb //e03c42
+ shadowSize: 2
+ };
+ function showTooltip(x, y, contents) {
+ $(\'\' + contents + \'
\').css( {
+ position: \'absolute\',
+ display: \'none\',
+ top: y - 35,
+ left: x + 0,
+ color: \'#333\',
+ border: \'1px solid #999\',
+ padding: \'2px\',
+ \'background-color\': \'#EFEFEF\',
+ opacity: 0.80
+ }).appendTo("body").fadeIn(200);
+ }
+
+ var plot = $.plot($("#placeholder"), [d], options);
+ var previousPoint = null;
+ $("#placeholder").bind("plothover", function (event, pos, item) {
+ $("#x").text(pos.x.toFixed(2));
+ $("#y").text(pos.y.toFixed(2));
+ if (item) {
+ if (previousPoint != item.datapoint) {
+ previousPoint = item.datapoint;
+
+ $("#tooltip").remove();
+ var x = item.datapoint[0].toFixed(0),
+ y = item.datapoint[1].toFixed(0);
+
+ if(y == 1) {
+ showTooltip(item.pageX, item.pageY,
+ y + " visitor");
+ }
+ else {
+ showTooltip(item.pageX, item.pageY,
+ y + " visitors");
+ }
+ }
+ }
+ else {
+ $("#tooltip").remove();
+ previousPoint = null;
+ }
+ });
+});
+', Admin::GetJSFormattedVisitorsValue());
+ break;
+ case 'news':
+ echo '';
+ break;
+}
+?>
+
+
+
+
+
+
+
World of Warcraft Armory : Admin panel
+
+
+
+
+
+
+
+
+
+
+
+
This content comes from a hidden element on this page.
+
+
Try testing yourself!
+
You can call as many dialogs you want with jQuery UI.
+
+
+
+
+
+
+
+
+