aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Kuzminski <marcin@python-works.com>2010-07-24 02:17:48 +0200
committerMarcin Kuzminski <marcin@python-works.com>2010-07-24 02:17:48 +0200
commitddea94f664f3018a400d464c58bf6b254e202ebe (patch)
tree9d1aca27c0e6a5e0d3c3eabe26aafda3b2c25da6
parent8a78e19bbd55af11df5e21718610aabab53ba5d0 (diff)
version bump to 0.8v0.8.0
hg app 0.8 new template. Add yui flot and graph into summary page. + various tweeks and patches into look of application
-rw-r--r--pylons_app/__init__.py2
-rw-r--r--pylons_app/controllers/summary.py82
-rw-r--r--pylons_app/lib/base.py2
-rw-r--r--pylons_app/public/css/colors/blue.css302
-rw-r--r--pylons_app/public/css/diff.css13
-rw-r--r--pylons_app/public/css/monoblue_custom.css952
-rw-r--r--pylons_app/public/css/pygments.css9
-rw-r--r--pylons_app/public/css/reset.css53
-rw-r--r--pylons_app/public/css/style.css3624
-rw-r--r--pylons_app/public/css/style_full.css36
-rw-r--r--pylons_app/public/images/background.pngbin0 -> 4828 bytes
-rw-r--r--pylons_app/public/images/button.pngbin0 -> 210 bytes
-rw-r--r--pylons_app/public/images/button_browse.pngbin0 -> 851 bytes
-rw-r--r--pylons_app/public/images/button_browse_selected.pngbin0 -> 808 bytes
-rw-r--r--pylons_app/public/images/button_selected.pngbin0 -> 225 bytes
-rw-r--r--pylons_app/public/images/colors/blue/button_highlight.pngbin0 -> 225 bytes
-rw-r--r--pylons_app/public/images/colors/blue/button_highlight_selected.pngbin0 -> 225 bytes
-rw-r--r--pylons_app/public/images/colors/blue/button_home.pngbin0 -> 1468 bytes
-rw-r--r--pylons_app/public/images/colors/blue/header_inner.pngbin0 -> 234 bytes
-rw-r--r--pylons_app/public/images/colors/blue/header_inner_corners.pngbin0 -> 264 bytes
-rw-r--r--pylons_app/public/images/colors/blue/index.sofbin0 -> 834 bytes
-rw-r--r--pylons_app/public/images/colors/blue/login_corners.pngbin0 -> 267 bytes
-rw-r--r--pylons_app/public/images/colors/blue/menu_arrow.pngbin0 -> 133 bytes
-rw-r--r--pylons_app/public/images/colors/blue/menu_border.pngbin0 -> 129 bytes
-rw-r--r--pylons_app/public/images/colors/blue/menu_l_selected.pngbin0 -> 300 bytes
-rw-r--r--pylons_app/public/images/colors/blue/menu_r_selected.pngbin0 -> 293 bytes
-rw-r--r--pylons_app/public/images/colors/blue/menu_selected.pngbin0 -> 225 bytes
-rw-r--r--pylons_app/public/images/colors/blue/quick_l.pngbin0 -> 177 bytes
-rw-r--r--pylons_app/public/images/colors/blue/quick_l_selected.pngbin0 -> 166 bytes
-rw-r--r--pylons_app/public/images/colors/blue/quick_r.pngbin0 -> 173 bytes
-rw-r--r--pylons_app/public/images/colors/blue/quick_r_selected.pngbin0 -> 168 bytes
-rw-r--r--pylons_app/public/images/colors/blue/title.pngbin0 -> 247 bytes
-rw-r--r--pylons_app/public/images/colors/blue/title_link.pngbin0 -> 224 bytes
-rw-r--r--pylons_app/public/images/colors/blue/title_tab_selected.pngbin0 -> 147 bytes
-rw-r--r--pylons_app/public/images/content.pngbin0 -> 218 bytes
-rw-r--r--pylons_app/public/images/header_background.pngbin0 -> 5630 bytes
-rw-r--r--pylons_app/public/images/icons/cross.pngbin655 -> 3812 bytes
-rw-r--r--pylons_app/public/images/icons/index.sofbin0 -> 414 bytes
-rw-r--r--pylons_app/public/images/icons/success.pngbin0 -> 7793 bytes
-rw-r--r--pylons_app/public/images/icons/warning.pngbin0 -> 7189 bytes
-rw-r--r--pylons_app/public/images/login.pngbin0 -> 1256 bytes
-rw-r--r--pylons_app/public/images/menu.pngbin0 -> 210 bytes
-rw-r--r--pylons_app/public/images/menu_l.pngbin0 -> 343 bytes
-rw-r--r--pylons_app/public/images/menu_minus.pngbin0 -> 146 bytes
-rw-r--r--pylons_app/public/images/menu_plus.pngbin0 -> 150 bytes
-rw-r--r--pylons_app/public/images/menu_r.pngbin0 -> 350 bytes
-rw-r--r--pylons_app/public/images/pager.pngbin0 -> 184 bytes
-rw-r--r--pylons_app/public/images/pager_selected.pngbin0 -> 225 bytes
-rw-r--r--pylons_app/public/js/excanvas.min.js1
-rw-r--r--pylons_app/public/js/yui.flot.js2483
-rw-r--r--pylons_app/templates/admin/admin.html25
-rw-r--r--pylons_app/templates/admin/admin_log.html45
-rw-r--r--pylons_app/templates/admin/permissions/permissions.html23
-rw-r--r--pylons_app/templates/admin/repos/repo_add.html78
-rw-r--r--pylons_app/templates/admin/repos/repo_edit.html490
-rw-r--r--pylons_app/templates/admin/repos/repos.html62
-rw-r--r--pylons_app/templates/admin/settings/settings.html111
-rw-r--r--pylons_app/templates/admin/users/user_add.html123
-rw-r--r--pylons_app/templates/admin/users/user_edit.html139
-rw-r--r--pylons_app/templates/admin/users/users.html57
-rw-r--r--pylons_app/templates/base/base.html308
-rw-r--r--pylons_app/templates/branches/branches.html29
-rw-r--r--pylons_app/templates/branches/branches_data.html12
-rw-r--r--pylons_app/templates/changelog/changelog.html189
-rw-r--r--pylons_app/templates/changeset/changeset.html33
-rwxr-xr-xpylons_app/templates/errors/error_document.html85
-rw-r--r--pylons_app/templates/files/file_diff.html70
-rw-r--r--pylons_app/templates/files/files.html58
-rw-r--r--pylons_app/templates/files/files_annotate.html73
-rw-r--r--pylons_app/templates/files/files_browser.html10
-rw-r--r--pylons_app/templates/files/files_source.html11
-rw-r--r--pylons_app/templates/index.html101
-rw-r--r--pylons_app/templates/login.html108
-rw-r--r--pylons_app/templates/register.html88
-rw-r--r--pylons_app/templates/settings/repo_settings.html469
-rw-r--r--pylons_app/templates/shortlog/shortlog.html35
-rw-r--r--pylons_app/templates/shortlog/shortlog_data.html55
-rw-r--r--pylons_app/templates/summary/summary.html297
-rw-r--r--pylons_app/templates/tags/tags.html31
-rw-r--r--pylons_app/templates/tags/tags_data.html12
80 files changed, 8557 insertions, 2229 deletions
diff --git a/pylons_app/__init__.py b/pylons_app/__init__.py
index a1448314..ea0d2f61 100644
--- a/pylons_app/__init__.py
+++ b/pylons_app/__init__.py
@@ -24,7 +24,7 @@ Hg app, a web based mercurial repository managment based on pylons
@author: marcink
"""
-VERSION = (0, 7, 9, 'beta')
+VERSION = (0, 8, 0, 'beta')
__version__ = '.'.join((str(each) for each in VERSION[:4]))
diff --git a/pylons_app/controllers/summary.py b/pylons_app/controllers/summary.py
index e98bd664..9a5180d5 100644
--- a/pylons_app/controllers/summary.py
+++ b/pylons_app/controllers/summary.py
@@ -2,7 +2,7 @@
# encoding: utf-8
# summary controller for pylons
# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
-
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
@@ -22,12 +22,18 @@ Created on April 18, 2010
summary controller for pylons
@author: marcink
"""
+from datetime import datetime, timedelta
from pylons import tmpl_context as c, request
from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
from pylons_app.lib.base import BaseController, render
+from pylons_app.lib.helpers import person
+from pylons_app.lib.utils import OrderedDict
from pylons_app.model.hg_model import HgModel
+from time import mktime
from webhelpers.paginate import Page
+import calendar
import logging
+
log = logging.getLogger(__name__)
class SummaryController(BaseController):
@@ -56,5 +62,77 @@ class SummaryController(BaseController):
c.repo_branches = {}
for name, hash in c.repo_info.branches.items()[:10]:
c.repo_branches[name] = c.repo_info.get_changeset(hash)
-
+
+ c.commit_data = self.__get_commit_stats(c.repo_info)
+
return render('summary/summary.html')
+
+
+
+ def __get_commit_stats(self, repo):
+ aggregate = OrderedDict()
+
+
+ #graph range
+ td = datetime.today()
+ y = td.year
+ m = td.month
+ d = td.day
+ c.ts_min = mktime((y, (td - timedelta(days=calendar.mdays[m] - 1)).month, d, 0, 0, 0, 0, 0, 0,))
+ c.ts_max = mktime((y, m, d, 0, 0, 0, 0, 0, 0,))
+
+
+# #generate this monhts keys
+# dates_range = OrderedDict()
+# year_range = range(2010, datetime.today().year + 1)
+# month_range = range(1, datetime.today().month + 1)
+#
+#
+#
+# for y in year_range:
+# for m in month_range:
+# for d in range(1, calendar.mdays[m] + 1):
+# k = '%s-%s-%s' % (y, m, d)
+# timetupple = [int(x) for x in k.split('-')]
+# timetupple.extend([0 for _ in xrange(6)])
+# k = mktime(timetupple)
+# dates_range[k] = 0
+
+ def author_key_cleaner(k):
+ k = person(k)
+ return k
+
+ for cs in repo:
+ k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
+ cs.date.timetuple()[2])
+ timetupple = [int(x) for x in k.split('-')]
+ timetupple.extend([0 for _ in xrange(6)])
+ k = mktime(timetupple)
+ if aggregate.has_key(author_key_cleaner(cs.author)):
+ if aggregate[author_key_cleaner(cs.author)].has_key(k):
+ aggregate[author_key_cleaner(cs.author)][k] += 1
+ else:
+ #aggregate[author_key_cleaner(cs.author)].update(dates_range)
+ if k >= c.ts_min and k <= c.ts_max:
+ aggregate[author_key_cleaner(cs.author)][k] = 1
+ else:
+ if k >= c.ts_min and k <= c.ts_max:
+ aggregate[author_key_cleaner(cs.author)] = OrderedDict()
+ #aggregate[author_key_cleaner(cs.author)].update(dates_range)
+ aggregate[author_key_cleaner(cs.author)][k] = 1
+
+ d = ''
+ tmpl0 = u""""%s":%s"""
+ tmpl1 = u"""{label:"%s",data:%s},"""
+ for author in aggregate:
+ d += tmpl0 % (author.decode('utf8'),
+ tmpl1 \
+ % (author.decode('utf8'),
+ [[x, aggregate[author][x]] for x in aggregate[author]]))
+ if d == '':
+ d = '"%s":{label:"%s",data:[[0,0],]}' \
+ % (author_key_cleaner(repo.contact),
+ author_key_cleaner(repo.contact))
+ return d
+
+
diff --git a/pylons_app/lib/base.py b/pylons_app/lib/base.py
index dfc93282..a1eabfc2 100644
--- a/pylons_app/lib/base.py
+++ b/pylons_app/lib/base.py
@@ -15,7 +15,7 @@ class BaseController(WSGIController):
def __before__(self):
c.hg_app_version = __version__
- c.repos_prefix = config['hg_app_name']
+ c.hg_app_name = config['hg_app_name']
c.repo_name = get_repo_slug(request)
c.hg_app_user = auth.get_user(session)
c.cached_repo_list = _get_repos_cached()
diff --git a/pylons_app/public/css/colors/blue.css b/pylons_app/public/css/colors/blue.css
new file mode 100644
index 00000000..f59dd493
--- /dev/null
+++ b/pylons_app/public/css/colors/blue.css
@@ -0,0 +1,302 @@
+/* -----------------------------------------------------------
+ header
+----------------------------------------------------------- */
+
+#header #header-inner
+{
+ background: #b0b0b0 url("../../images/colors/blue/header_inner.png") repeat-x;
+}
+
+/* -----------------------------------------------------------
+ header -> home
+----------------------------------------------------------- */
+
+#header #header-inner #home a
+{
+ background: url("../../images/colors/blue/button_home.png");
+}
+
+/* -----------------------------------------------------------
+ header -> quick
+----------------------------------------------------------- */
+
+#header #header-inner #quick li a
+{
+ background: #336699 url("../../images/colors/blue/quick_l.png") no-repeat top left;
+}
+
+#header #header-inner #quick li span
+{
+ background: url("../../images/colors/blue/quick_r.png") no-repeat top right;
+ border-left: 1px solid #3f6f9f;
+}
+
+#header #header-inner #quick li span.icon
+{
+ background: url("../../images/colors/blue/quick_l.png") no-repeat top left;
+ border-right: 1px solid #2e5c89;
+}
+
+#header #header-inner #quick li a:hover
+{
+ background: #4e4e4e url("../../images/colors/blue/quick_l_selected.png") no-repeat top left;
+}
+
+#header #header-inner #quick li a:hover span
+{
+ background: url("../../images/colors/blue/quick_r_selected.png") no-repeat top right;
+}
+
+#header #header-inner #quick li a:hover span.icon
+{
+ background: url("../../images/colors/blue/quick_l_selected.png") no-repeat top left;
+}
+
+/* -----------------------------------------------------------
+ header corners
+----------------------------------------------------------- */
+
+#header #header-inner div.corner
+{
+ background: url("../../images/colors/blue/header_inner_corners.png") no-repeat;
+}
+
+#header #header-inner div.tl
+{
+ top: 0;
+ left: 0;
+ background-position: 0 0;
+}
+
+#header #header-inner div.tr
+{
+ top: 0;
+ right: 0;
+ background-position: -6px 0;
+}
+
+/* -----------------------------------------------------------
+ content -> left -> menu
+----------------------------------------------------------- */
+
+#content #left #menu h6.selected
+{
+ background: #00376e url("../../images/colors/blue/menu_selected.png") repeat-x;
+}
+
+#content #left #menu h6.selected a
+{
+ background: url("../../images/colors/blue/menu_l_selected.png") no-repeat top left;
+}
+
+#content #left #menu h6.selected span
+{
+ background: url("../../images/colors/blue/menu_r_selected.png") no-repeat top right;
+}
+
+#content #left #menu ul
+{
+ background: #376ea6;
+}
+
+#content #left #menu li
+{
+ border-top: 1px solid #4377ab;
+ border-bottom: 1px solid #326395;
+}
+
+#content #left #menu li a
+{
+ background: url("../../images/colors/blue/menu_arrow.png") no-repeat 0 9px;
+}
+
+#content #left #menu li a:hover
+{
+ color: #b9dcff;
+}
+
+#content #left #menu li.collapsible
+{
+ background: url("../../images/colors/blue/menu_border.png") no-repeat top left;
+}
+
+#content #left #menu li.collapsible a.minus
+{
+ border-bottom: 1px solid #326395;
+}
+
+#content #left #menu li ul
+{
+ border-left: 18px solid #326395;
+}
+
+#content #left #menu li ul li
+{
+ background: url("../../images/colors/blue/menu_arrow.png") no-repeat 10px 9px;
+ border-top: 1px solid #4377ab;
+ border-bottom: 1px solid #326395;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / title
+----------------------------------------------------------- */
+
+#content div.box div.title
+{
+ background: #336699 url("../../images/colors/blue/title.png") repeat-x;
+}
+
+#content div.box div.title ul.links li a
+{
+ background: url("../../images/colors/blue/title_link.png") no-repeat top left;
+ border-left: 1px solid #316293;
+}
+
+#content div.box div.title ul.links li a:hover
+{
+ background: url("../../images/colors/blue/title_tab_selected.png") no-repeat bottom center;
+ color: #bfe3ff;
+}
+
+#content div.box div.title ul.links li.ui-tabs-selected a
+{
+ background: url("../../images/colors/blue/title_tab_selected.png") no-repeat bottom center;
+ color: #bfe3ff;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / search
+----------------------------------------------------------- */
+
+#content div.box div.title div.search
+{
+ background: url("../../images/colors/blue/title_link.png") no-repeat top left;
+ border-left: 1px solid #316293;
+}
+
+#content div.box div.title div.search div.input input
+{
+ border: 1px solid #316293;
+}
+
+#content div.box div.title div.search div.button input.ui-state-default
+{
+ background: #4e85bb url("../../images/colors/blue/button_highlight.png") repeat-x;
+ border: 1px solid #316293;
+ border-left: none;
+ color: #FFFFFF;
+}
+
+#content div.box div.title div.search div.button input.ui-state-hover
+{
+ background: #46a0c1 url("../../images/colors/blue/button_highlight_selected.png") repeat-x;
+ border: 1px solid #316293;
+ border-left: none;
+ color: #FFFFFF;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> button
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.highlight .ui-state-default
+{
+ background: #4e85bb url("../../images/colors/blue/button_highlight.png") repeat-x;
+ border-top: 1px solid #5c91a4;
+ border-left: 1px solid #2a6f89;
+ border-right: 1px solid #2b7089;
+ border-bottom: 1px solid #1a6480;
+ color: #ffffff;
+}
+
+#content div.box div.form div.fields div.field div.highlight .ui-state-hover
+{
+ background: #46a0c1 url("../../images/colors/blue/button_highlight_selected.png") repeat-x;
+ border-top: 1px solid #78acbf;
+ border-left: 1px solid #34819e;
+ border-right: 1px solid #35829f;
+ border-bottom: 1px solid #257897;
+ color: #ffffff;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> buttons
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.buttons div.highlight input.ui-state-default
+{
+ background: #4e85bb url("../../images/colors/blue/button_highlight.png") repeat-x;
+ border-top: 1px solid #5c91a4;
+ border-left: 1px solid #2a6f89;
+ border-right: 1px solid #2b7089;
+ border-bottom: 1px solid #1a6480;
+ color: #ffffff;
+}
+
+#content div.box div.form div.fields div.buttons div.highlight input.ui-state-hover
+{
+ background: #46a0c1 url("../../images/colors/blue/button_highlight_selected.png") repeat-x;
+ border-top: 1px solid #78acbf;
+ border-left: 1px solid #34819e;
+ border-right: 1px solid #35829f;
+ border-bottom: 1px solid #257897;
+ color: #ffffff;
+}
+
+/* -----------------------------------------------------------
+ login -> title
+----------------------------------------------------------- */
+
+#login div.title
+{
+ background: #003367 url("../../images/colors/blue/header_inner.png") repeat-x;
+}
+
+/* -----------------------------------------------------------
+ login -> title / corners
+----------------------------------------------------------- */
+
+#login div.title div.corner
+{
+ background: url("../../images/colors/blue/login_corners.png") no-repeat;
+}
+
+#login div.title div.tl
+{
+ top: 0;
+ left: 0;
+ background-position: 0 0;
+}
+
+#login div.title div.tr
+{
+ top: 0;
+ right: 0;
+ background-position: -6px 0;
+}
+
+/* -----------------------------------------------------------
+ jquery ui -> select styling
+----------------------------------------------------------- */
+
+.ui-selectmenu-open li.ui-selectmenu-item-focus { background: #376ea6; }
+.ui-selectmenu-open li.ui-selectmenu-item-focus a { color: #ffffff; }
+
+/* -----------------------------------------------------------
+ jquery ui -> datepicker
+----------------------------------------------------------- */
+.ui-datepicker td span, .ui-datepicker td a:hover { background: #376ea6; color: #ffffff; }
+.ui-datepicker td span, .ui-datepicker td.ui-datepicker-current-day a { background: #376ea6; color: #ffffff; }
+
+/* -----------------------------------------------------------
+ jquery ui -> autocomplete
+----------------------------------------------------------- */
+
+.ui-autocomplete .ui-menu-item a:hover { background: #376ea6; color: #ffffff; }
+
+/* -----------------------------------------------------------
+ jquery ui -> dialog
+----------------------------------------------------------- */
+
+.ui-dialog { border: 1px solid #336699; }
+.ui-dialog .ui-dialog-titlebar { background: #336699 url("../../images/colors/blue/title.png") repeat-x; } \ No newline at end of file
diff --git a/pylons_app/public/css/diff.css b/pylons_app/public/css/diff.css
index 9beb6955..72acf880 100644
--- a/pylons_app/public/css/diff.css
+++ b/pylons_app/public/css/diff.css
@@ -26,14 +26,22 @@ div.diffblock pre.raw{
color:#000000;
}
-.code-difftable{
+table.code-difftable{
border-collapse: collapse;
width: 99%;
}
-.code-difftable td:target *{
+table.code-difftable td:target *{
background: repeat scroll 0 0 #FFFFBE !important;
text-decoration: underline;
}
+
+table.code-difftable td {
+ padding: 0 !important;
+ background: none !important;
+ border:0 !important;
+}
+
+
.code-difftable .context{
background:none repeat scroll 0 0 #DDE7EF;
}
@@ -82,7 +90,6 @@ div.diffblock pre.raw{
padding:0;
}
-
.code {
display: block;
width: 100%;
diff --git a/pylons_app/public/css/monoblue_custom.css b/pylons_app/public/css/monoblue_custom.css
deleted file mode 100644
index 6abadf87..00000000
--- a/pylons_app/public/css/monoblue_custom.css
+++ /dev/null
@@ -1,952 +0,0 @@
-/*** Initial Settings ***/
-#mainhtml {
- margin: 15px 50px;
- background: #DBD4C6;
- font-family: sans-serif;
-}
-
-#mainhtml .breadcrumbs a:HOVER {
- text-decoration: underline;
-}
-
-a {
- color: #556CB5;
- text-decoration: none;
-}
-
-a:HOVER {
- text-decoration: underline;
-}
-
-/*** end of Initial Settings ***/
-
-/*** ***/
-.table_disp {
- border-left: 0px solid #666666;
- border-bottom: 1px solid #666666;
- border-right: 1px solid #666666;
- padding: 0px;
- margin: 0px;
- border-spacing: 0px;
-}
-
-.table_disp .header {
- border-top: 1px solid #666666;
- background-color: #556CB5;
- font-weight: bold;
- color: white;
- vertical-align: middle;
- padding: 3px 5px;
- text-align: left;
- font-size: 0.9em;
-}
-
-.table_disp .header td {
- padding: 4px;
- vertical-align: middle;
- border-top: 1px solid #AAAAAA;
- border-bottom: 2px solid #666666;
-}
-
-.table_disp td {
- border-left: 1px solid #AAAAAA;
- padding-left: 4px;
- padding-right: 4px;
-}
-
-table tr.parity0:hover,table tr.parity1:hover {
- background: #D5E1E6;
-}
-
-table tr.parity0 {
- background: #EAEAE9;
-}
-
-table tr.parity1 {
- background: #FFFFFF;
-}
-
-/*** ***/
-
-/** COMMON SETTINGS **/
-.add_icon {
- background: url("/images/icons/add.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- padding-top: 0px;
- text-align: left;
-}
-
-.edit_icon {
- background: url("/images/icons/folder_edit.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- padding-top: 0px;
- text-align: left;
-}
-
-.delete_icon {
- background: url("/images/icons/delete.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- padding-top: 0px;
- text-align: left;
-}
-
-.action_button {
- border: 0px;
- display: block;
-}
-
-.action_button:hover {
- border: 0px;
- font-style: italic;
- cursor: pointer;
-}
-
-.flash_msg ul {
- margin: 0;
- padding: 25px 0px 0px 0px;
-}
-
-.error_msg {
- background-color: #FFCFCF;
- background-image: url("/images/icons/error_msg.png");
- border: 1px solid #FF9595;
- color: #CC3300;
-}
-
-.warning_msg {
- background-color: #FFFBCC;
- background-image: url("/images/icons/warning_msg.png");
- border: 1px solid #FFF35E;
- color: #C69E00;
-}
-
-.success_msg {
- background-color: #D5FFCF;
- background-image: url("/images/icons/success_msg.png");
- border: 1px solid #97FF88;
- color: #009900;
-}
-
-.notice_msg {
- background-color: #DCE3FF;
- background-image: url("/images/icons/notice_msg.png");
- border: 1px solid #93A8FF;
- color: #556CB5;
-}
-
-.success_msg,.error_msg,.notice_msg,.warning_msg {
- background-position: 10px center;
- background-repeat: no-repeat;
- font-size: 12px;
- font-weight: bold;
- min-height: 14px;
- line-height: 14px;
- margin-bottom: 0px;
- margin-top: 0px;
- padding: 3px 10px 3px 40px;
- display: block;
- overflow: auto;
-}
-
-#msg_close {
- background: transparent url("icons/cross_grey_small.png") no-repeat
- scroll 0 0;
- cursor: pointer;
- height: 16px;
- position: absolute;
- right: 5px;
- top: 5px;
- width: 16px;
-}
-
-.error-message {
- color: #CC3300;
-}
-
-/**** TOOLTIP ****/
-.yui-overlay,.yui-panel-container {
- visibility: hidden;
- position: absolute;
- z-index: 2;
-}
-
-.yui-tt {
- visibility: hidden;
- position: absolute;
- color: #666666;
- background-color: #FFFFFF;
- font-family: arial, helvetica, verdana, sans-serif;
- padding: 8px;
- border: 2px solid #556CB5;
- font: 100% sans-serif;
- width: auto;
- opacity: 1.0;
-}
-
-.yui-tt-shadow {
- display: none;
-}
-
-/** END TOOLTIP **/
-
-/** AUTOCOMPLETE **/
-
-.ac{
- vertical-align: top;
-
-}
-.ac .match {
- font-weight:bold;
-}
-
-.ac .yui-ac {
- position: relative;
- font-family: arial;
- font-size: 100%;
-}
-
-.ac .perm_ac{
- width:15em;
-}
-/* styles for input field */
-.ac .yui-ac-input {
- position: absolute;
- width: 100%;
-}
-
-/* styles for results container */
-.ac .yui-ac-container {
- position: absolute;
- top: 1.6em;
- width: 100%;
-}
-
-/* styles for header/body/footer wrapper within container */
-.ac .yui-ac-content {
- position: absolute;
- width: 100%;
- border: 1px solid #808080;
- background: #fff;
- overflow: hidden;
- z-index: 9050;
-}
-
-/* styles for container shadow */
-.ac .yui-ac-shadow {
- position: absolute;
- margin: .3em;
- width: 100%;
- background: #000;
- -moz-opacity: 0.10;
- opacity: .10;
- filter: alpha(opacity = 10);
- z-index: 9049;
-}
-
-/* styles for results list */
-.ac .yui-ac-content ul {
- margin: 0;
- padding: 0;
- width: 100%;
-}
-
-/* styles for result item */
-.ac .yui-ac-content li {
- margin: 0;
- padding: 2px 5px;
- cursor: default;
- white-space: nowrap;
-}
-
-/* styles for prehighlighted result item */
-.ac .yui-ac-content li.yui-ac-prehighlight {
- background: #B3D4FF;
-}
-
-/* styles for highlighted result item */
-.ac .yui-ac-content li.yui-ac-highlight {
- background: #556CB5;
- color: #FFF;
-}
-
-/** END AUTOCOMPLETE **/
-div#main {
- padding: 5px;
-}
-
-div#container {
- background: #FFFFFF;
- position: relative;
- color: #666;
-}
-
-div.page-header {
- padding: 50px 20px 0;
- background: #556cb5 top left repeat-x;
- position: relative;
-}
-
-div.page-header h1 {
- margin: 10px 0 30px;
- font-size: 1.8em;
- font-weight: bold;
- font-family: sans-serif;
- letter-spacing: 1px;
- color: #FFFFFF;
-}
-
-div.page-header h1 a {
- font-weight: bold;
- color: #FFFFFF;
-}
-
-div.page-header a {
- text-decoration: none;
-}
-
-div.page-header form {
- position: absolute;
- margin-bottom: 2px;
- bottom: 0;
- right: 20px;
-}
-
-div.page-header form label {
- color: #DDD;
-}
-
-div.page-header form input {
- padding: 2px;
- border: solid 1px #DDD;
-}
-
-div.page-header form dl {
- overflow: hidden;
-}
-
-div.page-header form dl dt {
- font-size: 1.2em;
-}
-
-div.page-header form dl dt,div.page-header form dl dd {
- margin: 0 0 0 5px;
- float: left;
- height: 24px;
- line-height: 20px;
-}
-
-ul.page-nav {
- margin: 10px 0 0 0;
- list-style-type: none;
- overflow: hidden;
- width: 800px;
- padding: 0;
-}
-
-ul.page-nav li {
- margin: 0 4px 0 0;
- float: left;
- height: 24px;
- font-size: 1.1em;
- line-height: 24px;
- text-align: center;
- background: #556CB5;
-}
-
-ul.page-nav li.current {
- background: #FFF;
- padding-right: 5px;
- padding-left: 5px;
-}
-
-ul.page-nav li.current a {
- color: #556CB5;
-}
-
-ul.page-nav li a {
- height: 24px;
- color: #FFF;
- padding-right: 5px;
- padding-left: 5px;
- display: block;
- text-decoration: none;
- font-weight: bold;
-}
-
-ul.page-nav li.logout a {
- color: #FDAC9D;
-}
-
-ul.page-nav li a:hover {
- background: #FFF;
- color: #556CB5;
-}
-
-ul.submenu {
- margin: 5px 0px -20px 0px;
- list-style-type: none;
-}
-
-ul.submenu li {
- margin: 0 10px 0 0;
- font-size: 0.9em;
- font-weight: bold;
- display: inline;
-}
-
-ul.submenu .repos {
- background: url("/images/icons/folder_edit.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- padding-top: 0px;
- text-align: left;
-}
-
-ul.submenu .users {
- background: url("/images/icons/user_edit.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- padding-top: 0px;
- text-align: left;
-}
-
-ul.submenu .permissions {
- background: url("/images/icons/folder_key.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- padding-top: 0px;
- text-align: left;
-}
-ul.submenu .settings {
- background: url("/images/icons/cog.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- padding-top: 0px;
- text-align: left;
-}
-
-ul.submenu .current_submenu {
- border-bottom: 2px solid #556CB5;
-}
-
-h2 {
- margin: 20px 0 10px;
- height: 30px;
- line-height: 30px;
- text-indent: 20px;
- background: #FFF;
- font-size: 1.2em;
- border-top: dotted 1px #D5E1E6;
- font-weight: bold;
- color: #556CB5;
-}
-
-h2.no-link {
- color: #006699;
-}
-
-h2.no-border {
- color: #FFF;
- background: #556CB5;
- border: 0;
-}
-
-h2 a {
- font-weight: bold;
- color: #006699;
-}
-
-div.page-path {
- text-align: right;
- padding: 20px 30px 10px 0;
- border: solid #d9d8d1;
- border-width: 0px 0px 1px;
- font-size: 1.2em;
-}
-
-div.page-footer {
- margin: 50px 0 0;
- position: relative;
- text-align: center;
- font-weight: bold;
- font-size: 90%;
-}
-
-div.page-footer p {
- position: relative;
- left: 20px;
- bottom: 5px;
- font-size: 1.2em;
-}
-
-ul.rss-logo {
- position: absolute;
- top: -10px;
- right: 20px;
- height: 20px;
- list-style-type: none;
-}
-
-ul.rss-logo li {
- display: inline;
-}
-
-ul.rss-logo li a {
- padding: 3px 6px;
- line-height: 10px;
- border: 1px solid;
- border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
- color: #ffffff;
- background-color: #ff6600;
- font-weight: bold;
- font-family: sans-serif;
- font-size: 10px;
- text-align: center;
- text-decoration: none;
-}
-
-div.rss-logo li a:hover {
- background-color: #ee5500;
-}
-
-p.normal {
- margin: 20px 0 20px 30px;
- font-size: 1.2em;
-}
-
-span.logtags span {
- background-repeat: no-repeat;
- height: 16px;
- padding-left: 20px;
- padding-top: 0px;
- text-align: left;
- font-weight: bold;
-}
-
-span.logtags span.tagtag {
- background-image: url("/images/icons/tag_green.png");
-}
-
-span.logtags span.branchtag {
- background-image: url("/images/icons/arrow_branch.png");
- color: #628F53;
-}
-
-span.logtags span.inbranchtag {
- background-image: url("/images/icons/arrow_branch.png");
-}
-
-div.diff pre {
- margin: 10px 0 0 0;
-}
-
-div.diff pre span {
- font-family: monospace;
- white-space: pre;
- font-size: 1.2em;
- padding: 3px 0;
-}
-
-td.source {
- white-space: pre;
- font-family: monospace;
- margin: 10px 30px 0;
- font-size: 1.2em;
- font-family: monospace;
-}
-
-div.source div.parity0,div.source div.parity1 {
- padding: 1px;
- font-size: 1.2em;
-}
-
-div.source div.parity0 {
- background: #F1F6F7;
-}
-
-div.source div.parity1 {
- background: #FFFFFF;
-}
-
-div.parity0:hover,div.parity1:hover {
- background: #D5E1E6;
-}
-
-.linenr {
- color: #999;
- text-align: right;
-}
-
-.lineno {
- text-align: right;
-}
-
-.lineno a {
- color: #999;
-}
-
-td.linenr {
- width: 60px;
-}
-
-div#powered-by {
- position: absolute;
- width: 75px;
- top: 15px;
- right: 20px;
- font-size: 1.2em;
-}
-
-div#powered-by a {
- color: #EEE;
- text-decoration: none;
-}
-
-div#powered-by a:hover {
- text-decoration: underline;
-}
-
-dl.overview {
- margin: 0 0 0 30px;
- font-size: 1.1em;
- overflow: hidden;
-}
-
-dl.overview dt,dl.overview dd {
- margin: 5px 0;
- float: left;
-}
-
-dl.overview dt {
- clear: left;
- font-weight: bold;
- width: 150px;
-}
-
-#clone_url {
- border: 0px;
-}
-
-/** end of summary **/ /** chagelog **/
-h3.changelog {
- margin: 20px 0 5px 30px;
- padding: 0 0 2px;
- font-size: 1.4em;
- border-bottom: dotted 1px #D5E1E6;
-}
-
-ul.changelog-entry {
- margin: 0 0 10px 30px;
- list-style-type: none;
- position: relative;
-}
-
-ul.changelog-entry li span.revdate {
- font-size: 1.1em;
-}
-
-ul.changelog-entry li.age {
- position: absolute;
- top: -25px;
- right: 10px;
- font-size: 1.4em;
- color: #CCC;
- font-weight: bold;
- font-style: italic;
-}
-
-ul.changelog-entry li span.name {
- font-size: 1.2em;
- font-weight: bold;
-}
-
-ul.changelog-entry li.description {
- margin: 10px 0 0;
- font-size: 1.1em;
-}
-
-/** end of changelog **/ /** file **/
-p.files {
- margin: 0 0 0 20px;
- font-size: 2.0em;
- font-weight: bold;
-}
-
-/** end of file **/ /** changeset **/
-#changeset_content {
- border:1px solid #CCCCCC;
- padding:5px;
-}
-
-#changeset_content .container .wrapper {
- width: 600px;
-}
-
-#changeset_content .container {
- height: 120px;
-}
-
-#changeset_content .container .left {
- float: left;
- width: 70%;
- padding-left: 5px;
-}
-
-#changeset_content .container .right {
- float: right;
- width: 25%;
- text-align: right;
-}
-
-#changeset_content .container .left .date {
- font-weight: bold;
-}
-
-#changeset_content .container .left .author {
-
-}
-
-#changeset_content .container .left .message {
- font-style: italic;
- color: #556CB5;
-}
-
-.cs_files {
-
-}
-
-.cs_files .cs_added {
- background: url("/images/icons/page_white_add.png") no-repeat scroll 3px;
- /*background-color:#BBFFBB;*/
- height: 16px;
- padding-left: 20px;
- margin-top: 7px;
- text-align: left;
-}
-
-.cs_files .cs_changed {
- background: url("/images/icons/page_white_edit.png") no-repeat scroll
- 3px;
- /*background-color: #FFDD88;*/
- height: 16px;
- padding-left: 20px;
- margin-top: 7px;
- text-align: left;
-}
-
-.cs_files .cs_removed {
- background: url("/images/icons/page_white_delete.png") no-repeat scroll
- 3px;
- /*background-color: #FF8888;*/
- height: 16px;
- padding-left: 20px;
- margin-top: 7px;
- text-align: left;
-}
-
-/** end of changeset **/ /** canvas **/
-
-#graph {
- overflow: hidden;
-}
-
-#graph_nodes {
- width: 160px;
- float: left;
- margin-left:-50px;
- margin-top: 5px;
-}
-
-#graph_content {
- width: 800px;
- float: left;
-}
-
-#graph_content .container_header {
- border: 1px solid #CCCCCC;
- height: 30px;
- background: #EEEEEE;
-}
-
-#graph_content .container .wrapper {
- width: 600px;
-}
-
-#graph_content .container {
- border-bottom: 1px solid #CCCCCC;
- border-left: 1px solid #CCCCCC;
- border-right: 1px solid #CCCCCC;
- min-height: 80px;
- overflow: hidden;
-}
-
-#graph_content .container .left {
- float: left;
- width: 70%;
- padding-left: 5px;
-}
-
-#graph_content .container .right {
- float: right;
- width: 25%;
- text-align: right;
-}
-
-#graph_content .container .left .date {
- font-weight: bold;
-}
-
-#graph_content .container .left .author {
-
-}
-
-#graph_content .container .left .message {
- font-size: 80%;
-}
-
-.right div {
- clear: both;
-}
-
-.right .changes .added,.changed,.removed {
- border: 1px solid #DDDDDD;
- display: block;
- float: right;
- font-size: 0.75em;
- text-align: center;
- min-width: 15px;
-}
-
-.right .changes .added {
- background: #BBFFBB;
-}
-
-.right .changes .changed {
- background: #FFDD88;
-}
-
-.right .changes .removed {
- background: #FF8888;
-}
-
-.right .merge {
- vertical-align: top;
- font-size: 60%;
- font-weight: bold;
-}
-
-.right .merge img {
- vertical-align: bottom;
-}
-
-.right .parent {
- font-size: 90%;
- font-family: monospace;
-}
-
-/** end of canvas **/ /* FILE BROWSER */
-div.browserblock {
- overflow: hidden;
- padding: 0px;
- border: 1px solid #ccc;
- background: #f8f8f8;
- font-size: 100%;
- line-height: 100%;
- /* new */
- line-height: 125%;
-}
-
-div.browserblock .browser-header {
- border-bottom: 1px solid #CCCCCC;
- background: #EEEEEE;
- color: blue;
- padding: 10px 0 10px 0;
-}
-
-div.browserblock .browser-header span {
- margin-left: 25px;
- font-weight: bold;
-}
-
-div.browserblock .browser-body {
- background: #EEEEEE;
-}
-
-table.code-browser {
- border-collapse: collapse;
- width: 100%;
-}
-
-table.code-browser tr {
- margin: 3px;
-}
-
-table.code-browser thead th {
- background-color: #EEEEEE;
- height: 20px;
- font-size: 1.1em;
- font-weight: bold;
- text-align: center;
- text-align: left;
- padding-left: 10px;
-}
-
-table.code-browser tbody tr {
-
-}
-
-table.code-browser tbody td {
- padding-left: 10px;
- height: 20px;
-}
-
-.info-table {
- background: none repeat scroll 0 0 #FAFAFA;
- border-bottom: 1px solid #DDDDDD;
- width: 100%;
-}
-
-.rss_logo {
- background: url("/images/icons/rss_16.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- padding-top: 0px;
- text-align: left;
-}
-
-.atom_logo {
- background: url("/images/icons/atom.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- padding-top: 0px;
- text-align: left;
-}
-
-.archive_logo {
- background: url("/images/icons/compress.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- text-align: left;
-}
-
-.browser-file {
- background: url("/images/icons/document_16.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- text-align: left;
-}
-
-.browser-dir {
- background: url("/images/icons/folder_16.png") no-repeat scroll 3px;
- height: 16px;
- padding-left: 20px;
- text-align: left;
-}
-
-#repos_list {
- border: 1px solid #556CB5;
- background: #FFFFFF;
-} \ No newline at end of file
diff --git a/pylons_app/public/css/pygments.css b/pylons_app/public/css/pygments.css
index a7260547..69fcc725 100644
--- a/pylons_app/public/css/pygments.css
+++ b/pylons_app/public/css/pygments.css
@@ -22,6 +22,15 @@ div.codeblock .code-header .commit{
margin-left:25px;
font-weight: normal;
}
+div.codeblock .code-body table{
+ width: 0 !important;
+}
+
+div.annotatediv{
+ margin-left:2px;
+ margin-right:4px;
+}
+
.code-highlight {
padding: 0px;
diff --git a/pylons_app/public/css/reset.css b/pylons_app/public/css/reset.css
new file mode 100644
index 00000000..13f8e0a1
--- /dev/null
+++ b/pylons_app/public/css/reset.css
@@ -0,0 +1,53 @@
+/* http://meyerweb.com/eric/tools/css/reset/ */
+/* v1.0 | 20080212 */
+
+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: '';
+ content: none;
+}
+
+/* remember to define focus styles! */
+:focus {
+ outline: 0;
+}
+
+/* remember to highlight inserts somehow! */
+ins {
+ text-decoration: none;
+}
+del {
+ text-decoration: line-through;
+}
+
+/* tables still need 'cellspacing="0"' in the markup */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+} \ No newline at end of file
diff --git a/pylons_app/public/css/style.css b/pylons_app/public/css/style.css
new file mode 100644
index 00000000..07f77dc3
--- /dev/null
+++ b/pylons_app/public/css/style.css
@@ -0,0 +1,3624 @@
+/* -----------------------------------------------------------
+ main stylesheet
+----------------------------------------------------------- */
+
+html
+{
+ height: 100%;
+}
+
+body
+{
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ background: #d1d1d1 url("../images/background.png") repeat;
+ font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
+ font-size: 11px;
+}
+
+/* -----------------------------------------------------------
+ images
+----------------------------------------------------------- */
+
+img
+{
+ border: none;
+}
+
+/* -----------------------------------------------------------
+ anchors
+----------------------------------------------------------- */
+
+a
+{
+ color: #0066CC;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+a:hover
+{
+ color: #000000;
+ text-decoration: underline;
+}
+
+/* -----------------------------------------------------------
+ headings
+----------------------------------------------------------- */
+
+h1, h2, h3, h4, h5, h6
+{
+ color: #292929;
+ font-weight: bold;
+}
+
+h1
+{
+ font-size: 22px;
+}
+
+h2
+{
+ font-size: 20px;
+}
+
+h3
+{
+ font-size: 18px;
+}
+
+h4
+{
+ font-size: 16px;
+}
+
+h5
+{
+ font-size: 14px;
+}
+
+h6
+{
+ font-size: 11px;
+}
+
+/* -----------------------------------------------------------
+ lists
+----------------------------------------------------------- */
+
+ul.circle { list-style-type: circle; }
+ul.disc { list-style-type: disc; }
+ul.square { list-style-type: square; }
+ol.lower-roman { list-style-type: lower-roman; }
+ol.upper-roman { list-style-type: upper-roman; }
+ol.lower-alpha { list-style-type: lower-alpha; }
+ol.upper-alpha { list-style-type: upper-alpha; }
+ol.decimal { list-style-type: decimal; }
+
+/* -----------------------------------------------------------
+ colors
+----------------------------------------------------------- */
+
+div.color
+{
+ margin: 7px 0 0 60px;
+ padding: 1px 1px 1px 0px;
+ clear: both;
+ overflow: hidden;
+ position: absolute;
+ background: #FFFFFF;
+}
+
+div.color a
+{
+ margin: 0 0 0 1px;
+ padding: 0;
+ width: 15px;
+ height: 15px;
+ display: block;
+ float: left;
+}
+
+div.color a.blue
+{
+ background: #376ea6;
+}
+
+div.color a.green
+{
+ background: #85924b;
+}
+
+div.color a.brown
+{
+ background: #9b6e42;
+}
+
+div.color a.purple
+{
+ background: #88528b;
+}
+
+div.color a.red
+{
+ background: #bd3220;
+}
+
+div.color a.greyblue
+{
+ background: #566e86;
+}
+
+/* -----------------------------------------------------------
+ options
+----------------------------------------------------------- */
+
+div.options
+{
+ margin: 7px 0 0 162px;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+ position: absolute;
+ background: #FFFFFF;
+}
+
+div.options a
+{
+ margin: 0;
+ padding: 3px 8px 3px 8px;
+ height: 1%;
+ display: block;
+ text-decoration: none;
+}
+
+div.options a:hover
+{
+ text-decoration: none;
+}
+
+/* -----------------------------------------------------------
+ header
+----------------------------------------------------------- */
+
+#header
+{
+ margin: 0;
+ padding: 0 60px 0 60px;
+ background: #b0b0b0 url("../images/header_background.png") repeat;
+}
+
+
+/* -----------------------------------------------------------
+ header -> user
+----------------------------------------------------------- */
+
+#header ul#logged-user
+{
+ margin: 0;
+ padding: 0;
+ float: right;
+}
+
+#header ul#logged-user li
+{
+ margin: 0;
+ padding: 10px 12px 10px 12px;
+ list-style: none;
+ float: left;
+ border-left: 1px solid #bbbbbb;
+ border-right: 1px solid #a5a5a5;
+}
+
+#header ul#logged-user li.first
+{
+ border-left: none;
+}
+
+#header ul#logged-user li.last
+{
+ border-right: none;
+}
+
+#header ul#logged-user li a
+{
+ color: #4e4e4e;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+#header ul#logged-user li a:hover
+{
+ color: #376ea6;
+ text-decoration: underline;
+}
+
+#header ul#logged-user li.highlight a
+{
+ color: #ffffff;
+}
+
+#header ul#logged-user li.highlight a:hover
+{
+ color: #376ea6;
+}
+
+#header #header-inner
+{
+ margin: 0;
+ padding: 0;
+ height: 40px;
+ clear: both;
+ position: relative;
+ background: #003367 url("../images/colors/blue/header_inner.png") repeat-x;
+ border-bottom: 6px solid #ffffff;
+}
+
+/* -----------------------------------------------------------
+ header -> home
+----------------------------------------------------------- */
+
+#header #header-inner #home
+{
+ float: left;
+}
+
+#header #header-inner #home a
+{
+ margin: 0;
+ padding: 0;
+ height: 40px;
+ width: 46px;
+ display: block;
+ background: url("../images/colors/blue/button_home.png");
+ background-position: 0 0;
+}
+
+#header #header-inner #home a:hover
+{
+ background-position: 0 -40px;
+}
+
+/* -----------------------------------------------------------
+ header -> logo
+----------------------------------------------------------- */
+
+#header #header-inner #logo
+{
+ float: left;
+}
+
+#header #header-inner #logo h1
+{
+ margin: 13px 0 0 13px;
+ padding: 0;
+ color: #FFFFFF;
+ font-size: 14px;
+ text-transform: uppercase;
+}
+
+#header #header-inner #logo a
+{
+ color: #ffffff;
+ text-decoration: none;
+}
+
+#header #header-inner #logo a:hover
+{
+ color: #dabf29;
+}
+
+/* -----------------------------------------------------------
+ header -> quick
+----------------------------------------------------------- */
+
+#header #header-inner #quick,
+#header #header-inner #quick ul
+{
+ margin: 10px 5px 0 0;
+ padding: 0;
+ position: relative;
+ float: right;
+ list-style-type: none;
+ list-style-position: outside;
+}
+
+#header #header-inner #quick li
+{
+ margin: 0 4px 0 0;
+ padding: 0;
+ position: relative;
+ float: left;
+}
+
+#header #header-inner #quick li a
+{
+ top: 0;
+ left: 0;
+ padding: 0;
+ height: 1%;
+ display: block;
+ clear: both;
+ overflow: hidden;
+ background: #336699 url("../images/colors/blue/quick_l.png") no-repeat top left;
+ color: #FFFFFF;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+#header #header-inner #quick li span
+{
+ top: 0;
+ right: 0;
+ margin: 0;
+ padding: 10px 12px 8px 10px;
+ height: 1%;
+ display: block;
+ float: left;
+ background: url("../images/colors/blue/quick_r.png") no-repeat top right;
+ border-left: 1px solid #3f6f9f;
+}
+
+#header #header-inner #quick li span.icon
+{
+ top: 0;
+ left: 0;
+ padding: 8px 8px 4px 8px;
+ background: url("../images/colors/blue/quick_l.png") no-repeat top left;
+ border-left: none;
+ border-right: 1px solid #2e5c89;
+}
+
+#header #header-inner #quick li a:hover
+{
+ background: #4e4e4e;
+}
+
+#header #header-inner #quick li a:hover span
+{
+ background: url("../images/colors/blue/quick_r_selected.png") no-repeat top right;
+ border-left: 1px solid #545454;
+}
+
+#header #header-inner #quick li a:hover span.icon
+{
+ background: url("../images/colors/blue/quick_l_selected.png") no-repeat top left;
+ border-left: none;
+ border-right: 1px solid #464646;
+}
+
+#header #header-inner #quick ul
+{
+ top: 29px;
+ right: 0;
+ margin: 0;
+ padding: 0;
+ width: 200px;
+ display: none;
+ position: absolute;
+ background: #FFFFFF;
+ border: 1px solid #666;
+ border-top: 1px solid #003367;
+}
+
+#header #header-inner #quick li ul li
+{
+ border-bottom: 1px solid #dddddd;
+}
+
+#header #header-inner #quick li ul li.last
+{
+ border: none;
+}
+
+#header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover
+{
+ margin: 0;
+ padding: 12px 9px 7px 28px;
+ width: 167px;
+ background: #FFFFFF url("../images/icons/folder_edit.png") no-repeat 8px 9px;
+}
+#header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover
+{
+ margin: 0;
+ padding: 12px 9px 7px 28px;
+ width: 167px;
+ background: #FFFFFF url("../images/icons/user_edit.png") no-repeat 8px 9px;
+}
+#header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover
+{
+ margin: 0;
+ padding: 12px 9px 7px 28px;
+ width: 167px;
+ background: #FFFFFF url("../images/icons/cog.png") no-repeat 8px 9px;
+}
+
+#header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover
+{
+ margin: 0;
+ padding: 12px 9px 7px 28px;
+ width: 167px;
+ background: #FFFFFF url("../images/icons/key.png") no-repeat 8px 9px;
+}
+
+#header #header-inner #quick li ul li a
+{
+ margin: 0;
+ padding: 7px 9px 7px 9px;
+ height: 1%;
+ width: 182px;
+ height: auto;
+ display: block;
+ float: left;
+ background: #FFFFFF;
+ color: #0066CC;
+ font-weight: normal;
+}
+
+#header #header-inner #quick li ul li a:hover
+{
+ color: #000000;
+ background: #FFFFFF;
+}
+
+#header #header-inner #quick ul ul
+{
+ top: auto;
+}
+
+#header #header-inner #quick li ul ul
+{
+ right: 200px;
+}
+
+#header #header-inner #quick li:hover ul ul,
+#header #header-inner #quick li:hover ul ul ul,
+#header #header-inner #quick li:hover ul ul ul ul
+{
+ display: none;
+}
+
+#header #header-inner #quick li:hover ul,
+#header #header-inner #quick li li:hover ul,
+#header #header-inner #quick li li li:hover ul,
+#header #header-inner #quick li li li li:hover ul
+{
+ display: block;
+}
+
+/* -----------------------------------------------------------
+ header corners
+----------------------------------------------------------- */
+
+#header #header-inner div.corner
+{
+ height: 6px;
+ width: 6px;
+ position: absolute;
+ background: url("../images/colors/blue/header_inner_corners.png") no-repeat;
+}
+
+#header #header-inner div.tl
+{
+ top: 0;
+ left: 0;
+ background-position: 0 0;
+}
+
+#header #header-inner div.tr
+{
+ top: 0;
+ right: 0;
+ background-position: -6px 0;
+}
+
+/* -----------------------------------------------------------
+ content
+----------------------------------------------------------- */
+
+#content
+{
+ margin: 10px 0 0 0;
+ padding: 0;
+ min-height: 100%;
+ clear: both;
+ overflow: hidden;
+ background: url("../images/content.png") repeat-y top left;
+}
+
+/* -----------------------------------------------------------
+ content -> left
+----------------------------------------------------------- */
+
+#content #left
+{
+ left: 0;
+ width: 280px;
+ position: absolute;
+}
+
+/* -----------------------------------------------------------
+ content -> left -> menu
+----------------------------------------------------------- */
+
+#content #left #menu
+{
+ margin: 5px 10px 0 60px;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+}
+
+/* -----------------------------------------------------------
+ content -> left -> menu / heading
+----------------------------------------------------------- */
+
+#content #left #menu h6
+{
+ margin: 5px 0 0 0;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+ background: #dfdfdf url("../images/menu.png") repeat-x;
+ color: #6e6e6e;
+}
+
+#content #left #menu h6 a
+{
+ margin: 0;
+ padding: 0;
+ height: 1%;
+ display: block;
+ clear: both;
+ overflow: hidden;
+ background: url("../images/menu_l.png") no-repeat top left;
+ color: #6e6e6e;
+ text-decoration: none;
+}
+
+#content #left #menu h6 span
+{
+ margin: 0;
+ padding: 9px 10px 10px 10px;
+ height: 1%;
+ display: block;
+ background: url("../images/menu_r.png") no-repeat top right;
+}
+
+#content #left #menu h6.selected
+{
+ background: #00376e url("../images/colors/blue/menu_selected.png") repeat-x;
+ color: #FFFFFF;
+}
+
+#content #left #menu h6.selected a
+{
+ background: url("../images/colors/blue/menu_l_selected.png") no-repeat top left;
+ color: #ffffff;
+}
+
+#content #left #menu h6.selected span
+{
+ background: url("../images/colors/blue/menu_r_selected.png") no-repeat top right;
+}
+
+/* -----------------------------------------------------------
+ content -> left -> menu / links
+----------------------------------------------------------- */
+
+#content #left #menu ul
+{
+ margin: 0;
+ padding: 0;
+ background: #376ea6;
+}
+
+#content #left #menu ul.opened
+{
+ display: block;
+}
+
+#content #left #menu ul.closed
+{
+ display: none;
+}
+
+#content #left #menu li
+{
+ margin: 0;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+ list-style: none;
+ border-bottom: 1px solid #5f8bb7;
+ color: #ffffff;
+}
+
+#content #left #menu li a
+{
+ margin: 0 0 0 6px;
+ padding: 8px 0 8px 18px;
+ height: 1%;
+ display: block;
+ float: left;
+ background: url("../images/colors/colors/blue/menu_arrow.png") no-repeat 0 9px;
+ color: #ffffff;
+ text-decoration: none;
+}
+
+#content #left #menu li a:hover
+{
+ color: #b9dcff;
+}
+
+/* -----------------------------------------------------------
+ content -> left -> menu / collapsible
+----------------------------------------------------------- */
+
+#content #left #menu li.collapsible
+{
+ background: url("../images/colors/blue/menu_border.png") no-repeat top left;
+}
+
+#content #left #menu li.collapsible a
+{
+ margin: 0 0 0 6px;
+ padding: 8px 0 8px 0;
+ height: 1%;
+ display: block;
+ background: transparent;
+ float: left;
+ font-weight: bold;
+}
+
+#content #left #menu li.collapsible a.plus
+{
+ margin: 0;
+ padding: 8px 0 9px 24px;
+ height: 10px;
+ width: 10px;
+ display: block;
+ float: left;
+ background: url("../images/menu_plus.png") no-repeat 5px 10px;
+ border: none;
+}
+
+#content #left #menu li.collapsible a.minus
+{
+ margin: 0;
+ padding: 8px 0 9px 24px;
+ height: 10px;
+ width: 10px;
+ display: block;
+ float: left;
+ background: url("../images/menu_minus.png") no-repeat 5px 10px;
+ border: none;
+}
+
+#content #left #menu li ul
+{
+ margin: 0;
+ padding: 0;
+ border-left: 18px solid #285889;
+}
+
+#content #left #menu li ul.expanded
+{
+ display: block;
+}
+
+#content #left #menu li ul.collapsed
+{
+ display: none;
+}
+
+#content #left #menu li ul li
+{
+ margin: 0;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+ list-style: none;
+ border-bottom: 1px solid #5f8bb7;
+ color: #ffffff;
+}
+
+#content #left #menu li.collapsible ul li a
+{
+ font-weight: normal;
+}
+
+#content #left #menu li.last
+{
+ border-bottom: none;
+}
+
+/* -----------------------------------------------------------
+ content -> left -> date picker
+----------------------------------------------------------- */
+
+#content #left #date-picker
+{
+ margin: 10px 10px 0 60px;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#content #left #date-picker .ui-datepicker
+{
+ width: auto;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+ background: #FFFFFF;
+ border: 1px solid #d1d1d1;
+}
+
+#content #left #date-picker .ui-datepicker .ui-datepicker-header
+{
+ padding: 5px 0;
+}
+
+#content #left #date-picker .ui-datepicker .ui-datepicker-prev
+{
+ top: 5px;
+ left: 4px;
+}
+
+#content #left #date-picker .ui-datepicker .ui-datepicker-next
+{
+ top: 5px;
+ right: 4px;
+}
+
+#content #left #date-picker .ui-datepicker .ui-datepicker-prev-hover
+{
+ top: 5px;
+ left: 4px;
+}
+
+#content #left #date-picker .ui-datepicker .ui-datepicker-next-hover
+{
+ top: 5px;
+ right: 4px;
+}
+
+/* -----------------------------------------------------------
+ content -> right
+----------------------------------------------------------- */
+
+#content #right
+{
+ margin: 0 60px 10px 290px;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box
+----------------------------------------------------------- */
+
+#content div.box
+{
+ margin: 0 0 10px 0;
+ padding: 0 0 10px 0;
+ clear: both;
+ overflow: hidden;
+ background: #ffffff;
+}
+
+#content div.box-left
+{
+ margin: 0 0 10px;
+ width: 49%;
+ clear: none;
+ float: left;
+}
+
+#content div.box-right
+{
+ margin: 0 0 10px;
+ width: 49%;
+ clear: none;
+ float: right;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / title
+----------------------------------------------------------- */
+
+#content div.box div.title
+{
+ margin: 0 0 20px 0;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+ background: #336699 url("../images/colors/blue/title.png") repeat-x;
+}
+
+#content div.box div.title h5
+{
+ margin: 0;
+ padding: 11px 0 11px 10px;
+ float: left;
+ border: none;
+ color: #ffffff;
+ text-transform: uppercase;
+}
+
+#content div.box div.title ul.links
+{
+ margin: 0;
+ padding: 0;
+ float: right;
+}
+
+#content div.box div.title ul.links li
+{
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ float: left;
+}
+
+#content div.box div.title ul.links li a
+{
+ margin: 0;
+ padding: 13px 16px 12px 16px;
+ height: 1%;
+ display: block;
+ float: left;
+ background: url("../images/colors/blue/title_link.png") no-repeat top left;
+ border-left: 1px solid #316293;
+ color: #ffffff;
+ font-size: 11px;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+#content div.box div.title ul.links li a:hover
+{
+ color: #bfe3ff;
+}
+
+#content div.box div.title ul.links li.ui-tabs-selected a
+{
+ background: url("../../../resources/images/colors/blue/title_tab_selected.png") no-repeat bottom center;
+ color: #bfe3ff;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / headings
+----------------------------------------------------------- */
+
+#content div.box h1,
+#content div.box h2,
+#content div.box h3,
+#content div.box h4,
+#content div.box h5,
+#content div.box h6
+{
+ margin: 10px 20px 10px 20px;
+ padding: 0 0 15px 0;
+ clear: both;
+ overflow: hidden;
+ border-bottom: 1px solid #DDDDDD;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / paragraphs
+----------------------------------------------------------- */
+
+#content div.box p
+{
+ margin: 0 24px 10px 24px;
+ padding: 0;
+ color: #5f5f5f;
+ font-size: 12px;
+ line-height: 150%;
+}
+
+#content div.box blockquote
+{
+ margin: 0 34px 0 34px;
+ padding: 0 0 0 14px;
+ border-left: 4px solid #DDDDDD;
+ color: #5f5f5f;
+ font-size: 11px;
+ line-height: 150%;
+}
+
+#content div.box blockquote p
+{
+ margin: 10px 0 10px 0;
+ padding: 0;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / lists
+----------------------------------------------------------- */
+
+#content div.box dl
+{
+ margin: 10px 24px 10px 24px;
+}
+
+#content div.box dt
+{
+ margin: 0;
+ font-size: 12px;
+}
+
+#content div.box dd
+{
+ margin: 0;
+ padding: 8px 0 8px 15px;
+ font-size: 12px;
+}
+
+#content div.box ul.left
+{
+ float: left;
+}
+
+#content div.box ol.left
+{
+ float: left;
+}
+
+#content div.box li
+{
+ padding: 4px 0 4px 0;
+ font-size: 12px;
+}
+
+#content div.box ol.lower-roman,
+#content div.box ol.upper-roman
+{
+ margin: 10px 24px 10px 44px;
+}
+
+#content div.box ol.lower-alpha,
+#content div.box ol.upper-alpha
+{
+ margin: 10px 24px 10px 44px;
+}
+
+#content div.box ol.decimal
+{
+ margin: 10px 24px 10px 44px;
+}
+
+#content div.box ul.disc,
+#content div.box ul.circle
+{
+ margin: 10px 24px 10px 38px;
+}
+
+#content div.box ul.square
+{
+ margin: 10px 24px 10px 40px;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / images
+----------------------------------------------------------- */
+
+#content div.box img.left
+{
+ margin: 10px 10px 10px 0;
+ border: none;
+ float: left;
+}
+
+#content div.box img.right
+{
+ margin: 10px 0 10px 10px;
+ border: none;
+ float: right;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / messages
+----------------------------------------------------------- */
+
+#content div.box div.messages
+{
+ margin: 0 20px 0 20px;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#content div.box div.message
+{
+ margin: 0 0 10px 0;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#content div.box div.message div.image
+{
+ margin: 9px 0 0 5px;
+ padding: 6px;
+ float: left;
+}
+
+#content div.box div.message div.image img
+{
+ margin: 0;
+ vertical-align: middle;
+}
+
+#content div.box div.message div.text
+{
+ margin: 0;
+ padding: 9px 6px 9px 6px;
+ float: left;
+}
+
+#content div.box div.message div.dismiss
+{
+ margin: 0;
+ padding: 0;
+ float: right;
+}
+
+#content div.box div.message div.dismiss a
+{
+ margin: 15px 14px 0 0;
+ padding: 0;
+ height: 16px;
+ width: 16px;
+ display: block;
+ background: url("../images/icons/cross.png") no-repeat;
+}
+
+#content div.box div.message div.text h1,
+#content div.box div.message div.text h2,
+#content div.box div.message div.text h3,
+#content div.box div.message div.text h4,
+#content div.box div.message div.text h5,
+#content div.box div.message div.text h6
+{
+ margin: 0;
+ padding: 0px;
+ border: none;
+}
+
+#content div.box div.message div.text span
+{
+ margin: 0;
+ padding: 5px 0 0 0;
+ height: 1%;
+ display: block;
+}
+
+#content div.box div.message-error
+{
+ height: 1%;
+ clear: both;
+ overflow: hidden;
+ background: #FBE3E4;
+ border: 1px solid #FBC2C4;
+ color: #860006;
+}
+
+#content div.box div.message-error h6
+{
+ color: #860006;
+}
+
+#content div.box div.message-warning
+{
+ height: 1%;
+ clear: both;
+ overflow: hidden;
+ background: #FFF6BF;
+ border: 1px solid #FFD324;
+ color: #5f5200;
+}
+
+#content div.box div.message-warning h6
+{
+ color: #5f5200;
+}
+
+#content div.box div.message-notice
+{
+ height: 1%;
+ clear: both;
+ overflow: hidden;
+ background: #8FBDE0;
+ border: 1px solid #6BACDE;
+ color: #003863;
+}
+
+#content div.box div.message-notice h6
+{
+ color: #003863;
+}
+
+#content div.box div.message-success
+{
+ height: 1%;
+ clear: both;
+ overflow: hidden;
+ background: #E6EFC2;
+ border: 1px solid #C6D880;
+ color: #4e6100;
+}
+
+#content div.box div.message-success h6
+{
+ color: #4e6100;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / forms
+----------------------------------------------------------- */
+
+#content div.box div.form
+{
+ margin: 0;
+ padding: 0 20px 10px 20px;
+ clear: both;
+ overflow: hidden;
+}
+
+#content div.box div.form div.fields
+{
+ margin: 0;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#content div.box div.form div.fields div.field
+{
+ margin: 0;
+ padding: 10px 0 10px 0;
+ height: 1%;
+ border-bottom: 1px solid #DDDDDD;
+ clear: both;
+ overflow: hidden;
+}
+
+#content div.box div.form div.fields div.field-first
+{
+ padding: 0 0 10px 0;
+}
+
+#content div.box div.form div.fields div.field span.error-message
+{
+ margin: 8px 0 0 0;
+ padding: 0;
+ height: 1%;
+ display: block;
+ color: #FF0000;
+}
+
+#content div.box div.form div.fields div.field span.success
+{
+ margin: 8px 0 0 0;
+ padding: 0;
+ height: 1%;
+ display: block;
+ color: #316309;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> labels
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.label
+{
+ left: 310px;
+ margin: 0;
+ padding: 8px 0 0 5px;
+ width: auto;
+ position: absolute;
+}
+
+#content div.box-left div.form div.fields div.field div.label,
+#content div.box-right div.form div.fields div.field div.label
+{
+ left: 0;
+ margin: 0;
+ padding: 0 0 8px 0;
+ width: auto;
+ position: relative;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> label (select)
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.label-select
+{
+ padding: 2px 0 0 5px;
+}
+
+#content div.box-left div.form div.fields div.field div.label-select,
+#content div.box-right div.form div.fields div.field div.label-select
+{
+ padding: 0 0 8px 0;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> label (checkbox)
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.label-checkbox
+{
+ padding: 0 0 0 5px;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> label (radio)
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.label-radio
+{
+ padding: 0 0 0 5px;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> label (textarea)
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.label-textarea
+{
+ padding: 0 0 0 5px;
+}
+
+#content div.box-left div.form div.fields div.field div.label-textarea,
+#content div.box-right div.form div.fields div.field div.label-textarea
+{
+ padding: 0 0 8px 0;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> labels (label)
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.label label
+{
+ color: #393939;
+ font-weight: bold;
+}
+
+#content div.box div.form div.fields div.field div.label span
+{
+ margin: 0;
+ padding: 2px 0 0 0;
+ height: 1%;
+ display: block;
+ color: #363636;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> input
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.input
+{
+ margin: 0 0 0 200px;
+ padding: 0;
+}
+
+#content div.box-left div.form div.fields div.field div.input,
+#content div.box-right div.form div.fields div.field div.input
+{
+ margin: 0;
+ padding: 7px 7px 6px 7px;
+ border-top: 1px solid #b3b3b3;
+ border-left: 1px solid #b3b3b3;
+ border-right: 1px solid #eaeaea;
+ border-bottom: 1px solid #eaeaea;
+}
+
+#content div.box div.form div.fields div.field div.input input
+{
+ margin: 0;
+ padding: 7px 7px 6px 7px;
+ background: #FFFFFF;
+ border-top: 1px solid #b3b3b3;
+ border-left: 1px solid #b3b3b3;
+ border-right: 1px solid #eaeaea;
+ border-bottom: 1px solid #eaeaea;
+ color: #000000;
+ font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
+ font-size: 11px;
+}
+
+#content div.box-left div.form div.fields div.field div.input input,
+#content div.box-right div.form div.fields div.field div.input input
+{
+ width: 100%;
+ padding: 0;
+ border: none;
+}
+
+#content div.box div.form div.fields div.field div.input input.small
+{
+ width: 30%;
+}
+
+#content div.box div.form div.fields div.field div.input input.medium
+{
+ width: 55%;
+}
+
+#content div.box div.form div.fields div.field div.input input.large
+{
+ width: 85%;
+}
+
+#content div.box div.form div.fields div.field div.input input.date
+{
+ width: 177px;
+}
+
+#content div.box div.form div.fields div.field div.input input.button
+{
+ margin: 0;
+ padding: 4px 8px 4px 8px;
+ background: #D4D0C8;
+ border-top: 1px solid #FFFFFF;
+ border-left: 1px solid #FFFFFF;
+ border-right: 1px solid #404040;
+ border-bottom: 1px solid #404040;
+ color: #000000;
+}
+
+#content div.box div.form div.fields div.field div.input input.error
+{
+ background: #FBE3E4;
+ border-top: 1px solid #e1b2b3;
+ border-left: 1px solid #e1b2b3;
+ border-right: 1px solid #FBC2C4;
+ border-bottom: 1px solid #FBC2C4;
+}
+
+#content div.box div.form div.fields div.field div.input input.success
+{
+ background: #E6EFC2;
+ border-top: 1px solid #cebb98;
+ border-left: 1px solid #cebb98;
+ border-right: 1px solid #c6d880;
+ border-bottom: 1px solid #c6d880;
+}
+
+#content div.box div.form div.fields div.field div.input img.ui-datepicker-trigger
+{
+ margin: 0 0 0 6px;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> input (file styling)
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.input a.ui-input-file
+{
+ margin: 0 0 0 6px;
+ padding: 0;
+ width: 28px;
+ height: 28px;
+ display: inline;
+ position: absolute;
+ overflow: hidden;
+ cursor: pointer;
+ background: #e5e3e3 url("../images/button_browse.png") no-repeat;
+ border: none;
+ text-decoration: none;
+}
+
+#content div.box div.form div.fields div.field div.input a:hover.ui-input-file
+{
+ background: #e5e3e3 url("../images/button_browse_selected.png") no-repeat;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> textarea
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.textarea
+{
+ margin: 0 0 0 200px;
+ padding: 10px;
+ border-top: 1px solid #b3b3b3;
+ border-left: 1px solid #b3b3b3;
+ border-right: 1px solid #eaeaea;
+ border-bottom: 1px solid #eaeaea;
+}
+
+#content div.box div.form div.fields div.field div.textarea-editor
+{
+ padding: 0;
+ border: 1px solid #dddddd;
+}
+
+#content div.box-left div.form div.fields div.field div.textarea,
+#content div.box-right div.form div.fields div.field div.textarea
+{
+ margin: 0;
+}
+
+#content div.box div.form div.fields div.field div.textarea textarea
+{
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ height: 220px;
+ overflow: hidden;
+ background: #FFFFFF;
+ border-width: 0;
+ color: #000000;
+ font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
+ font-size: 11px;
+ outline: none;
+}
+
+#content div.box-left div.form div.fields div.field div.textarea textarea,
+#content div.box-right div.form div.fields div.field div.textarea textarea
+{
+ width: 100%;
+ height: 100px;
+}
+
+#content div.box div.form div.fields div.field div.textarea textarea.error
+{
+ padding: 3px 10px 10px 23px;
+ background-color: #FBE3E4;
+ background-image: url("../../../resources/images/icons/exclamation.png");
+ background-repeat: no-repeat;
+ background-position: 3px 3px;
+ border: 1px solid #FBC2C4;
+}
+
+#content div.box div.form div.fields div.field div.textarea textarea.success
+{
+ padding: 3px 10px 10px 23px;
+ background-color: #E6EFC2;
+ background-image: url("../../../resources/images/icons/accept.png");
+ background-repeat: no-repeat;
+ background-position: 3px 3px;
+ border: 1px solid #C6D880;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> textarea (tinymce editor)
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.textarea table
+{
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ border: none;
+}
+
+#content div.box div.form div.fields div.field div.textarea table td
+{
+ padding: 0;
+ background: #DDDDDD;
+ border: none;
+}
+
+#content div.box div.form div.fields div.field div.textarea table td table
+{
+ margin: 0;
+ padding: 0;
+ width: auto;
+ border: none;
+}
+
+#content div.box div.form div.fields div.field div.textarea table td table td
+{
+ padding: 5px 5px 5px 0;
+ font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
+ font-size: 11px;
+}
+
+#content div.box div.form div.fields div.field div.textarea table td table td a
+{
+ border: none;
+}
+
+#content div.box div.form div.fields div.field div.textarea table td table td a.mceButtonActive
+{
+ background: #b1b1b1;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> select
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.select
+{
+ margin: 0 0 0 200px;
+ padding: 0;
+}
+
+#content div.box div.form div.fields div.field div.select a:hover
+{
+ color: #000000;
+ text-decoration: none;
+}
+
+#content div.box div.form div.fields div.field div.select select
+{
+ margin: 0;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> select (jquery styling)
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus
+{
+ border: 1px solid #666666;
+}
+
+#content div.box div.form div.fields div.field div.select a.ui-selectmenu
+{
+ color: #565656;
+ text-decoration: none;
+}
+
+#content div.box div.form div.fields div.field div.select a.ui-selectmenu:hover
+{
+ color: #000000;
+ text-decoration: none;
+}
+
+#content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus span.ui-icon
+{
+ background-image: url(../images/ui/ui-icons_222222_256x240.png);
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> element focus
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field input[type=text]:focus,
+#content div.box div.form div.fields div.field input[type=password]:focus,
+#content div.box div.form div.fields div.field input[type=file]:focus,
+#content div.box div.form div.fields div.field textarea:focus,
+#content div.box div.form div.fields div.field select:focus
+{
+ background: #f6f6f6;
+ border-color: #666;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> checkboxes
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.checkboxes
+{
+ margin: 0 0 0 200px;
+ padding: 0;
+}
+
+#content div.box div.form div.fields div.field div.checkboxes div.checkbox
+{
+ margin: 0;
+ padding: 2px 0 2px 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#content div.box div.form div.fields div.field div.checkboxes div.checkbox input
+{
+ margin: 0;
+ float: left;
+}
+
+#content div.box div.form div.fields div.field div.checkboxes div.checkbox label
+{
+ margin: 3px 0 0 4px;
+ height: 1%;
+ display: block;
+ float: left;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> radios
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.radios
+{
+ margin: 0 0 0 200px;
+ padding: 0;
+}
+
+#content div.box div.form div.fields div.field div.radios div.radio
+{
+ margin: 0;
+ padding: 2px 0 2px 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#content div.box div.form div.fields div.field div.radios div.radio input
+{
+ margin: 0;
+ float: left;
+}
+
+#content div.box div.form div.fields div.field div.radios div.radio label
+{
+ margin: 3px 0 0 4px;
+ height: 1%;
+ display: block;
+ float: left;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> buttons
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.buttons
+{
+ margin: 10px 0 0 200px;
+ padding: 0;
+}
+
+#content div.box-left div.form div.fields div.buttons,
+#content div.box-right div.form div.fields div.buttons
+{
+ margin: 10px 0 0 0;
+}
+
+#content div.box div.form div.fields div.buttons input
+{
+ margin: 0;
+ color: #000000;
+ font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
+ font-size: 11px;
+ font-weight: bold;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> buttons (jquery styling)
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.buttons input.ui-state-default
+{
+ margin: 0;
+ padding: 6px 12px 6px 12px;
+ background: #e5e3e3 url("../images/button.png") repeat-x;
+ border-top: 1px solid #DDDDDD;
+ border-left: 1px solid #c6c6c6;
+ border-right: 1px solid #DDDDDD;
+ border-bottom: 1px solid #c6c6c6;
+ color: #515151;
+ outline: none;
+}
+
+#content div.box div.form div.fields div.buttons input.ui-state-hover
+{
+ margin: 0;
+ padding: 6px 12px 6px 12px;
+ background: #b4b4b4 url("../images/button_selected.png") repeat-x;
+ border-top: 1px solid #cccccc;
+ border-left: 1px solid #bebebe;
+ border-right: 1px solid #b1b1b1;
+ border-bottom: 1px solid #afafaf;
+ color: #515151;
+ outline: none;
+}
+
+#content div.box div.form div.fields div.buttons div.highlight
+{
+ display: inline;
+}
+
+#content div.box div.form div.fields div.buttons div.highlight input.ui-state-default
+{
+ margin: 0;
+ padding: 6px 12px 6px 12px;
+ background: #4e85bb url("../images/colors/blue/button_highlight.png") repeat-x;
+ border-top: 1px solid #5c91a4;
+ border-left: 1px solid #2a6f89;
+ border-right: 1px solid #2b7089;
+ border-bottom: 1px solid #1a6480;
+ color: #FFFFFF;
+}
+
+#content div.box div.form div.fields div.buttons div.highlight input.ui-state-hover
+{
+ margin: 0;
+ padding: 6px 12px 6px 12px;
+ background: #46a0c1 url("../images/colors/blue/button_highlight_selected.png") repeat-x;
+ border-top: 1px solid #78acbf;
+ border-left: 1px solid #34819e;
+ border-right: 1px solid #35829f;
+ border-bottom: 1px solid #257897;
+ color: #FFFFFF;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / tables
+----------------------------------------------------------- */
+
+#content div.box div.table
+{
+ margin: 0;
+ padding: 0 20px 10px 20px;
+ clear: both;
+ overflow: hidden;
+}
+
+#content div.box table
+{
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ border-collapse: collapse;
+}
+
+#content div.box table th
+{
+ padding: 10px;
+ background: #eeeeee;
+ border-bottom: 1px solid #dddddd;
+}
+
+#content div.box table th.left
+{
+ text-align: left;
+}
+
+#content div.box table th.right
+{
+ text-align: right;
+}
+
+#content div.box table th.center
+{
+ text-align: center;
+}
+
+#content div.box table th.selected
+{
+ padding: 0;
+ vertical-align: middle;
+}
+
+#content div.box table th.selected input
+{
+ margin: 0;
+}
+
+#content div.box table td
+{
+ padding: 5px;
+ background: #ffffff;
+ border-bottom: 1px solid #cdcdcd;
+}
+
+#content div.box table tr.selected td
+{
+ background: #FFFFCC;
+}
+
+#content div.box table td.selected
+{
+ padding: 0;
+ width: 3%;
+ text-align: center;
+ vertical-align: middle;
+}
+
+#content div.box table td.selected input
+{
+ margin: 0;
+}
+
+#content div.box table td.action
+{
+ width: 45%;
+ text-align: left;
+}
+
+#content div.box table td.user
+{
+ width: 10%;
+ text-align: center;
+}
+
+#content div.box table td.date
+{
+ width: 33%;
+ text-align: center;
+}
+
+#content div.box table td.address
+{
+ width: 10%;
+ text-align: center;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> box / table action
+----------------------------------------------------------- */
+
+#content div.box div.action
+{
+ margin: 10px 0 0 0;
+ padding: 0;
+ float: right;
+ background: #FFFFFF;
+ text-align: right;
+}
+
+#content div.box div.action a:hover
+{
+ color: #000000;
+ text-decoration: none;
+}
+
+#content div.box div.action select
+{
+ margin: 0;
+ font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
+ font-size: 11px;
+}
+
+#content div.box div.action div.button
+{
+ margin: 6px 0 0 0;
+ padding: 0;
+ text-align: right;
+}
+
+#content div.box div.action div.button input
+{
+ margin: 0;
+ color: #000000;
+ font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
+ font-size: 11px;
+ font-weight: bold;
+}
+
+#content div.box div.action div.button input.ui-state-default
+{
+ margin: 0;
+ padding: 6px 12px 6px 12px;
+ background: #e5e3e3 url("../images/button.png") repeat-x;
+ border-top: 1px solid #DDDDDD;
+ border-left: 1px solid #c6c6c6;
+ border-right: 1px solid #DDDDDD;
+ border-bottom: 1px solid #c6c6c6;
+ color: #515151;
+}
+
+#content div.box div.action div.button input.ui-state-hover
+{
+ margin: 0;
+ padding: 6px 12px 6px 12px;
+ background: #b4b4b4 url("../images/button_selected.png") repeat-x;
+ border-top: 1px solid #cccccc;
+ border-left: 1px solid #bebebe;
+ border-right: 1px solid #b1b1b1;
+ border-bottom: 1px solid #afafaf;
+ color: #515151;
+}
+
+#content div.box div.action .ui-selectmenu
+{
+ margin: 0;
+ padding: 0;
+}
+
+#content div.box div.action a.ui-selectmenu-focus
+{
+ border: 1px solid #666666;
+}
+
+#content div.box div.action a.ui-selectmenu-focus span.ui-icon
+{
+ background-image: url(../images/ui/ui-icons_222222_256x240.png);
+}
+
+/* -----------------------------------------------------------
+ content -> right -> pagination
+----------------------------------------------------------- */
+
+#content div.box div.pagination
+{
+ margin: 10px 0 0 0;
+ padding: 0;
+ height: 1%;
+ clear: both;
+ overflow: hidden;
+}
+
+#content div.box div.pagination div.results
+{
+ margin: 0;
+ padding: 0;
+ text-align: left;
+ float: left
+}
+
+#content div.box div.pagination div.results span
+{
+ margin: 0;
+ padding: 6px 8px 6px 8px;
+ height: 1%;
+ display: block;
+ float: left;
+ background: #ebebeb url("../images/pager.png") repeat-x;
+ border-top: 1px solid #dedede;
+ border-left: 1px solid #cfcfcf;
+ border-right: 1px solid #c4c4c4;
+ border-bottom: 1px solid #c4c4c4;
+ color: #4A4A4A;
+ font-weight: bold;
+}
+
+#content div.box div.pagination ul.pager
+{
+ margin: 0;
+ padding: 0;
+ float: right;
+ text-align: right;
+}
+
+#content div.box div.pagination ul.pager li
+{
+ margin: 0 0 0 4px;
+ padding: 0;
+ height: 1%;
+ float: left;
+ list-style: none;
+ background: #ebebeb url("../images/pager.png") repeat-x;
+ border-top: 1px solid #dedede;
+ border-left: 1px solid #cfcfcf;
+ border-right: 1px solid #c4c4c4;
+ border-bottom: 1px solid #c4c4c4;
+ color: #4A4A4A;
+ font-weight: bold;
+}
+
+#content div.box div.pagination ul.pager li.separator
+{
+ padding: 6px;
+}
+
+#content div.box div.pagination ul.pager li.current
+{
+ padding: 6px;
+ background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
+ border-top: 1px solid #cccccc;
+ border-left: 1px solid #bebebe;
+ border-right: 1px solid #b1b1b1;
+ border-bottom: 1px solid #afafaf;
+ color: #515151;
+}
+
+#content div.box div.pagination ul.pager li.disabled
+{
+ padding: 6px;
+ color: #B4B4B4;
+}
+
+#content div.box div.pagination ul.pager li a
+{
+ margin: 0;
+ padding: 6px;
+ height: 1%;
+ display: block;
+ float: left;
+ color: #515151;
+ text-decoration: none;
+}
+
+#content div.box div.pagination ul.pager li a:hover,
+#content div.box div.pagination ul.pager li a:active
+{
+ margin: -1px;
+ background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
+ border-top: 1px solid #cccccc;
+ border-left: 1px solid #bebebe;
+ border-right: 1px solid #b1b1b1;
+ border-bottom: 1px solid #afafaf;
+}
+
+/* -----------------------------------------------------------
+ content -> webhelpers pagination
+----------------------------------------------------------- */
+
+#content div.box div.pagination-wh
+{
+ margin: 10px 0 0 0;
+ padding: 0;
+ height: 1%;
+ clear: both;
+ overflow: hidden;
+ text-align: right;
+}
+
+#content div.box div.pagination-wh div.results
+{
+ margin: 0;
+ padding: 0;
+ text-align: left;
+ float: left
+}
+
+#content div.box div.pagination-wh div.results span
+{
+ margin: 0;
+ padding: 6px 8px 6px 8px;
+ height: 1%;
+ display: block;
+ float: left;
+ background: #ebebeb url("../images/pager.png") repeat-x;
+ border-top: 1px solid #dedede;
+ border-left: 1px solid #cfcfcf;
+ border-right: 1px solid #c4c4c4;
+ border-bottom: 1px solid #c4c4c4;
+ color: #4A4A4A;
+ font-weight: bold;
+}
+
+#content div.box div.pagination-left{
+ float:left;
+}
+#content div.box div.pagination-right{
+ float:right;
+}
+
+#content div.box div.pagination-wh a,
+#content div.box div.pagination-wh span.pager_dotdot
+{
+ margin: 0 0 0 4px;
+ padding: 6px;
+ height: 1%;
+ float: left;
+ background: #ebebeb url("../images/pager.png") repeat-x;
+ border-top: 1px solid #dedede;
+ border-left: 1px solid #cfcfcf;
+ border-right: 1px solid #c4c4c4;
+ border-bottom: 1px solid #c4c4c4;
+ color: #4A4A4A;
+ font-weight: bold;
+}
+#content div.box div.pagination-wh span.pager_curpage
+{
+ margin: 0 0 0 4px;
+ padding: 6px;
+ height: 1%;
+ float: left;
+ background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
+ border-top: 1px solid #cccccc;
+ border-left: 1px solid #bebebe;
+ border-right: 1px solid #b1b1b1;
+ border-bottom: 1px solid #afafaf;
+ color: #515151;
+ font-weight: bold;
+}
+
+#content div.box div.pagination-wh a.disabled
+{
+ padding: 6px;
+ color: #B4B4B4;
+}
+
+
+#content div.box div.pagination-wh a:hover,
+#content div.box div.pagination-wh a:active
+{
+ background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
+ border-top: 1px solid #cccccc;
+ border-left: 1px solid #bebebe;
+ border-right: 1px solid #b1b1b1;
+ border-bottom: 1px solid #afafaf;
+ text-decoration: none;
+}
+
+
+/* -----------------------------------------------------------
+ content -> right -> traffic chart
+----------------------------------------------------------- */
+
+#content div.box div.traffic
+{
+ margin: 0;
+ padding: 0 20px 10px 20px;
+ clear: both;
+ overflow: hidden;
+}
+
+#content div.box div.traffic div.legend
+{
+ margin: 0 0 10px 0;
+ padding: 0 0 10px 0;
+ clear: both;
+ overflow: hidden;
+ border-bottom: 1px solid #dddddd;
+}
+
+#content div.box div.traffic div.legend h6
+{
+ margin: 0;
+ padding: 0;
+ float: left;
+ border: none;
+}
+
+#content div.box div.traffic div.legend ul
+{
+ margin: 0;
+ padding: 0;
+ float: right;
+}
+
+#content div.box div.traffic div.legend li
+{
+ margin: 0;
+ padding: 0 8px 0 4px;
+ list-style: none;
+ float: left;
+ font-size: 11px;
+}
+
+#content div.box div.traffic div.legend li.visits
+{
+ border-left: 12px solid #edc240;
+}
+
+#content div.box div.traffic div.legend li.pageviews
+{
+ border-left: 12px solid #afd8f8;
+}
+
+#content div.box div.traffic table
+{
+ width: auto;
+}
+
+#content div.box div.traffic table td
+{
+ padding: 2px 3px 3px 3px;
+ background: transparent;
+ border: none;
+}
+
+#content div.box div.traffic table td.legendLabel
+{
+ padding: 0 3px 2px 3px;
+}
+
+/* -----------------------------------------------------------
+ footer
+----------------------------------------------------------- */
+
+#footer
+{
+ margin: 0;
+ padding: 5px 0 5px 0;
+ clear: both;
+ overflow: hidden;
+ background: #2a2a2a;
+ text-align: right;
+}
+
+#footer p
+{
+ margin: 0 80px 0 80px;
+ padding: 10px 0 10px 0;
+ color: #ffffff;
+}
+
+/* -----------------------------------------------------------
+ login
+----------------------------------------------------------- */
+
+#login
+{
+ margin: 10% auto 0 auto;
+ padding: 0;
+ width: 420px;
+}
+
+/* -----------------------------------------------------------
+ login -> colors
+----------------------------------------------------------- */
+
+#login div.color
+{
+ margin: 10px auto 0 auto;
+ padding: 3px 3px 3px 0;
+ clear: both;
+ overflow: hidden;
+ background: #FFFFFF;
+}
+
+#login div.color a
+{
+ margin: 0 0 0 3px;
+ padding: 0;
+ width: 20px;
+ height: 20px;
+ display: block;
+ float: left;
+}
+
+/* -----------------------------------------------------------
+ login -> title
+----------------------------------------------------------- */
+
+#login div.title
+{
+ margin: 0 auto;
+ padding: 0;
+ width: 420px;
+ clear: both;
+ overflow: hidden;
+ position: relative;
+ background: #003367 url("../images/colors/blue/header_inner.png") repeat-x;
+}
+
+#login div.title h5
+{
+ margin: 10px;
+ padding: 0;
+ color: #ffffff;
+}
+
+/* -----------------------------------------------------------
+ login -> title / corners
+----------------------------------------------------------- */
+
+#login div.title div.corner
+{
+ height: 6px;
+ width: 6px;
+ position: absolute;
+ background: url("../images/colors/blue/login_corners.png") no-repeat;
+}
+
+#login div.title div.tl
+{
+ top: 0;
+ left: 0;
+ background-position: 0 0;
+}
+
+#login div.title div.tr
+{
+ top: 0;
+ right: 0;
+ background-position: -6px 0;
+}
+
+#login div.inner
+{
+ margin: 0 auto;
+ padding: 20px;
+ width: 380px;
+ background: #FFFFFF url("../images/login.png") no-repeat top left;
+ border-top: none;
+ border-bottom: none;
+}
+
+/* -----------------------------------------------------------
+ login -> form
+----------------------------------------------------------- */
+
+#login div.form
+{
+ margin: 0;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#login div.form div.fields
+{
+ margin: 0;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#login div.form div.fields div.field
+{
+ margin: 0;
+ padding: 0 0 10px 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#login div.form div.fields div.field span.error-message
+{
+ margin: 8px 0 0 0;
+ padding: 0;
+ height: 1%;
+ display: block;
+ color: #FF0000;
+}
+
+#login div.form div.fields div.field div.label
+{
+ margin: 2px 10px 0 0;
+ padding: 5px 0 0 5px;
+ width: 173px;
+ float: left;
+ text-align: right;
+}
+
+#login div.form div.fields div.field div.label label
+{
+ color: #000000;
+ font-weight: bold;
+}
+
+#login div.form div.fields div.field div.label span
+{
+ margin: 0;
+ padding: 2px 0 0 0;
+ height: 1%;
+ display: block;
+ color: #363636;
+}
+
+#login div.form div.fields div.field div.input
+{
+ margin: 0;
+ padding: 0;
+ float: left;
+}
+
+#login div.form div.fields div.field div.input input
+{
+ margin: 0;
+ padding: 7px 7px 6px 7px;
+ width: 176px;
+ background: #FFFFFF;
+ border-top: 1px solid #b3b3b3;
+ border-left: 1px solid #b3b3b3;
+ border-right: 1px solid #eaeaea;
+ border-bottom: 1px solid #eaeaea;
+ color: #000000;
+ font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
+ font-size: 11px;
+}
+
+#login div.form div.fields div.field div.input input.error
+{
+ background: #FBE3E4;
+ border-top: 1px solid #e1b2b3;
+ border-left: 1px solid #e1b2b3;
+ border-right: 1px solid #FBC2C4;
+ border-bottom: 1px solid #FBC2C4;
+}
+
+#login div.form div.fields div.field div.input input.success
+{
+ background: #E6EFC2;
+ border-top: 1px solid #cebb98;
+ border-left: 1px solid #cebb98;
+ border-right: 1px solid #c6d880;
+ border-bottom: 1px solid #c6d880;
+}
+
+#login div.form div.fields div.field div.input div.link
+{
+ margin: 6px 0 0 0;
+ padding: 0;
+ text-align: right;
+}
+
+#login div.form div.fields div.field div.checkbox
+{
+ margin: 0 0 0 184px;
+ padding: 0;
+}
+
+#login div.form div.fields div.field div.checkbox label
+{
+ color: #565656;
+ font-weight: bold;
+}
+
+#login div.form div.fields div.buttons
+{
+ margin: 0;
+ padding: 10px 0 0 0;
+ clear: both;
+ overflow: hidden;
+ border-top: 1px solid #DDDDDD;
+ text-align: right;
+}
+
+#login div.form div.fields div.buttons input
+{
+ margin: 0;
+ color: #000000;
+ font-size: 1.0em;
+ font-weight: bold;
+ font-family: Verdana, Helvetica, Sans-Serif;
+}
+
+#login div.form div.fields div.buttons input.ui-state-default
+{
+ margin: 0;
+ padding: 6px 12px 6px 12px;
+ background: #e5e3e3 url("../images/button.png") repeat-x;
+ border-top: 1px solid #DDDDDD;
+ border-left: 1px solid #c6c6c6;
+ border-right: 1px solid #DDDDDD;
+ border-bottom: 1px solid #c6c6c6;
+ color: #515151;
+}
+
+#login div.form div.fields div.buttons input.ui-state-hover
+{
+ margin: 0;
+ padding: 6px 12px 6px 12px;
+ background: #b4b4b4 url("../images/button_selected.png") repeat-x;
+ border-top: 1px solid #cccccc;
+ border-left: 1px solid #bebebe;
+ border-right: 1px solid #b1b1b1;
+ border-bottom: 1px solid #afafaf;
+ color: #515151;
+}
+
+/* -----------------------------------------------------------
+ login -> links
+----------------------------------------------------------- */
+
+#login div.form div.links
+{
+ margin: 10px 0 0 0;
+ padding: 0 0 2px 0;
+ clear: both;
+ overflow: hidden;
+}
+
+/* -----------------------------------------------------------
+ register
+----------------------------------------------------------- */
+
+#register
+{
+ margin: 10% auto 0 auto;
+ padding: 0;
+ width: 420px;
+}
+
+/* -----------------------------------------------------------
+ register -> colors
+----------------------------------------------------------- */
+
+#register div.color
+{
+ margin: 10px auto 0 auto;
+ padding: 3px 3px 3px 0;
+ clear: both;
+ overflow: hidden;
+ background: #FFFFFF;
+}
+
+#register div.color a
+{
+ margin: 0 0 0 3px;
+ padding: 0;
+ width: 20px;
+ height: 20px;
+ display: block;
+ float: left;
+}
+
+/* -----------------------------------------------------------
+ register -> title
+----------------------------------------------------------- */
+
+#register div.title
+{
+ margin: 0 auto;
+ padding: 0;
+ width: 420px;
+ clear: both;
+ overflow: hidden;
+ position: relative;
+ background: #003367 url("../images/colors/blue/header_inner.png") repeat-x;
+}
+
+#register div.title h5
+{
+ margin: 10px;
+ padding: 0;
+ color: #ffffff;
+}
+
+/* -----------------------------------------------------------
+ register -> inner
+----------------------------------------------------------- */
+#register div.title div.corner
+{
+ height: 6px;
+ width: 6px;
+ position: absolute;
+ background: url("../images/colors/blue/login_corners.png") no-repeat;
+}
+
+#register div.title div.tl
+{
+ top: 0;
+ left: 0;
+ background-position: 0 0;
+}
+
+#register div.title div.tr
+{
+ top: 0;
+ right: 0;
+ background-position: -6px 0;
+
+}
+#register div.inner
+{
+ margin: 0 auto;
+ padding: 20px;
+ width: 380px;
+ background: #FFFFFF;
+ border-top: none;
+ border-bottom: none;
+}
+
+/* -----------------------------------------------------------
+ register -> form
+----------------------------------------------------------- */
+
+#register div.form
+{
+ margin: 0;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#register div.form div.fields
+{
+ margin: 0;
+ padding: 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#register div.form div.fields div.field
+{
+ margin: 0;
+ padding: 0 0 10px 0;
+ clear: both;
+ overflow: hidden;
+}
+
+#register div.form div.fields div.field span.error-message
+{
+ margin: 8px 0 0 0;
+ padding: 0;
+ height: 1%;
+ display: block;
+ color: #FF0000;
+}
+
+#register div.form div.fields div.field div.label
+{
+ margin: 2px 10px 0 0;
+ padding: 5px 0 0 5px;
+ width: 82px;
+ float: left;
+ text-align: right;
+}
+
+#register div.form div.fields div.field div.label label
+{
+ color: #000000;
+ font-weight: bold;
+}
+
+#register div.form div.fields div.field div.label span
+{
+ margin: 0;
+ padding: 2px 0 0 0;
+ height: 1%;
+ display: block;
+ color: #363636;
+}
+
+#register div.form div.fields div.field div.input
+{
+ margin: 0;
+ padding: 0;
+ float: left;
+}
+
+#register div.form div.fields div.field div.input input
+{
+ margin: 0;
+ padding: 7px 7px 6px 7px;
+ width: 266px;
+ background: #FFFFFF;
+ border-top: 1px solid #b3b3b3;
+ border-left: 1px solid #b3b3b3;
+ border-right: 1px solid #eaeaea;
+ border-bottom: 1px solid #eaeaea;
+ color: #000000;
+ font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
+ font-size: 11px;
+}
+
+#register div.form div.fields div.field div.input input.error
+{
+ background: #FBE3E4;
+ border-top: 1px solid #e1b2b3;
+ border-left: 1px solid #e1b2b3;
+ border-right: 1px solid #FBC2C4;
+ border-bottom: 1px solid #FBC2C4;
+}
+
+#register div.form div.fields div.field div.input input.success
+{
+ background: #E6EFC2;
+ border-top: 1px solid #cebb98;
+ border-left: 1px solid #cebb98;
+ border-right: 1px solid #c6d880;
+ border-bottom: 1px solid #c6d880;
+}
+
+#register div.form div.fields div.field div.input div.link
+{
+ margin: 6px 0 0 0;
+ padding: 0;
+ text-align: right;
+}
+
+#register div.form div.fields div.field div.checkbox
+{
+ margin: 0 0 0 184px;
+ padding: 0;
+}
+
+#register div.form div.fields div.field div.checkbox label
+{
+ color: #565656;
+ font-weight: bold;
+}
+
+#register div.form div.fields div.buttons
+{
+ margin: 0;
+ padding: 10px 0 0 97px;
+ clear: both;
+ overflow: hidden;
+ border-top: 1px solid #DDDDDD;
+ text-align: left;
+}
+
+#register div.form div.fields div.buttons input
+{
+ margin: 0;
+ color: #000000;
+ font-size: 1.0em;
+ font-weight: bold;
+ font-family: Verdana, Helvetica, Sans-Serif;
+}
+
+#register div.form div.fields div.buttons input.ui-state-default
+{
+ margin: 0;
+ padding: 6px 12px 6px 12px;
+ background: #e5e3e3 url("../images/button.png") repeat-x;
+ border-top: 1px solid #DDDDDD;
+ border-left: 1px solid #c6c6c6;
+ border-right: 1px solid #DDDDDD;
+ border-bottom: 1px solid #c6c6c6;
+ color: #515151;
+}
+#register div.form div.fields div.buttons div.highlight input.ui-state-default
+{
+ background:url("../images/colors/blue/button_highlight.png") repeat-x scroll 0 0 #4E85BB;
+ border-color:#5C91A4 #2B7089 #1A6480 #2A6F89;
+ border-style:solid;
+ border-width:1px;
+ color:#FFFFFF;
+}
+
+
+
+#register div.form div.fields div.buttons input.ui-state-hover
+{
+ margin: 0;
+ padding: 6px 12px 6px 12px;
+ background: #b4b4b4 url("../images/button_selected.png") repeat-x;
+ border-top: 1px solid #cccccc;
+ border-left: 1px solid #bebebe;
+ border-right: 1px solid #b1b1b1;
+ border-bottom: 1px solid #afafaf;
+ color: #515151;
+}
+
+
+/* -----------------------------------------------------------
+ CHANGESETS
+----------------------------------------------------------- */
+#changeset_content {
+ border:1px solid #CCCCCC;
+ padding:5px;
+}
+
+#changeset_content .container .wrapper {
+ width: 600px;
+}
+
+#changeset_content .container {
+ height: 120px;
+}
+
+#changeset_content .container .left {
+ float: left;
+ width: 70%;
+ padding-left: 5px;
+}
+
+#changeset_content .container .right {
+ float: right;
+ width: 25%;
+ text-align: right;
+}
+
+#changeset_content .container .left .date {
+ font-weight: bold;
+}
+
+#changeset_content .container .left .author {
+
+}
+
+#changeset_content .container .left .message {
+ font-style: italic;
+ color: #556CB5;
+}
+
+.cs_files {
+
+}
+
+.cs_files .cs_added {
+ background: url("/images/icons/page_white_add.png") no-repeat scroll 3px;
+ /*background-color:#BBFFBB;*/
+ height: 16px;
+ padding-left: 20px;
+ margin-top: 7px;
+ text-align: left;
+}
+
+.cs_files .cs_changed {
+ background: url("/images/icons/page_white_edit.png") no-repeat scroll
+ 3px;
+ /*background-color: #FFDD88;*/
+ height: 16px;
+ padding-left: 20px;
+ margin-top: 7px;
+ text-align: left;
+}
+
+.cs_files .cs_removed {
+ background: url("/images/icons/page_white_delete.png") no-repeat scroll
+ 3px;
+ /*background-color: #FF8888;*/
+ height: 16px;
+ padding-left: 20px;
+ margin-top: 7px;
+ text-align: left;
+}
+
+
+
+/* -----------------------------------------------------------
+ CHANGESETS - CANVAS
+----------------------------------------------------------- */
+
+#graph {
+ overflow: hidden;
+}
+
+#graph_nodes {
+ width: 160px;
+ float: left;
+ margin-left:-50px;
+ margin-top: 5px;
+}
+
+#graph_content {
+ width: 800px;
+ float: left;
+}
+
+#graph_content .container_header {
+ border: 1px solid #CCCCCC;
+ padding:10px;
+}
+
+#graph_content .container .wrapper {
+ width: 600px;
+}
+
+#graph_content .container {
+ border-bottom: 1px solid #CCCCCC;
+ border-left: 1px solid #CCCCCC;
+ border-right: 1px solid #CCCCCC;
+ min-height: 80px;
+ overflow: hidden;
+}
+
+#graph_content .container .left {
+ float: left;
+ width: 70%;
+ padding-left: 5px;
+}
+
+#graph_content .container .right {
+ float: right;
+ width: 25%;
+ text-align: right;
+}
+
+#graph_content .container .left .date {
+ font-weight: bold;
+}
+
+#graph_content .container .left .author {
+
+}
+
+#graph_content .container .left .message {
+ font-size: 80%;
+}
+
+.right div {
+ clear: both;
+}
+
+.right .changes .added,.changed,.removed {
+ border: 1px solid #DDDDDD;
+ display: block;
+ float: right;
+ font-size: 0.75em;
+ text-align: center;
+ min-width: 15px;
+}
+
+.right .changes .added {
+ background: #BBFFBB;
+}
+
+.right .changes .changed {
+ background: #FFDD88;
+}
+
+.right .changes .removed {
+ background: #FF8888;
+}
+
+.right .merge {
+ vertical-align: top;
+ font-size: 60%;
+ font-weight: bold;
+}
+
+.right .merge img {
+ vertical-align: bottom;
+}
+
+.right .parent {
+ font-size: 90%;
+ font-family: monospace;
+}
+
+
+
+/* -----------------------------------------------------------
+ FILE BROWSER
+----------------------------------------------------------- */
+div.browserblock {
+ overflow: hidden;
+ padding: 0px;
+ border: 1px solid #ccc;
+ background: #f8f8f8;
+ font-size: 100%;
+ line-height: 100%;
+ /* new */
+ line-height: 125%;
+}
+
+div.browserblock .browser-header {
+ border-bottom: 1px solid #CCCCCC;
+ background: #FFFFFF;
+ color: blue;
+ padding: 10px 0 10px 0;
+}
+
+div.browserblock .browser-header span {
+ margin-left: 25px;
+ font-weight: bold;
+}
+
+div.browserblock .browser-body {
+ background: #EEEEEE;
+}
+
+table.code-browser {
+ border-collapse: collapse;
+ width: 100%;
+}
+
+table.code-browser tr {
+ margin: 3px;
+}
+
+table.code-browser thead th {
+ background-color: #EEEEEE;
+ height: 20px;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-align: center;
+ text-align: left;
+ padding-left: 10px;
+}
+
+table.code-browser tbody tr {
+
+}
+
+table.code-browser tbody td {
+ padding-left: 10px;
+ height: 20px;
+}
+table.code-browser .browser-file {
+ background: url("/images/icons/document_16.png") no-repeat scroll 3px;
+ height: 16px;
+ padding-left: 20px;
+ text-align: left;
+}
+
+table.code-browser .browser-dir {
+ background: url("/images/icons/folder_16.png") no-repeat scroll 3px;
+ height: 16px;
+ padding-left: 20px;
+ text-align: left;
+}
+
+
+/* -----------------------------------------------------------
+ INFOBOX
+----------------------------------------------------------- */
+.info_box *{
+ background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB;
+ border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF;
+ border-style:solid;
+ border-width:1px;
+ color:#4A4A4A;
+ display:block;
+ font-weight:bold;
+ height:1%;
+ padding:4px 6px;
+ display: inline;
+}
+.info_box span{
+ margin-left:3px;
+ margin-righ:3px;
+}
+.info_box input {
+ padding:3px 6px;
+}
+
+/* -----------------------------------------------------------
+ TOOLTIP
+----------------------------------------------------------- */
+.yui-overlay,.yui-panel-container {
+ visibility: hidden;
+ position: absolute;
+ z-index: 2;
+}
+
+.yui-tt {
+ visibility: hidden;
+ position: absolute;
+ color: #666666;
+ background-color: #FFFFFF;
+ font-family: arial, helvetica, verdana, sans-serif;
+ padding: 8px;
+ border: 2px solid #556CB5;
+ font: 100% sans-serif;
+ width: auto;
+ opacity: 1.0;
+}
+
+.yui-tt-shadow {
+ display: none;
+}
+
+/* -----------------------------------------------------------
+ AUTOCOMPLETE
+----------------------------------------------------------- */
+
+.ac{
+ vertical-align: top;
+
+}
+.ac .match {
+ font-weight:bold;
+}
+
+.ac .yui-ac {
+ position: relative;
+ font-family: arial;
+ font-size: 100%;
+}
+
+.ac .perm_ac{
+ width:15em;
+}
+/* styles for input field */
+.ac .yui-ac-input {
+ width: 100%;
+}
+
+/* styles for results container */
+.ac .yui-ac-container {
+ position: absolute;
+ top: 1.6em;
+ width: 100%;
+}
+
+/* styles for header/body/footer wrapper within container */
+.ac .yui-ac-content {
+ position: absolute;
+ width: 100%;
+ border: 1px solid #808080;
+ background: #fff;
+ overflow: hidden;
+ z-index: 9050;
+}
+
+/* styles for container shadow */
+.ac .yui-ac-shadow {
+ position: absolute;
+ margin: .3em;
+ width: 100%;
+ background: #000;
+ -moz-opacity: 0.10;
+ opacity: .10;
+ filter: alpha(opacity = 10);
+ z-index: 9049;
+}
+
+/* styles for results list */
+.ac .yui-ac-content ul {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+}
+
+/* styles for result item */
+.ac .yui-ac-content li {
+ margin: 0;
+ padding: 2px 5px;
+ cursor: default;
+ white-space: nowrap;
+}
+
+/* styles for prehighlighted result item */
+.ac .yui-ac-content li.yui-ac-prehighlight {
+ background: #B3D4FF;
+}
+
+/* styles for highlighted result item */
+.ac .yui-ac-content li.yui-ac-highlight {
+ background: #556CB5;
+ color: #FFF;
+}
+
+
+/* -----------------------------------------------------------
+ ACTION ICONS
+----------------------------------------------------------- */
+.add_icon {
+ background: url("/images/icons/add.png") no-repeat scroll 3px ;
+ height: 16px;
+ padding-left: 20px;
+ padding-top: 1px;
+ text-align: left;
+}
+
+.edit_icon {
+ background: url("/images/icons/folder_edit.png") no-repeat scroll 3px;
+ height: 16px;
+ padding-left: 20px;
+ padding-top: 1px;
+ text-align: left;
+}
+
+.delete_icon {
+ background: url("/images/icons/delete.png") no-repeat scroll 3px;
+ height: 16px;
+ padding-left: 20px;
+ padding-top: 1px;
+ text-align: left;
+}
+
+.rss_icon {
+ background: url("/images/icons/rss_16.png") no-repeat scroll 3px;
+ height: 16px;
+ padding-left: 20px;
+ padding-top: 1px;
+ text-align: left;
+}
+
+.atom_icon {
+ background: url("/images/icons/atom.png") no-repeat scroll 3px;
+ height: 16px;
+ padding-left: 20px;
+ padding-top: 1px;
+ text-align: left;
+}
+
+.archive_icon {
+ background: url("/images/icons/compress.png") no-repeat scroll 3px;
+ height: 16px;
+ padding-left: 20px;
+ text-align: left;
+ padding-top: 1px;
+}
+
+
+
+
+.action_button {
+ border: 0px;
+ display: block;
+}
+
+.action_button:hover {
+ border: 0px;
+ font-style: italic;
+ cursor: pointer;
+}
+
+/* -----------------------------------------------------------
+ BREADCRUMBS
+----------------------------------------------------------- */
+
+.breadcrumbs{
+ border:medium none;
+ color:#FFFFFF;
+ float:left;
+ margin:0;
+ padding:11px 0 11px 10px;
+ text-transform:uppercase;
+ font-weight: bold;
+ font-size: 14px;
+}
+.breadcrumbs a{
+ color: #FFFFFF;
+}
+
+
+/* -----------------------------------------------------------
+ FLASH MSG
+----------------------------------------------------------- */
+.flash_msg ul {
+ margin: 0;
+ padding: 0px 0px 10px 0px;
+}
+
+.error_msg {
+ background-color: #FFCFCF;
+ background-image: url("/images/icons/error_msg.png");
+ border: 1px solid #FF9595;
+ color: #CC3300;
+}
+
+.warning_msg {
+ background-color: #FFFBCC;
+ background-image: url("/images/icons/warning_msg.png");
+ border: 1px solid #FFF35E;
+ color: #C69E00;
+}
+
+.success_msg {
+ background-color: #D5FFCF;
+ background-image: url("/images/icons/success_msg.png");
+ border: 1px solid #97FF88;
+ color: #009900;
+}
+
+.notice_msg {
+ background-color: #DCE3FF;
+ background-image: url("/images/icons/notice_msg.png");
+ border: 1px solid #93A8FF;
+ color: #556CB5;
+}
+
+.success_msg,.error_msg,.notice_msg,.warning_msg {
+ background-position: 10px center;
+ background-repeat: no-repeat;
+ font-size: 12px;
+ font-weight: bold;
+ min-height: 14px;
+ line-height: 14px;
+ margin-bottom: 0px;
+ margin-top: 0px;
+ padding: 6px 10px 6px 40px;
+ display: block;
+ overflow: auto;
+}
+
+#msg_close {
+ background: transparent url("icons/cross_grey_small.png") no-repeat
+ scroll 0 0;
+ cursor: pointer;
+ height: 16px;
+ position: absolute;
+ right: 5px;
+ top: 5px;
+ width: 16px;
+}
+/* -----------------------------------------------------------
+ YUI FLOT
+----------------------------------------------------------- */
+
+div#commit_history{
+ float: left;
+}
+div#legend_data{
+ float:left;
+
+}
+div#legend_container {
+ float: left;
+}
+
+div#legend_container table,div#legend_choices table{
+ width:auto !important;
+}
+
+div#legend_container table td{
+ border: none !important;
+ padding: 2px !important;
+}
+
+div#legend_choices table td{
+ border: none !important;
+ padding: 0px !important;
+}
+
+div#legend_choices{
+ float:left;
+}
+
+/* -----------------------------------------------------------
+ PERMISSIONS TABLE
+----------------------------------------------------------- */
+table#permissions_manage{
+ width: 0 !important;
+
+}
+table#permissions_manage span.private_repo_msg{
+ style="font-size: 0.8em"
+}
+table#permissions_manage tr#add_perm_input td{
+ vertical-align:middle;
+
+}
+
+
+/* -----------------------------------------------------------
+ jquery ui
+----------------------------------------------------------- */
+
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+/* -----------------------------------------------------------
+ jquery ui -> icons
+----------------------------------------------------------- */
+
+.ui-icon { width: 16px; height: 16px; background-image: url(../images/ui/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(../images/ui/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(../images/ui/ui-icons_222222_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(../images/ui/ui-icons_ef8c08_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon { background-image: url(../images/ui/ui-icons_ef8c08_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(../images/ui/ui-icons_ef8c08_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(../images/ui/ui-icons_228ef1_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(../images/ui/ui-icons_ffd27a_256x240.png); }
+
+/* -----------------------------------------------------------
+ jquery ui -> icon 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-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+/* -----------------------------------------------------------
+ jquery ui -> tabs
+----------------------------------------------------------- */
+.ui-tabs .ui-tabs-hide { display: none; }
+
+/* -----------------------------------------------------------
+ jquery ui -> datepicker
+----------------------------------------------------------- */
+.ui-datepicker { width: 17em; padding: .2em .2em 0; background: #FFFFFF; border: 1px solid #000000; border-top: none; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; background: #F6F6F6; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 1px; 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: 0; }
+.ui-datepicker .ui-datepicker-next { right: 0; }
+.ui-datepicker .ui-datepicker-prev-hover { left: 0; }
+.ui-datepicker .ui-datepicker-next-hover { right: 0; }
+.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 { margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; border: 0; }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: 3px; text-align: center; text-decoration: none; }
+.ui-datepicker td span, .ui-datepicker td a:hover { background: #376ea6; color: #ffffff; }
+.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; }
+.ui-datepicker td span, .ui-datepicker td.ui-datepicker-today a { background: #DDDDDD; color: #585858; }
+.ui-datepicker td span, .ui-datepicker td.ui-datepicker-current-day a { background: #376ea6; color: #ffffff; }
+
+/* -----------------------------------------------------------
+ jquery ui -> datepicker / multiple calenders
+----------------------------------------------------------- */
+.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%; }
+
+/* -----------------------------------------------------------
+ jquery ui -> datepicker / 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; }
+
+/* -----------------------------------------------------------
+ jquery ui -> select styling
+----------------------------------------------------------- */
+
+.ui-selectmenu
+{
+ display: block;
+ position: relative;
+ overflow: hidden;
+ background: #ffffff;
+ border-top: 1px solid #b3b3b3;
+ border-left: 1px solid #b3b3b3;
+ border-right: 1px solid #eaeaea;
+ border-bottom: 1px solid #eaeaea;
+ text-align: left;
+ text-decoration: none;
+}
+
+.ui-selectmenu-icon { position:absolute; right:6px; margin-top:-8px; top: 50%; }
+.ui-selectmenu-menu { padding:0; margin:0; list-style:none; position:absolute; top: 0; visibility: hidden; overflow: auto; }
+.ui-selectmenu-open { background: #ffffff; border: 1px solid #666666; border-top: none; visibility: visible; }
+.ui-selectmenu-menu-popup { margin-top: -1px; }
+.ui-selectmenu-menu-dropdown { }
+.ui-selectmenu-menu li { padding:0; margin:0; display: block; border-top: 1px dotted transparent; border-bottom: 1px dotted transparent; border-right-width: 0 !important; border-left-width: 0 !important; }
+.ui-selectmenu-menu li a,.ui-selectmenu-status {line-height: 1.4em; display:block; padding: 5px 0 5px 8px; outline:none; text-decoration:none; color: #000000; }
+.ui-selectmenu-menu li.ui-selectmenu-hasIcon a,
+.ui-selectmenu-hasIcon .ui-selectmenu-status { margin-left: 5px; padding-left: 20px; position: relative; }
+.ui-selectmenu-menu li .ui-icon, .ui-selectmenu-status .ui-icon { position: absolute; top: 1em; margin-top: -8px; left: 0; }
+.ui-selectmenu-status { line-height: 1.4em; }
+.ui-selectmenu-open li.ui-selectmenu-item-focus { background: #376ea6; }
+.ui-selectmenu-open li.ui-selectmenu-item-focus a { color: #ffffff; }
+.ui-selectmenu-open li.ui-selectmenu-item-selected { background: #dfdfdf; }
+.ui-selectmenu-open li.ui-selectmenu-item-selected a { color: #000000; }
+.ui-selectmenu-menu li span,.ui-selectmenu-status span { display:block; margin-bottom: .2em; }
+.ui-selectmenu-menu .ui-selectmenu-group .ui-selectmenu-group-label { line-height: 1.4em; display:block; padding:.6em .5em 0; }
+.ui-selectmenu-menu .ui-selectmenu-group ul { margin: 0; padding: 0; } \ No newline at end of file
diff --git a/pylons_app/public/css/style_full.css b/pylons_app/public/css/style_full.css
new file mode 100644
index 00000000..6f7c852f
--- /dev/null
+++ b/pylons_app/public/css/style_full.css
@@ -0,0 +1,36 @@
+/* -----------------------------------------------------------
+ content
+----------------------------------------------------------- */
+
+#content
+{
+ margin: 10px 60px 0 60px;
+ padding: 0;
+ min-height: 100%;
+ clear: both;
+ overflow: hidden;
+ background: transparent;
+}
+
+/* -----------------------------------------------------------
+ content -> right -> forms -> labels
+----------------------------------------------------------- */
+
+#content div.box div.form div.fields div.field div.label
+{
+ left: 80px;
+ margin: 0;
+ padding: 8px 0 0 5px;
+ width: auto;
+ position: absolute;
+}
+
+#content div.box-left div.form div.fields div.field div.label,
+#content div.box-right div.form div.fields div.field div.label
+{
+ left: 0;
+ margin: 0;
+ padding: 0 0 8px 0;
+ width: auto;
+ position: relative;
+} \ No newline at end of file
diff --git a/pylons_app/public/images/background.png b/pylons_app/public/images/background.png
new file mode 100644
index 00000000..1ece980b
--- /dev/null
+++ b/pylons_app/public/images/background.png
Binary files differ
diff --git a/pylons_app/public/images/button.png b/pylons_app/public/images/button.png
new file mode 100644
index 00000000..a1901e1e
--- /dev/null
+++ b/pylons_app/public/images/button.png
Binary files differ
diff --git a/pylons_app/public/images/button_browse.png b/pylons_app/public/images/button_browse.png
new file mode 100644
index 00000000..6943f5e3
--- /dev/null
+++ b/pylons_app/public/images/button_browse.png
Binary files differ
diff --git a/pylons_app/public/images/button_browse_selected.png b/pylons_app/public/images/button_browse_selected.png
new file mode 100644
index 00000000..f900cfbe
--- /dev/null
+++ b/pylons_app/public/images/button_browse_selected.png
Binary files differ
diff --git a/pylons_app/public/images/button_selected.png b/pylons_app/public/images/button_selected.png
new file mode 100644
index 00000000..61becc3e
--- /dev/null
+++ b/pylons_app/public/images/button_selected.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/button_highlight.png b/pylons_app/public/images/colors/blue/button_highlight.png
new file mode 100644
index 00000000..ef76eb9a
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/button_highlight.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/button_highlight_selected.png b/pylons_app/public/images/colors/blue/button_highlight_selected.png
new file mode 100644
index 00000000..ffd3a38e
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/button_highlight_selected.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/button_home.png b/pylons_app/public/images/colors/blue/button_home.png
new file mode 100644
index 00000000..81bf165f
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/button_home.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/header_inner.png b/pylons_app/public/images/colors/blue/header_inner.png
new file mode 100644
index 00000000..be6eb56b
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/header_inner.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/header_inner_corners.png b/pylons_app/public/images/colors/blue/header_inner_corners.png
new file mode 100644
index 00000000..2f7e848a
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/header_inner_corners.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/index.sof b/pylons_app/public/images/colors/blue/index.sof
new file mode 100644
index 00000000..9d5e7029
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/index.sof
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/login_corners.png b/pylons_app/public/images/colors/blue/login_corners.png
new file mode 100644
index 00000000..4b3bb263
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/login_corners.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/menu_arrow.png b/pylons_app/public/images/colors/blue/menu_arrow.png
new file mode 100644
index 00000000..1c762247
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/menu_arrow.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/menu_border.png b/pylons_app/public/images/colors/blue/menu_border.png
new file mode 100644
index 00000000..4c31e315
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/menu_border.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/menu_l_selected.png b/pylons_app/public/images/colors/blue/menu_l_selected.png
new file mode 100644
index 00000000..e3d14a01
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/menu_l_selected.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/menu_r_selected.png b/pylons_app/public/images/colors/blue/menu_r_selected.png
new file mode 100644
index 00000000..e661f4c5
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/menu_r_selected.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/menu_selected.png b/pylons_app/public/images/colors/blue/menu_selected.png
new file mode 100644
index 00000000..ad63d42a
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/menu_selected.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/quick_l.png b/pylons_app/public/images/colors/blue/quick_l.png
new file mode 100644
index 00000000..4f4242e6
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/quick_l.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/quick_l_selected.png b/pylons_app/public/images/colors/blue/quick_l_selected.png
new file mode 100644
index 00000000..f970fa27
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/quick_l_selected.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/quick_r.png b/pylons_app/public/images/colors/blue/quick_r.png
new file mode 100644
index 00000000..3937241c
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/quick_r.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/quick_r_selected.png b/pylons_app/public/images/colors/blue/quick_r_selected.png
new file mode 100644
index 00000000..a3a8681f
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/quick_r_selected.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/title.png b/pylons_app/public/images/colors/blue/title.png
new file mode 100644
index 00000000..94d4b242
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/title.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/title_link.png b/pylons_app/public/images/colors/blue/title_link.png
new file mode 100644
index 00000000..fc2ad037
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/title_link.png
Binary files differ
diff --git a/pylons_app/public/images/colors/blue/title_tab_selected.png b/pylons_app/public/images/colors/blue/title_tab_selected.png
new file mode 100644
index 00000000..0213bc00
--- /dev/null
+++ b/pylons_app/public/images/colors/blue/title_tab_selected.png
Binary files differ
diff --git a/pylons_app/public/images/content.png b/pylons_app/public/images/content.png
new file mode 100644
index 00000000..65f412c7
--- /dev/null
+++ b/pylons_app/public/images/content.png
Binary files differ
diff --git a/pylons_app/public/images/header_background.png b/pylons_app/public/images/header_background.png
new file mode 100644
index 00000000..afb1380b
--- /dev/null
+++ b/pylons_app/public/images/header_background.png
Binary files differ
diff --git a/pylons_app/public/images/icons/cross.png b/pylons_app/public/images/icons/cross.png
index 1514d51a..11a18451 100644
--- a/pylons_app/public/images/icons/cross.png
+++ b/pylons_app/public/images/icons/cross.png
Binary files differ
diff --git a/pylons_app/public/images/icons/index.sof b/pylons_app/public/images/icons/index.sof
new file mode 100644
index 00000000..6338da74
--- /dev/null
+++ b/pylons_app/public/images/icons/index.sof
Binary files differ
diff --git a/pylons_app/public/images/icons/success.png b/pylons_app/public/images/icons/success.png
new file mode 100644
index 00000000..c9fc7ba4
--- /dev/null
+++ b/pylons_app/public/images/icons/success.png
Binary files differ
diff --git a/pylons_app/public/images/icons/warning.png b/pylons_app/public/images/icons/warning.png
new file mode 100644
index 00000000..1421812e
--- /dev/null
+++ b/pylons_app/public/images/icons/warning.png
Binary files differ
diff --git a/pylons_app/public/images/login.png b/pylons_app/public/images/login.png
new file mode 100644
index 00000000..cf29049e
--- /dev/null
+++ b/pylons_app/public/images/login.png
Binary files differ
diff --git a/pylons_app/public/images/menu.png b/pylons_app/public/images/menu.png
new file mode 100644
index 00000000..f61b1d3a
--- /dev/null
+++ b/pylons_app/public/images/menu.png
Binary files differ
diff --git a/pylons_app/public/images/menu_l.png b/pylons_app/public/images/menu_l.png
new file mode 100644
index 00000000..a45acbe6
--- /dev/null
+++ b/pylons_app/public/images/menu_l.png
Binary files differ
diff --git a/pylons_app/public/images/menu_minus.png b/pylons_app/public/images/menu_minus.png
new file mode 100644
index 00000000..c31dcfb3
--- /dev/null
+++ b/pylons_app/public/images/menu_minus.png
Binary files differ
diff --git a/pylons_app/public/images/menu_plus.png b/pylons_app/public/images/menu_plus.png
new file mode 100644
index 00000000..1ae9adb5
--- /dev/null
+++ b/pylons_app/public/images/menu_plus.png
Binary files differ
diff --git a/pylons_app/public/images/menu_r.png b/pylons_app/public/images/menu_r.png
new file mode 100644
index 00000000..3c359458
--- /dev/null
+++ b/pylons_app/public/images/menu_r.png
Binary files differ
diff --git a/pylons_app/public/images/pager.png b/pylons_app/public/images/pager.png
new file mode 100644
index 00000000..590e5d40
--- /dev/null
+++ b/pylons_app/public/images/pager.png
Binary files differ
diff --git a/pylons_app/public/images/pager_selected.png b/pylons_app/public/images/pager_selected.png
new file mode 100644
index 00000000..61becc3e
--- /dev/null
+++ b/pylons_app/public/images/pager_selected.png
Binary files differ
diff --git a/pylons_app/public/js/excanvas.min.js b/pylons_app/public/js/excanvas.min.js
new file mode 100644
index 00000000..832bbd15
--- /dev/null
+++ b/pylons_app/public/js/excanvas.min.js
@@ -0,0 +1 @@
+if(!document.createElement("canvas").getContext){(function(){var R=Math;var S=R.round;var O=R.sin;var a=R.cos;var J=R.abs;var Y=R.sqrt;var A=10;var K=A/2;function G(){return this.context_||(this.context_=new M(this))}var Q=Array.prototype.slice;function b(c,d,e){var Z=Q.call(arguments,2);return function(){return c.apply(d,Z.concat(Q.call(arguments)))}}var H={init:function(Z){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var c=Z||document;c.createElement("canvas");c.attachEvent("onreadystatechange",b(this.init_,this,c))}},init_:function(e){if(!e.namespaces.g_vml_){e.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML")}if(!e.namespaces.g_o_){e.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML")}if(!e.styleSheets.ex_canvas_){var d=e.createStyleSheet();d.owningElement.id="ex_canvas_";d.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}g_o_\\:*{behavior:url(#default#VML)}"}var c=e.getElementsByTagName("canvas");for(var Z=0;Z<c.length;Z++){this.initElement(c[Z])}},initElement:function(c){if(!c.getContext){c.getContext=G;c.innerHTML="";c.attachEvent("onpropertychange",X);c.attachEvent("onresize",B);var Z=c.attributes;if(Z.width&&Z.width.specified){c.style.width=Z.width.nodeValue+"px"}else{c.width=c.clientWidth}if(Z.height&&Z.height.specified){c.style.height=Z.height.nodeValue+"px"}else{c.height=c.clientHeight}}return c}};function X(c){var Z=c.srcElement;switch(c.propertyName){case"width":Z.style.width=Z.attributes.width.nodeValue+"px";Z.getContext().clearRect();break;case"height":Z.style.height=Z.attributes.height.nodeValue+"px";Z.getContext().clearRect();break}}function B(c){var Z=c.srcElement;if(Z.firstChild){Z.firstChild.style.width=Z.clientWidth+"px";Z.firstChild.style.height=Z.clientHeight+"px"}}H.init();var E=[];for(var V=0;V<16;V++){for(var U=0;U<16;U++){E[V*16+U]=V.toString(16)+U.toString(16)}}function N(){return[[1,0,0],[0,1,0],[0,0,1]]}function D(e,d){var c=N();for(var Z=0;Z<3;Z++){for(var h=0;h<3;h++){var f=0;for(var g=0;g<3;g++){f+=e[Z][g]*d[g][h]}c[Z][h]=f}}return c}function T(c,Z){Z.fillStyle=c.fillStyle;Z.lineCap=c.lineCap;Z.lineJoin=c.lineJoin;Z.lineWidth=c.lineWidth;Z.miterLimit=c.miterLimit;Z.shadowBlur=c.shadowBlur;Z.shadowColor=c.shadowColor;Z.shadowOffsetX=c.shadowOffsetX;Z.shadowOffsetY=c.shadowOffsetY;Z.strokeStyle=c.strokeStyle;Z.globalAlpha=c.globalAlpha;Z.arcScaleX_=c.arcScaleX_;Z.arcScaleY_=c.arcScaleY_;Z.lineScale_=c.lineScale_}function C(c){var f,e=1;c=String(c);if(c.substring(0,3)=="rgb"){var h=c.indexOf("(",3);var Z=c.indexOf(")",h+1);var g=c.substring(h+1,Z).split(",");f="#";for(var d=0;d<3;d++){f+=E[Number(g[d])]}if(g.length==4&&c.substr(3,1)=="a"){e=g[3]}}else{f=c}return{color:f,alpha:e}}function P(Z){switch(Z){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function M(c){this.m_=N();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=A*1;this.globalAlpha=1;this.canvas=c;var Z=c.ownerDocument.createElement("div");Z.style.width=c.clientWidth+"px";Z.style.height=c.clientHeight+"px";Z.style.overflow="hidden";Z.style.position="absolute";c.appendChild(Z);this.element_=Z;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var I=M.prototype;I.clearRect=function(){this.element_.innerHTML=""};I.beginPath=function(){this.currentPath_=[]};I.moveTo=function(c,Z){var d=this.getCoords_(c,Z);this.currentPath_.push({type:"moveTo",x:d.x,y:d.y});this.currentX_=d.x;this.currentY_=d.y};I.lineTo=function(c,Z){var d=this.getCoords_(c,Z);this.currentPath_.push({type:"lineTo",x:d.x,y:d.y});this.currentX_=d.x;this.currentY_=d.y};I.bezierCurveTo=function(d,c,j,i,h,f){var Z=this.getCoords_(h,f);var g=this.getCoords_(d,c);var e=this.getCoords_(j,i);L(this,g,e,Z)};function L(Z,e,d,c){Z.currentPath_.push({type:"bezierCurveTo",cp1x:e.x,cp1y:e.y,cp2x:d.x,cp2y:d.y,x:c.x,y:c.y});Z.currentX_=c.x;Z.currentY_=c.y}I.quadraticCurveTo=function(h,d,c,Z){var g=this.getCoords_(h,d);var f=this.getCoords_(c,Z);var i={x:this.currentX_+2/3*(g.x-this.currentX_),y:this.currentY_+2/3*(g.y-this.currentY_)};var e={x:i.x+(f.x-this.currentX_)/3,y:i.y+(f.y-this.currentY_)/3};L(this,i,e,f)};I.arc=function(k,i,j,f,c,d){j*=A;var o=d?"at":"wa";var l=k+a(f)*j-K;var n=i+O(f)*j-K;var Z=k+a(c)*j-K;var m=i+O(c)*j-K;if(l==Z&&!d){l+=0.125}var e=this.getCoords_(k,i);var h=this.getCoords_(l,n);var g=this.getCoords_(Z,m);this.currentPath_.push({type:o,x:e.x,y:e.y,radius:j,xStart:h.x,yStart:h.y,xEnd:g.x,yEnd:g.y})};I.rect=function(d,c,Z,e){this.moveTo(d,c);this.lineTo(d+Z,c);this.lineTo(d+Z,c+e);this.lineTo(d,c+e);this.closePath()};I.strokeRect=function(d,c,Z,e){var f=this.currentPath_;this.beginPath();this.moveTo(d,c);this.lineTo(d+Z,c);this.lineTo(d+Z,c+e);this.lineTo(d,c+e);this.closePath();this.stroke();this.currentPath_=f};I.fillRect=function(d,c,Z,e){var f=this.currentPath_;this.beginPath();this.moveTo(d,c);this.lineTo(d+Z,c);this.lineTo(d+Z,c+e);this.lineTo(d,c+e);this.closePath();this.fill();this.currentPath_=f};I.createLinearGradient=function(c,e,Z,d){var f=new W("gradient");f.x0_=c;f.y0_=e;f.x1_=Z;f.y1_=d;return f};I.createRadialGradient=function(e,g,d,c,f,Z){var h=new W("gradientradial");h.x0_=e;h.y0_=g;h.r0_=d;h.x1_=c;h.y1_=f;h.r1_=Z;return h};I.drawImage=function(s,e){var l,j,n,AA,q,o,u,AC;var m=s.runtimeStyle.width;var r=s.runtimeStyle.height;s.runtimeStyle.width="auto";s.runtimeStyle.height="auto";var k=s.width;var y=s.height;s.runtimeStyle.width=m;s.runtimeStyle.height=r;if(arguments.length==3){l=arguments[1];j=arguments[2];q=o=0;u=n=k;AC=AA=y}else{if(arguments.length==5){l=arguments[1];j=arguments[2];n=arguments[3];AA=arguments[4];q=o=0;u=k;AC=y}else{if(arguments.length==9){q=arguments[1];o=arguments[2];u=arguments[3];AC=arguments[4];l=arguments[5];j=arguments[6];n=arguments[7];AA=arguments[8]}else{throw Error("Invalid number of arguments")}}}var AB=this.getCoords_(l,j);var f=u/2;var c=AC/2;var z=[];var Z=10;var i=10;z.push(" <g_vml_:group",' coordsize="',A*Z,",",A*i,'"',' coordorigin="0,0"',' style="width:',Z,"px;height:",i,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]){var g=[];g.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",S(AB.x/A),",","Dy=",S(AB.y/A),"");var x=AB;var v=this.getCoords_(l+n,j);var t=this.getCoords_(l,j+AA);var p=this.getCoords_(l+n,j+AA);x.x=R.max(x.x,v.x,t.x,p.x);x.y=R.max(x.y,v.y,t.y,p.y);z.push("padding:0 ",S(x.x/A),"px ",S(x.y/A),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",g.join(""),", sizingmethod='clip');")}else{z.push("top:",S(AB.y/A),"px;left:",S(AB.x/A),"px;")}z.push(' ">','<g_vml_:image src="',s.src,'"',' style="width:',A*n,"px;"," height:",A*AA,'px;"',' cropleft="',q/k,'"',' croptop="',o/y,'"',' cropright="',(k-q-u)/k,'"',' cropbottom="',(y-o-AC)/y,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",z.join(""))};I.stroke=function(AE){var j=[];var k=false;var AP=C(AE?this.fillStyle:this.strokeStyle);var AA=AP.color;var AK=AP.alpha*this.globalAlpha;var f=10;var m=10;j.push("<g_vml_:shape",' filled="',!!AE,'"',' style="position:absolute;width:',f,"px;height:",m,'px;"',' coordorigin="0 0" coordsize="',A*f," ",A*m,'"',' stroked="',!AE,'"',' path="');var l=false;var AO={x:null,y:null};var w={x:null,y:null};for(var AJ=0;AJ<this.currentPath_.length;AJ++){var AI=this.currentPath_[AJ];var AN;switch(AI.type){case"moveTo":AN=AI;j.push(" m ",S(AI.x),",",S(AI.y));break;case"lineTo":j.push(" l ",S(AI.x),",",S(AI.y));break;case"close":j.push(" x ");AI=null;break;case"bezierCurveTo":j.push(" c ",S(AI.cp1x),",",S(AI.cp1y),",",S(AI.cp2x),",",S(AI.cp2y),",",S(AI.x),",",S(AI.y));break;case"at":case"wa":j.push(" ",AI.type," ",S(AI.x-this.arcScaleX_*AI.radius),",",S(AI.y-this.arcScaleY_*AI.radius)," ",S(AI.x+this.arcScaleX_*AI.radius),",",S(AI.y+this.arcScaleY_*AI.radius)," ",S(AI.xStart),",",S(AI.yStart)," ",S(AI.xEnd),",",S(AI.yEnd));break}if(AI){if(AO.x==null||AI.x<AO.x){AO.x=AI.x}if(w.x==null||AI.x>w.x){w.x=AI.x}if(AO.y==null||AI.y<AO.y){AO.y=AI.y}if(w.y==null||AI.y>w.y){w.y=AI.y}}}j.push(' ">');if(!AE){var v=this.lineScale_*this.lineWidth;if(v<1){AK*=v}j.push("<g_vml_:stroke",' opacity="',AK,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',P(this.lineCap),'"',' weight="',v,'px"',' color="',AA,'" />')}else{if(typeof this.fillStyle=="object"){var n=this.fillStyle;var t=0;var AH={x:0,y:0};var AB=0;var r=1;if(n.type_=="gradient"){var q=n.x0_/this.arcScaleX_;var d=n.y0_/this.arcScaleY_;var o=n.x1_/this.arcScaleX_;var AQ=n.y1_/this.arcScaleY_;var AM=this.getCoords_(q,d);var AL=this.getCoords_(o,AQ);var h=AL.x-AM.x;var g=AL.y-AM.y;t=Math.atan2(h,g)*180/Math.PI;if(t<0){t+=360}if(t<0.000001){t=0}}else{var AM=this.getCoords_(n.x0_,n.y0_);var Z=w.x-AO.x;var e=w.y-AO.y;AH={x:(AM.x-AO.x)/Z,y:(AM.y-AO.y)/e};Z/=this.arcScaleX_*A;e/=this.arcScaleY_*A;var AG=R.max(Z,e);AB=2*n.r0_/AG;r=2*n.r1_/AG-AB}var z=n.colors_;z.sort(function(i,c){return i.offset-c.offset});var u=z.length;var y=z[0].color;var x=z[u-1].color;var AD=z[0].alpha*this.globalAlpha;var AC=z[u-1].alpha*this.globalAlpha;var AF=[];for(var AJ=0;AJ<u;AJ++){var s=z[AJ];AF.push(s.offset*r+AB+" "+s.color)}j.push('<g_vml_:fill type="',n.type_,'"',' method="none" focus="100%"',' color="',y,'"',' color2="',x,'"',' colors="',AF.join(","),'"',' opacity="',AC,'"',' g_o_:opacity2="',AD,'"',' angle="',t,'"',' focusposition="',AH.x,",",AH.y,'" />')}else{j.push('<g_vml_:fill color="',AA,'" opacity="',AK,'" />')}}j.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",j.join(""))};I.fill=function(){this.stroke(true)};I.closePath=function(){this.currentPath_.push({type:"close"})};I.getCoords_=function(d,c){var Z=this.m_;return{x:A*(d*Z[0][0]+c*Z[1][0]+Z[2][0])-K,y:A*(d*Z[0][1]+c*Z[1][1]+Z[2][1])-K}};I.save=function(){var Z={};T(this,Z);this.aStack_.push(Z);this.mStack_.push(this.m_);this.m_=D(N(),this.m_)};I.restore=function(){T(this.aStack_.pop(),this);this.m_=this.mStack_.pop()};I.translate=function(d,c){var Z=[[1,0,0],[0,1,0],[d,c,1]];this.m_=D(Z,this.m_)};I.rotate=function(d){var f=a(d);var e=O(d);var Z=[[f,e,0],[-e,f,0],[0,0,1]];this.m_=D(Z,this.m_)};I.scale=function(f,e){this.arcScaleX_*=f;this.arcScaleY_*=e;var c=[[f,0,0],[0,e,0],[0,0,1]];var Z=this.m_=D(c,this.m_);var d=Z[0][0]*Z[1][1]-Z[0][1]*Z[1][0];this.lineScale_=Y(J(d))};I.clip=function(){};I.arcTo=function(){};I.createPattern=function(){return new F};function W(Z){this.type_=Z;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}W.prototype.addColorStop=function(c,Z){Z=C(Z);this.colors_.push({offset:c,color:Z.color,alpha:Z.alpha})};function F(){}G_vmlCanvasManager=H;CanvasRenderingContext2D=M;CanvasGradient=W;CanvasPattern=F})()}; \ No newline at end of file
diff --git a/pylons_app/public/js/yui.flot.js b/pylons_app/public/js/yui.flot.js
new file mode 100644
index 00000000..292b89a2
--- /dev/null
+++ b/pylons_app/public/js/yui.flot.js
@@ -0,0 +1,2483 @@
+/**
+\file yui.flot.js
+\brief Javascript plotting library for YUI based on Flot v. 0.5.
+\details
+This file contains a port of Flot for YUI
+
+Copyright (c) 2009 Yahoo! Inc. All rights reserved. The copyrights embodied
+in the content of this file are licenced by Yahoo! Inc. under the BSD (revised)
+open source license.
+
+Requires yahoo-dom-event and datasource which you can get here:
+<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.7.0/build/yahoo-dom-event/yahoo-dom-event.js&2.7.0/build/datasource/datasource-min.js"></script>
+
+Datasource is optional, you only need it if one of your axes has its mode set to "time"
+*/
+
+(function() {
+ var L = YAHOO.lang;
+ var UA = YAHOO.env.ua;
+ var DOM = YAHOO.util.Dom;
+ var E = YAHOO.util.Event;
+
+ if(!DOM.createElementFromMarkup) {
+ DOM.createElementFromMarkup = function(markup) {
+ var p=document.createElement('div');
+ p.innerHTML = markup;
+ var e = p.firstChild;
+ return p.removeChild(e);
+ };
+ }
+
+ if(!DOM.removeElement) {
+ DOM.removeElement = function(el) {
+ return el.parentNode.removeChild(el);
+ };
+ }
+
+ function Plot(target_, data_, options_) {
+ // 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"],
+ locale: "en",
+ 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
+ label: null,
+ labelWidth: null, // size of tick labels in pixels
+ labelHeight: null,
+
+ scaleType: 'linear', // may be 'linear' or 'log'
+
+ // mode specific options
+ tickDecimals: null, // no. of decimals, null means auto
+ tickSize: null, // number or [number, "unit"]
+ minTickSize: null, // number or [number, "unit"]
+ timeformat: null // format string to use
+ },
+ yaxis: {
+ label: null,
+ autoscaleMargin: 0.02
+ },
+ x2axis: {
+ label: null,
+ autoscaleMargin: null
+ },
+ y2axis: {
+ label: null,
+ autoscaleMargin: 0.02
+ },
+ 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
+ },
+ bars: {
+ show: false,
+ lineWidth: 2, // in pixels
+ barWidth: 1, // in units of the x axis
+ fill: true,
+ fillColor: null,
+ align: "left" // or "center"
+ },
+ grid: {
+ show: true,
+ showLines: 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
+ labelFontSize: 16,
+ 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"
+ },
+ crosshair: {
+ mode: null, // one of null, "x", "y" or "xy",
+ color: "#aa0000"
+ },
+ shadowSize: 3
+ },
+ 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,
+ target = DOM.get(target_),
+ axes = { xaxis: {}, yaxis: {}, x2axis: {}, y2axis: {} },
+ plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
+ canvasWidth = 0, canvasHeight = 0,
+ plotWidth = 0, plotHeight = 0,
+ // dedicated to storing data for buggy standard compliance cases
+ workarounds = {};
+
+ this.setData = setData;
+ this.setupGrid = setupGrid;
+ this.draw = draw;
+ this.clearSelection = clearSelection;
+ this.setSelection = setSelection;
+ this.getCanvas = function() { return canvas; };
+ this.getPlotOffset = function() { return plotOffset; };
+ this.getData = function() { return series; };
+ this.getAxes = function() { return axes; };
+ this.setCrosshair = setCrosshair;
+ this.clearCrosshair = function () { setCrosshair(null); };
+ this.highlight = highlight;
+ this.unhighlight = unhighlight;
+
+ // initialize
+ parseOptions(options_);
+ setData(data_);
+ constructCanvas();
+ setupGrid();
+ draw();
+
+ var plot = this;
+
+ plot.createEvent('plotclick');
+ plot.createEvent('plothover');
+ plot.createEvent('plotselected');
+ plot.createEvent('plotunselected');
+
+
+
+ function setData(d) {
+ series = parseData(d);
+
+ fillInSeriesOptions();
+ processData();
+ }
+
+ function normalizeData(d) {
+ var possible_controls = ['x', 'time', 'date'];
+
+ if (L.isArray(d)) {
+ d = { data: d };
+ } else {
+ d = L.merge(d);
+ }
+
+ if(d.disabled) {
+ return undefined;
+ }
+
+ if (d.data.length === 0) {
+ return undefined;
+ }
+
+ var j, k;
+
+ // Make a copy so we don't obliterate the caller's data
+ var _data = [];
+
+ if (L.isArray(d.data[0])) {
+ for(j=0; j<d.data.length; j++) {
+ if(d.data[j]) {
+ var x = d.data[j][0];
+ var y = d.data[j][1];
+
+ if(L.isObject(x) && x.getTime) x = x.getTime()/1000;
+ else x = parseFloat(x);
+
+ if(L.isObject(y) && y.getTime) y = y.getTime()/1000;
+ else y = parseFloat(y);
+
+ _data.push({ x: x, y: y});
+ } else {
+ _data.push(d.data[j]);
+ }
+ }
+ d.control='x';
+ d.schema='y';
+ } else {
+ for(j=0; j<d.data.length; j++) {
+ _data.push({});
+ for(k in d.data[j]) {
+ if(L.isObject(d.data[j][k]) && d.data[j][k].getTime)
+ _data[j][k] = d.data[j][k].getTime()/1000;
+ else
+ _data[j][k] = parseFloat(d.data[j][k]);
+ }
+ }
+ }
+
+ d.data = _data;
+
+ if (!d.control) {
+ // try to guess the control field
+ for (j=0; j<possible_controls.length; j++) {
+ if(possible_controls[j] in d.data[0]) {
+ d.control = possible_controls[j];
+ break;
+ }
+ }
+ }
+
+ if (!d.schema) {
+ d.schema = [];
+ for(k in d.data[0]) {
+ if(!d.control) {
+ d.control = k;
+ }
+ if(k !== d.control) {
+ d.schema.push(k);
+ }
+ }
+ }
+
+ return L.merge(d, {dropped: []});
+ }
+
+ function markDroppedPoints(s) {
+ var l=s.data.length;
+
+ if(l <= canvasWidth/10 || options.dontDropPoints) { // at least 10px per point
+ return s;
+ }
+
+ var dropperiod = 1-canvasWidth/10/l;
+ var drops = 0;
+ var points = l;
+
+ for(var j=0; j<l; j++) {
+ var x = s.data[j].x;
+ var y = s.data[j].y;
+
+ s.dropped[j] = (drops > 1);
+ if(s.dropped[j]) {
+ drops-=1;
+ }
+
+ if(!isNaN(x) && !isNaN(x))
+ drops+=dropperiod;
+ else {
+ drops=0; // bonus for a null point
+ points--;
+ dropperiod=1-canvasWidth/10/points;
+ }
+ }
+
+ return s;
+ }
+
+ function splitSeries(s) {
+ var res = [];
+
+ for(var k=0; k<s.schema.length; k++) {
+ res[k] = L.merge(s, {data: []});
+ if(s.label && L.isObject(s.label) && s.label[s.schema[k]]) {
+ res[k].label = s.label[s.schema[k]];
+ }
+ if(s.color && L.isObject(s.color) && s.color[s.schema[k]]) {
+ res[k].color = s.color[s.schema[k]];
+ }
+ }
+
+ for(var i=0; i<s.data.length; i++) {
+ var d = s.data[i];
+ for(k=0; k<s.schema.length; k++) {
+ var tuple = { x: d[s.control], y: d[s.schema[k]] };
+ res[k].data.push(tuple);
+ res[k].control='x';
+ res[k].schema='y';
+ }
+ }
+
+ return res;
+ }
+
+ function parseData(d) {
+ if(d.length === 0) {
+ return null;
+ }
+
+ // get the canvas width so we know if we have to drop points
+ canvasWidth = parseInt(DOM.getStyle(target, 'width'), 10);
+
+ // First we normalise the data into a standard format
+ var s, res = [];
+ for (var i = 0; i < d.length; ++i) {
+ s = normalizeData(d[i]);
+ if(typeof s === 'undefined')
+ continue;
+
+ if(L.isArray(s.schema)) {
+ s = splitSeries(s);
+ }
+ else {
+ s = [s];
+ }
+
+ for(var k=0; k<s.length; k++) {
+ s[k] = markDroppedPoints(s[k]);
+ res.push(s[k]);
+ }
+ }
+
+ return res;
+ }
+
+ function parseOptions(o) {
+ if (options.grid.borderColor == null)
+ options.grid.borderColor = options.grid.color;
+
+ if(typeof o === 'undefined') {
+ return;
+ }
+ o = YAHOO.lang.merge(o);
+ for(var k in o) {
+ if(L.isObject(o[k]) && L.isObject(options[k])) {
+ L.augmentObject(options[k], o[k], true);
+ delete o[k];
+ }
+ }
+ L.augmentObject(options, o, true);
+ }
+
+ 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 too 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();
+
+ // copy the rest
+ s.lines = L.merge(options.lines, s.lines || {});
+ s.points = L.merge(options.points, s.points || {});
+ s.bars = L.merge(options.bars, s.bars || {});
+
+ // turn on lines automatically in case nothing is set
+ if (s.lines.show == null && !s.bars.show && !s.points.show)
+ s.lines.show = true;
+
+ if (s.shadowSize == null)
+ s.shadowSize = options.shadowSize;
+
+ if (s.xaxis && s.xaxis == 2)
+ s.xaxis = axes.x2axis;
+ else
+ s.xaxis = axes.xaxis;
+ if (s.yaxis && s.yaxis >= 2) {
+ if(!axes['y' + s.yaxis + 'axis'])
+ axes['y' + s.yaxis + 'axis'] = {};
+ if(!options['y' + s.yaxis + 'axis'])
+ options['y' + s.yaxis + 'axis'] = { autoscaleMargin: 0.02 };
+ s.yaxis = axes['y' + s.yaxis + 'axis'];
+ }
+ else
+ s.yaxis = axes.yaxis;
+ }
+ }
+
+ function processData() {
+ var topSentry = Number.POSITIVE_INFINITY,
+ bottomSentry = Number.NEGATIVE_INFINITY,
+ 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;
+ }
+
+ for (var i = 0; i < series.length; ++i) {
+ var s = series[i];
+ var data = s.data,
+ axisx = s.xaxis, axisy = s.yaxis,
+ xmin = topSentry, xmax = bottomSentry,
+ ymin = topSentry, ymax = bottomSentry,
+ x, y, p;
+
+ axisx.used = axisy.used = true;
+
+ if (s.bars.show) {
+ // make sure we got room for the bar
+ var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2;
+ xmin += delta;
+ xmax += delta + s.bars.barWidth;
+ }
+
+ for (var j = 0; j < data.length; ++j) {
+ p = data[j];
+
+ if(data[j] === null)
+ continue;
+
+ x = p.x;
+ y = p.y;
+
+ if(L.isObject(x) && x.getTime) { // this is a Date object
+ x = x.getTime()/1000;
+ }
+
+ if(L.isObject(y) && y.getTime) { // this is a Date object
+ y = y.getTime()/1000;
+ }
+
+ // convert to number
+ if (x != null && !isNaN(x = +x)) {
+ if (x < xmin)
+ xmin = x;
+ if (x > xmax)
+ xmax = x;
+ }
+ else
+ x = null;
+
+ if (y != null && !isNaN(y = +y)) {
+ if (y < ymin)
+ ymin = y;
+ if (y > ymax)
+ ymax = y;
+ }
+ else
+ y = null;
+
+ if (x == null || y == null)
+ data[j] = x = y = null; // mark this point invalid
+ }
+
+ axisx.datamin = Math.min(axisx.datamin, xmin);
+ axisx.datamax = Math.max(axisx.datamax, xmax);
+ axisy.datamin = Math.min(axisy.datamin, ymin);
+ axisy.datamax = Math.max(axisy.datamax, ymax);
+ }
+ }
+
+ function constructCanvas() {
+ function makeCanvas(width, height, container, style) {
+ var c = document.createElement('canvas');
+ c.width = width;
+ c.height = height;
+ if (typeof G_vmlCanvasManager !== 'undefined') // excanvas hack
+ c = G_vmlCanvasManager.initElement(c);
+
+ if(style) {
+ for(var k in style) {
+ c.style[k] = style[k];
+ }
+ }
+ container.appendChild(c);
+
+ return c;
+ }
+
+ canvasWidth = parseInt(DOM.getStyle(target, 'width'), 10);
+ canvasHeight = parseInt(DOM.getStyle(target, 'height'), 10);
+ target.innerHTML = ""; // clear target
+ target.style.position = "relative"; // for positioning labels and overlay
+
+ if (canvasWidth <= 0 || canvasHeight <= 0)
+ throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;
+
+ if (YAHOO.env.ua.ie) {
+ G_vmlCanvasManager.init_(document);
+ }
+
+ // the canvas
+ canvas = makeCanvas(canvasWidth, canvasHeight, target);
+ ctx = canvas.getContext("2d");
+
+ // overlay canvas for interactive features
+ overlay = makeCanvas(canvasWidth, canvasHeight, target, { position: 'absolute', left: '0px', top: '0px' });
+ octx = overlay.getContext("2d");
+
+ // 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.crosshair.mode != null || options.grid.hoverable) {
+ E.on(eventHolder, 'mousemove', onMouseMove);
+
+ if (options.selection.mode != null)
+ E.on(eventHolder, "mousedown", onMouseDown);
+ }
+
+ if (options.crosshair.mode != null)
+ E.on(eventHolder, "mouseout", onMouseOut);
+
+ if (options.grid.clickable)
+ E.on(eventHolder, "click", onClick);
+ }
+
+ function setupGrid() {
+ function setupAxis(axis, options, type) {
+ setRange(axis, options);
+ prepareTickGeneration(axis, options);
+ setTicks(axis, options);
+ // add transformation helpers
+ if (type == 'x') {
+ // data point to canvas coordinate
+ axis.p2c = function (p) { return (p - axis.min) * axis.scale; };
+ // canvas coordinate to data point
+ axis.c2p = function (c) { return axis.min + c / axis.scale; };
+ }
+ else {
+ axis.p2c = function (p) { return (axis.max - p) * axis.scale; };
+ axis.c2p = function (c) { return axis.max - c / axis.scale; };
+ }
+ }
+
+ for (var axis in axes)
+ setupAxis(axes[axis], options[axis], axis.charAt(0));
+
+ setSpacing();
+ if(options.grid.show)
+ insertLabels();
+ insertLegend();
+ insertAxisLabels();
+ }
+
+ function setRange(axis, axisOptions) {
+ var min = axisOptions.min != null ? (axisOptions.scaleType == 'log' ? Math.log(axisOptions.min<=0?1:axisOptions.min) * Math.LOG10E : axisOptions.min) : axis.datamin;
+ var max = axisOptions.max != null ? (axisOptions.scaleType == 'log' ? Math.log(axisOptions.max) * Math.LOG10E : axisOptions.max) : axis.datamax;
+
+ if(axisOptions.mode === 'time') {
+ if(L.isObject(min) && min.getTime) min = min.getTime()/1000;
+ if(L.isObject(max) && max.getTime) max = max.getTime()/1000;
+ }
+
+ // degenerate case
+ if (min == Number.POSITIVE_INFINITY)
+ min = 0;
+ if (max == Number.NEGATIVE_INFINITY)
+ max = 1;
+
+ 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 >= 0)
+ min = 0;
+ }
+ if (axisOptions.max == null) {
+ max += (max - min) * margin;
+ if (max > 0 && 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, magn, norm;
+
+ if (axisOptions.mode == "time") {
+ // pretty handling of time
+
+ delta*=1000;
+
+ // 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 (var 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*1000);
+
+ 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/1000, 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*1000 && v != prev);
+
+ return ticks;
+ };
+
+ formatter = function (v, axis) {
+ var d = new Date(v);
+
+ // first check global format
+ if (axisOptions.timeformat != null)
+ return YAHOO.util.Date.format(d, {format: axisOptions.timeformat}, options.locale);
+
+ var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
+ var span = axis.max - axis.min;
+ span*=1000;
+
+ if (t < timeUnitSize.minute)
+ var fmt = "%k:%M:%S";
+ else if (t < timeUnitSize.day) {
+ if (span < 2 * timeUnitSize.day)
+ fmt = "%k:%M";
+ else
+ fmt = "%b %d %k:%M";
+ }
+ else if (t < timeUnitSize.month)
+ fmt = "%b %d";
+ else if (t < timeUnitSize.year) {
+ if (span < timeUnitSize.year/2)
+ fmt = "%b";
+ else
+ fmt = "%b %Y";
+ }
+ else
+ fmt = "%Y";
+
+ return YAHOO.util.Date.format(d, {format: fmt}, axisOptions.timelang);
+ };
+ }
+ 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;
+ var t=v;
+ if(axis.scaleType == 'log') {
+ t = Math.exp(t / Math.LOG10E);
+ }
+ ticks.push({ v: v, label: axis.tickFormatter(t, axis) });
+ ++i;
+ } while (v < axis.max && v != prev);
+ return ticks;
+ };
+
+ formatter = function (v, axis) {
+ return v.toFixed(axis.tickDecimals);
+ };
+ }
+
+ axis.scaleType = axisOptions.scaleType;
+ axis.tickSize = unit ? [size, unit] : size;
+ axis.tickGenerator = generator;
+ if (L.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 (L.isFunction(ticks))
+ // generate the ticks
+ ticks = ticks({ min: axis.min, max: axis.max });
+
+ // clean up the user-supplied ticks, copy them over
+ var v;
+ for (var 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 (axisOptions.scaleType == 'log') {
+ if (label == null)
+ label = v;
+ v = Math.log(v) * Math.LOG10E;
+ }
+
+ 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 setSpacing() {
+ function measureXLabels(axis) {
+ if(options.grid.show){
+ // 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) {
+ var labels = [];
+ for (var i = 0; i < axis.ticks.length; ++i) {
+ var l = axis.ticks[i].label;
+ if (l)
+ labels.push('<div class="tickLabel" style="float:left;width:' + axis.labelWidth + 'px">' + l + '</div>');
+ }
+
+ axis.labelHeight = 0;
+ if (labels.length > 0) {
+ var dummyDiv = target.appendChild(DOM.createElementFromMarkup('<div style="position:absolute;top:-10000px;width:10000px;font-size:smaller">'
+ + labels.join("") + '<div style="clear:left"></div></div>'));
+ axis.labelHeight = dummyDiv.offsetHeight;
+ target.removeChild(dummyDiv);
+ }
+ }
+ }
+ else{
+ axis.labelHeight = 0;
+ axis.labelWidth = 0;
+ }
+ }
+
+ function measureYLabels(axis) {
+ if(options.grid.show){
+ if (axis.labelWidth == null || axis.labelHeight == null) {
+ var labels = [], l;
+ // calculate y label dimensions
+ for (var i = 0; i < axis.ticks.length; ++i) {
+ l = axis.ticks[i].label;
+ if (l)
+ labels.push('<div class="tickLabel">' + l + '</div>');
+ }
+
+ if (labels.length > 0) {
+ var dummyDiv = target.appendChild(DOM.createElementFromMarkup('<div style="position:absolute;top:-10000px;font-size:smaller">'
+ + labels.join("") + '</div>'));
+ if (axis.labelWidth == null)
+ axis.labelWidth = dummyDiv.offsetWidth;
+ if (axis.labelHeight == null)
+ axis.labelHeight = dummyDiv.firstChild.offsetHeight;
+ target.removeChild(dummyDiv);
+ }
+
+ if (axis.labelWidth == null)
+ axis.labelWidth = 0;
+ if (axis.labelHeight == null)
+ axis.labelHeight = 0;
+ }
+ }
+ else{
+ axis.labelHeight = 0;
+ axis.labelWidth = 0;
+ }
+ }
+
+ measureXLabels(axes.xaxis);
+ measureYLabels(axes.yaxis);
+ measureXLabels(axes.x2axis);
+ measureYLabels(axes.y2axis);
+ // get the most space needed around the grid for things
+ // that may stick out
+ var maxOutset = (options.grid.show) ? options.grid.borderWidth : 0;
+ for (var i = 0; i < series.length; ++i)
+ maxOutset = (Math.max(maxOutset, 2 * (((series[i].points.show) ? series[i].points.radius : 0 ) + series[i].points.lineWidth/2)));
+
+ plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = maxOutset;
+
+ var margin = options.grid.labelMargin + options.grid.borderWidth;
+
+ 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;
+
+ // precompute how much the axis is scaling a point in canvas space
+ for(var axis in axes) {
+ axes[axis].scale = (axis.charAt(0) == 'x' ? plotWidth : plotHeight) / (axes[axis].max - axes[axis].min);
+ }
+ }
+
+ function draw() {
+ drawGrid();
+ for (var i = 0; i < series.length; i++) {
+ drawSeries(series[i]);
+ }
+ }
+
+ function extractRange(ranges, coord) {
+ var firstAxis = coord + "axis",
+ secondaryAxis = coord + "2axis",
+ axis, from, to, reverse;
+
+ if (ranges[firstAxis]) {
+ axis = firstAxis;
+ }
+ else if (ranges[secondaryAxis]) {
+ axis = secondaryAxis;
+ }
+ else {
+ return { from: null, to: null, axis: axes[firstAxis] };
+ }
+
+ from = ranges[axis].from;
+ to = ranges[axis].to;
+
+ if (options[axis].scaleType == 'log') {
+ if (from != null)
+ from = Math.log(from) * Math.LOG10E;
+ if (to != null)
+ to = Math.log(to) * Math.LOG10E;
+ }
+
+ axis = axes[axis];
+
+ // 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 (L.isFunction(markings))
+ markings = markings({ 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(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);
+ }
+ }
+ }
+
+ if(options.grid.show && options.grid.showLines) {
+ // 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.show && options.grid.borderWidth) {
+ // draw border
+ var bw = options.grid.borderWidth;
+ ctx.lineWidth = bw;
+ ctx.strokeStyle = options.grid.borderColor;
+ ctx.lineJoin = "round";
+ ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
+ }
+
+ ctx.restore();
+ }
+
+ function insertLabels() {
+ DOM.getElementsByClassName("tickLabels", "div", target, DOM.removeElement);
+
+ var html = ['<div class="tickLabels" style="font-size:smaller;color:' + options.grid.color + '">'];
+
+ 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 '<div style="position:absolute;top:' + (plotOffset.top + plotHeight + margin) + 'px;left:' + Math.round(plotOffset.left + axis.p2c(tick.v) - axis.labelWidth/2) + 'px;width:' + axis.labelWidth + 'px;text-align:center" class="tickLabel">' + tick.label + "</div>";
+ });
+
+
+ addLabels(axes.yaxis, function (tick, axis) {
+ return '<div style="position:absolute;top:' + Math.round(plotOffset.top + axis.p2c(tick.v) - axis.labelHeight/2) + 'px;right:' + (plotOffset.right + plotWidth + margin) + 'px;width:' + axis.labelWidth + 'px;text-align:right" class="tickLabel">' + tick.label + "</div>";
+ });
+
+ addLabels(axes.x2axis, function (tick, axis) {
+ return '<div style="position:absolute;bottom:' + (plotOffset.bottom + plotHeight + margin) + 'px;left:' + Math.round(plotOffset.left + axis.p2c(tick.v) - axis.labelWidth/2) + 'px;width:' + axis.labelWidth + 'px;text-align:center" class="tickLabel">' + tick.label + "</div>";
+ });
+
+ addLabels(axes.y2axis, function (tick, axis) {
+ return '<div style="position:absolute;top:' + Math.round(plotOffset.top + axis.p2c(tick.v) - axis.labelHeight/2) + 'px;left:' + (plotOffset.left + plotWidth + margin) +'px;width:' + axis.labelWidth + 'px;text-align:left" class="tickLabel">' + tick.label + "</div>";
+ });
+
+ html.push('</div>');
+
+ target.appendChild(DOM.createElementFromMarkup(html.join("")));
+ }
+
+ function insertAxisLabels() {
+ var xLocation, yLocation;
+ if( options.xaxis.label ) {
+ yLocation = plotOffset.top + plotHeight + ( axes.xaxis.labelHeight * 1.5 );
+ xLocation = plotOffset.left;
+ DOM.getElementsByClassName("xaxislabel", "div", target, DOM.removeElement);
+ target.appendChild(
+ DOM.createElementFromMarkup(
+ "<div class='xaxislabel' style='color:" + options.grid.color + ";width:" + plotWidth + "px;"
+ + "text-align:center;position:absolute;top:" + yLocation + "px;left:" + xLocation + "px;'>"
+ + options.xaxis.label + "</div>"
+ )
+ );
+ }
+ if( options.yaxis.label ) {
+ xLocation = plotOffset.left - ( axes.yaxis.labelWidth * 2 ) - options.grid.labelFontSize;
+ yLocation = plotOffset.top + plotHeight/2;
+ DOM.getElementsByClassName("yaxislabel", "div", target, DOM.removeElement);
+
+ target.appendChild(
+ DOM.createElementFromMarkup(
+ "<div class='yaxislabel' style='-moz-transform:rotate(270deg);-webkit-transform:rotate(270deg);writing-mode:tb-rl;filter:flipV flipH;color:" + options.grid.color + ";"
+ + "text-align:center;position:absolute;top:" + yLocation + "px;left:" + xLocation + "px;'>"
+ + options.yaxis.label + "</div>")
+ );
+ }
+ }
+
+ 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(data, xoffset, yoffset, axisx, axisy) {
+ var prev = null, cur=null, drawx = null, drawy = null;
+
+ ctx.beginPath();
+ for (var i = 0; i < data.length; i++) {
+ prev = cur;
+ cur = data[i];
+
+ if(prev == null || cur == null)
+ continue;
+
+ var x1 = prev.x, y1 = prev.y,
+ x2 = cur.x, y2 = cur.y;
+
+ // 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 (drawx != axisx.p2c(x1) + xoffset || drawy != axisy.p2c(y1) + yoffset)
+ ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
+
+ drawx = axisx.p2c(x2) + xoffset;
+ drawy = axisy.p2c(y2) + yoffset;
+ ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
+ }
+ ctx.stroke();
+ }
+
+ function plotLineArea(data, axisx, axisy) {
+ var prev, cur = null,
+ bottom = Math.min(Math.max(0, axisy.min), axisy.max),
+ top, lastX = 0, areaOpen = false;
+
+ for (var i = 0; i < data.length; i++) {
+ prev = cur;
+ cur = data[i];
+
+ if (areaOpen && x1 != null && x2 == null) {
+ // close area
+ ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom));
+ ctx.fill();
+ areaOpen = false;
+ continue;
+ }
+
+ if (prev == null || cur == null) {
+ if(areaOpen) {
+ ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom));
+ ctx.fill();
+ }
+ areaOpen = false;
+ continue;
+ }
+
+ var x1 = prev.x, y1 = prev.y,
+ x2 = cur.x, y2 = cur.y;
+
+ // 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)";
+ var xoffset = 1;
+ plotLine(series.data, xoffset, Math.sqrt((lw/2 + sw/2)*(lw/2 + sw/2) - xoffset*xoffset), series.xaxis, series.yaxis);
+ ctx.lineWidth = sw/2;
+ plotLine(series.data, xoffset, Math.sqrt((lw/2 + sw/4)*(lw/2 + sw/4) - xoffset*xoffset), 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.data, series.xaxis, series.yaxis);
+ }
+
+ if (lw > 0)
+ plotLine(series.data, 0, 0, series.xaxis, series.yaxis);
+ ctx.restore();
+ }
+
+ function drawSeriesPoints(series) {
+ function plotPoints(data, radius, fillStyle, offset, circumference, axisx, axisy) {
+ for (var i = 0; i < data.length; i++) {
+ if (data[i] == null || series.dropped[i])
+ continue;
+
+ var x = data[i].x, y = data[i].y;
+ if (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, true);
+ 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.data, radius, null, w + w/2, 2 * Math.PI,
+ series.xaxis, series.yaxis);
+
+ ctx.strokeStyle = "rgba(0,0,0,0.2)";
+ plotPoints(series.data, radius, null, w/2, 2 * Math.PI,
+ series.xaxis, series.yaxis);
+ }
+
+ ctx.lineWidth = lw;
+ ctx.strokeStyle = series.color;
+ plotPoints(series.data, radius,
+ getFillStyle(series.points, series.color), 0, 2 * Math.PI,
+ series.xaxis, series.yaxis);
+ ctx.restore();
+ }
+
+ function drawBar(x, y, barLeft, barRight, offset, fill, axisx, axisy, c) {
+ var drawLeft = true, drawRight = true,
+ drawTop = true, drawBottom = false,
+ left = x + barLeft, right = x + barRight,
+ bottom = 0, top = y;
+
+ // account for negative bars
+ if (top < bottom) {
+ top = 0;
+ bottom = y;
+ 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 (fill) {
+ c.beginPath();
+ c.moveTo(left, bottom);
+ c.lineTo(left, top);
+ c.lineTo(right, top);
+ c.lineTo(right, bottom);
+ if(typeof fill === 'function') {
+ c.fillStyle = fill(bottom, top);
+ } else if(typeof fill === 'string') {
+ c.fillStyle = fill;
+ }
+ 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(data, barLeft, barRight, offset, fill, axisx, axisy) {
+
+ for (var i = 0; i < data.length; i++) {
+ if (data[i] == null)
+ continue;
+ drawBar(data[i].x, data[i].y, barLeft, barRight, offset, fill, axisx, axisy, ctx);
+ }
+ }
+
+ 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 fill = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
+ plotBars(series.data, barLeft, barLeft + series.bars.barWidth, 0, fill, 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() {
+ DOM.getElementsByClassName("legend", "div", target, DOM.removeElement);
+
+ if (!options.legend.show)
+ return;
+
+ var fragments = [], rowStarted = false,
+ lf = options.legend.labelFormatter, s, label;
+ for (var 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('</tr>');
+ fragments.push('<tr>');
+ rowStarted = true;
+ }
+
+ if (lf)
+ label = lf(label, s);
+
+ fragments.push(
+ '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + s.color + ';overflow:hidden"></div></div></td>' +
+ '<td class="legendLabel">' + label + '</td>');
+ }
+ if (rowStarted)
+ fragments.push('</tr>');
+
+ if (fragments.length == 0)
+ return;
+
+ var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>';
+ if (options.legend.container != null)
+ DOM.get(options.legend.container).innerHTML = 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 = target.appendChild(DOM.createElementFromMarkup('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>'));
+ 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.firstChild;
+ var _el = DOM.insertBefore(
+ DOM.createElementFromMarkup('<div style="position:absolute;width:' + parseInt(DOM.getStyle(div, 'width'), 10)
+ + 'px;height:' + parseInt(DOM.getStyle(div, 'height'), 10) + 'px;'
+ + pos +'background-color:' + c + ';"> </div>'),
+ legend
+ );
+ DOM.setStyle(_el, '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 },
+ crosshair = { pos: { x: -1, y: -1 } },
+ 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) {
+ var maxDistance = options.grid.mouseActiveRadius,
+ lowestDistance = maxDistance * maxDistance + 1,
+ item = null, foundPoint = false, j, x, y;
+
+ function result(i, j) {
+ return {
+ datapoint: series[i].data[j],
+ dataIndex: j,
+ series: series[i],
+ seriesIndex: i
+ };
+ }
+
+ for (var i = 0; i < series.length; ++i) {
+ var s = series[i],
+ axisx = s.xaxis,
+ axisy = s.yaxis,
+ mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
+ my = axisy.c2p(mouseY),
+ maxx = maxDistance / axisx.scale,
+ maxy = maxDistance / axisy.scale;
+
+ var data = s.data;
+
+ if (s.lines.show || s.points.show) {
+ for (j = 0; j < data.length; j++ ) {
+ if (data[j] == null)
+ continue;
+
+ x = data[j].x;
+ y = data[j].y;
+
+ // 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 = result(i, j);
+ }
+ }
+ }
+
+ 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 < data.length; j++) {
+ x = data[j].x;
+ y = data[j].y;
+ if (x == null)
+ continue;
+
+ // for a bar graph, the cursor must be inside the bar
+ if ((mx >= x + barLeft && mx <= x + barRight &&
+ my >= Math.min(0, y) && my <= Math.max(0, y)))
+ item = result(i, j);
+ }
+ }
+ }
+
+ return item;
+ }
+
+ function onMouseMove(e) {
+ lastMousePos.pageX = E.getPageX(e);
+ lastMousePos.pageY = E.getPageY(e);
+
+ if (options.grid.hoverable)
+ triggerClickHoverEvent("plothover", lastMousePos);
+
+ if (options.crosshair.mode != null) {
+ if (!selection.active) {
+ setPositionFromEvent(crosshair.pos, lastMousePos);
+ triggerRedrawOverlay();
+ }
+ else
+ crosshair.pos.x = -1; // hide the crosshair while selecting
+ }
+
+ if (selection.active) {
+ updateSelection(lastMousePos);
+ }
+ }
+
+ function onMouseDown(e) {
+ var button = e.which || e.button;
+ if (button != 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; };
+ }
+
+ var mousePos = {pageX: E.getPageX(e), pageY: E.getPageY(e)};
+ setSelectionPos(selection.first, mousePos);
+
+ lastMousePos.pageX = null;
+ selection.active = true;
+ E.on(document, "mouseup", onSelectionMouseUp);
+ }
+
+ function onMouseOut(e) {
+ if (options.crosshair.mode != null && crosshair.pos.x != -1) {
+ crosshair.pos.x = -1;
+ triggerRedrawOverlay();
+ }
+ }
+
+ function onClick(e) {
+ if (clickIsMouseUp) {
+ clickIsMouseUp = false;
+ return;
+ }
+
+ var mousePos = {pageX: E.getPageX(e), pageY: E.getPageY(e)};
+ triggerClickHoverEvent("plotclick", mousePos);
+ }
+
+ // trigger click or hover event (they send the same parameters
+ // so we share their code)
+ function triggerClickHoverEvent(eventname, event) {
+ var offset = DOM.getXY(eventHolder[0]),
+ pos = { pageX: event.pageX, pageY: event.pageY },
+ canvasX = event.pageX - offset[0] - plotOffset.left,
+ canvasY = event.pageY - offset[1] - plotOffset.top;
+
+ for(var axis in axes)
+ if(axes[axis].used)
+ pos[axis.replace(/axis$/, '')] = axes[axis].c2p(axis.charAt(0) == 'x' ? canvasX : canvasY);
+
+ var item = findNearbyItem(canvasX, canvasY);
+
+ if (item) {
+ // fill in mouse pos for any listeners out there
+ item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint.x) + offset[0] + plotOffset.left, 10);
+ item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint.y) + offset[1] + plotOffset.top, 10);
+ }
+
+ 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);
+ }
+
+ plot.fireEvent(eventname, {pos: pos, item: item });
+ }
+
+ function triggerRedrawOverlay() {
+ if (!redrawTimeout)
+ redrawTimeout = setTimeout(redrawOverlay, 30);
+ }
+
+ function redrawOverlay() {
+ redrawTimeout = null;
+
+ // redraw highlights
+ octx.save();
+ octx.clearRect(0, 0, canvasWidth, canvasHeight);
+ octx.translate(plotOffset.left, plotOffset.top);
+
+ var hi;
+ for (var 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);
+ }
+
+ // redraw 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);
+ }
+
+ // redraw crosshair
+ var pos = crosshair.pos, mode = options.crosshair.mode;
+ if (mode != null && pos.x != -1) {
+ octx.strokeStyle = parseColor(options.crosshair.color).scale(null, null, null, 0.8).toString();
+ octx.lineWidth = 1;
+ ctx.lineJoin = "round";
+
+ octx.beginPath();
+ if (mode.indexOf("x") != -1) {
+ octx.moveTo(pos.x, 0);
+ octx.lineTo(pos.x, plotHeight);
+ }
+ if (mode.indexOf("y") != -1) {
+ octx.moveTo(0, pos.y);
+ octx.lineTo(plotWidth, pos.y);
+ }
+ octx.stroke();
+
+ }
+ octx.restore();
+ }
+
+ 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 (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.x, y = point.y,
+ 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, true);
+ octx.stroke();
+ }
+
+ function drawBarHighlight(series, point) {
+ octx.lineJoin = "round";
+ 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.x, point.y, barLeft, barLeft + series.bars.barWidth,
+ 0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx);
+ }
+
+ function setPositionFromEvent(pos, e) {
+ var offset = DOM.getXY(eventHolder[0]);
+ pos.x = clamp(0, e.pageX - offset[0] - plotOffset.left, plotWidth);
+ pos.y = clamp(0, e.pageY - offset[1] - plotOffset.top, plotHeight);
+ }
+
+ function setCrosshair(pos) {
+ if (pos == null)
+ crosshair.pos.x = -1;
+ else {
+ crosshair.pos.x = clamp(0, pos.x != null ? axes.xaxis.p2c(pos.x) : axes.x2axis.p2c(pos.x2), plotWidth);
+ crosshair.pos.y = clamp(0, pos.y != null ? axes.yaxis.p2c(pos.y) : axes.y2axis.p2c(pos.y2), plotHeight);
+ }
+ triggerRedrawOverlay();
+ }
+
+ function getSelectionForEvent() {
+ 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 = getSelectionForEvent();
+
+ plot.fireEvent("plotselected", r);
+ }
+
+ 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;
+ var mousePos = {pageX: E.getPageX(e), pageY: E.getPageY(e)};
+ updateSelection(mousePos);
+
+ if (selectionIsSane()) {
+ triggerSelectedEvent();
+ clickIsMouseUp = true;
+ }
+ else {
+ // this counts as a clear
+ plot.fireEvent("plotunselected", {});
+ }
+
+ E.removeListener(document, "mouseup", onSelectionMouseUp);
+ return false;
+ }
+
+ function setSelectionPos(pos, e) {
+ setPositionFromEvent(pos, e);
+
+ 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)
+ plot.fireEvent("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;
+ }
+ }
+ }
+
+ L.augment(Plot, YAHOO.util.EventProvider);
+
+ YAHOO.widget.Flot = function(target, data, options) {
+ return new Plot(target, data, options);
+ };
+
+ // 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, 10), 255);
+ this.g = clamp(0, parseInt(this.g, 10), 255);
+ this.b = clamp(0, parseInt(this.b, 10), 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 = DOM.getStyle(elem, 'backgroundColor').toLowerCase();
+ // keep going until we find an element that has color, or
+ // we hit the body
+ if (color != '' && color != 'transparent')
+ break;
+ elem = elem.parentNode;
+ } while (!elem.nodeName == "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 = L.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]);
+ }
+ }
+
+})();
diff --git a/pylons_app/templates/admin/admin.html b/pylons_app/templates/admin/admin.html
index a8a2fb90..b50ac91d 100644
--- a/pylons_app/templates/admin/admin.html
+++ b/pylons_app/templates/admin/admin.html
@@ -4,18 +4,25 @@
<%def name="title()">
${_('Administration')}
</%def>
-<%def name="breadcrumbs()">
- ${h.link_to(u'Admin',h.url('admin_home'))}
+
+<%def name="breadcrumbs_links()">
+ ${_('Admin dashboard - journal')}
</%def>
+
<%def name="page_nav()">
${self.menu('admin')}
- ${self.submenu('')}
</%def>
<%def name="main()">
- <div>
- <h2>Welcome ${c.hg_app_user.username}</h2>
- <div id="user_log">
- ${c.log_data}
- </div>
- </div>
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <!-- end box / title -->
+ <div class="table">
+ <div id="user_log">
+ ${c.log_data}
+ </div>
+ </div>
+</div>
</%def> \ No newline at end of file
diff --git a/pylons_app/templates/admin/admin_log.html b/pylons_app/templates/admin/admin_log.html
index 6f6660c4..c03ce28c 100644
--- a/pylons_app/templates/admin/admin_log.html
+++ b/pylons_app/templates/admin/admin_log.html
@@ -1,12 +1,12 @@
## -*- coding: utf-8 -*-
%if c.users_log:
-<table class="table_disp">
- <tr class="header">
- <td>${_('Username')}</td>
- <td>${_('Repository')}</td>
- <td>${_('Action')}</td>
- <td>${_('Date')}</td>
- <td>${_('From IP')}</td>
+<table>
+ <tr>
+ <th class="left">${_('Username')}</th>
+ <th class="left">${_('Repository')}</th>
+ <th class="left">${_('Action')}</th>
+ <th class="left">${_('Date')}</th>
+ <th class="left">${_('From IP')}</th>
</tr>
%for cnt,l in enumerate(c.users_log):
@@ -18,22 +18,23 @@
<td>${l.user_ip}</td>
</tr>
%endfor
-
</table>
-<div>
- <script type="text/javascript">
- var data_div = 'user_log';
- YAHOO.util.Event.onDOMReady(function(){
- YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
- YAHOO.util.Dom.setStyle('shortlog_data','opacity','0.3');});});
- </script>
- <h2>${c.users_log.pager('$link_previous ~2~ $link_next',
- onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{
- success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText;
- YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
- YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');});
- YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
- </h2>
+
+<script type="text/javascript">
+ var data_div = 'user_log';
+ YAHOO.util.Event.onDOMReady(function(){
+ YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
+ YAHOO.util.Dom.setStyle('shortlog_data','opacity','0.3');});});
+</script>
+
+
+<div class="pagination-wh pagination-left">
+${c.users_log.pager('$link_previous ~2~ $link_next',
+onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{
+success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText;
+YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
+ YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');});
+YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
</div>
%else:
${_('No actions yet')}
diff --git a/pylons_app/templates/admin/permissions/permissions.html b/pylons_app/templates/admin/permissions/permissions.html
index ba11da09..32f04cec 100644
--- a/pylons_app/templates/admin/permissions/permissions.html
+++ b/pylons_app/templates/admin/permissions/permissions.html
@@ -4,18 +4,25 @@
<%def name="title()">
${_('Permissions administration')}
</%def>
-<%def name="breadcrumbs()">
- ${h.link_to(u'Admin',h.url('admin_home'))}
- /
- ${_('Permissions')}
+
+<%def name="breadcrumbs_links()">
+ ${h.link_to(_('Admin'),h.url('admin_home'))}
+ &raquo;
+ ${_('Permissions')}
+
</%def>
<%def name="page_nav()">
${self.menu('admin')}
- ${self.submenu('permissions')}
</%def>
<%def name="main()">
- <div>
- <h2>${_('Permissions')}</h2>
-
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <!-- end box / title -->
+ <div class="table">
+ To implement
</div>
+</div>
</%def>
diff --git a/pylons_app/templates/admin/repos/repo_add.html b/pylons_app/templates/admin/repos/repo_add.html
index 002cfd1d..088098b0 100644
--- a/pylons_app/templates/admin/repos/repo_add.html
+++ b/pylons_app/templates/admin/repos/repo_add.html
@@ -4,41 +4,57 @@
<%def name="title()">
${_('Repositories administration')}
</%def>
-<%def name="breadcrumbs()">
- ${h.link_to(u'Admin',h.url('admin_home'))}
- /
- ${_('Repos')}
+
+<%def name="breadcrumbs_links()">
+ ${h.link_to(_('Admin'),h.url('admin_home'))}
+ &raquo;
+ ${h.link_to(_('Repositories'),h.url('repos'))}
+ &raquo;
+ ${_('add new')}
</%def>
+
<%def name="page_nav()">
${self.menu('admin')}
- ${self.submenu('repos')}
</%def>
<%def name="main()">
- <div>
- <h2>${_('Repositories')} - ${_('add new')}</h2>
- ${h.form(url('repos'))}
- <table>
- <tr>
- <td>${_('Name')}</td>
- <td>${h.text('repo_name',c.new_repo)}</td>
- <td>${self.get_form_error('repo_name')}</td>
- </tr>
- <tr>
- <td>${_('Description')}</td>
- <td>${h.textarea('description',cols=23,rows=5)}</td>
- <td>${self.get_form_error('description')}</td>
- </tr>
- <tr>
- <td>${_('Private')}</td>
- <td>${h.checkbox('private',value="True")}</td>
- <td>${self.get_form_error('private')}</td>
- </tr>
- <tr>
- <td></td>
- <td>${h.submit('add','add')}</td>
- </tr>
-
- </table>
- ${h.end_form()}
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
</div>
+ ${h.form(url('repos'))}
+ <div class="form">
+ <!-- fields -->
+ <div class="fields">
+ <div class="field">
+ <div class="label">
+ <label for="repo_name">${_('Name')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('repo_name',c.new_repo)}
+ </div>
+ </div>
+ <div class="field">
+ <div class="label label-textarea">
+ <label for="description">${_('Description')}:</label>
+ </div>
+ <div class="textarea text-area editor">
+ ${h.textarea('description',cols=23,rows=5)}
+ </div>
+ </div>
+ <div class="field">
+ <div class="label label-checkbox">
+ <label for="private">${_('Private')}:</label>
+ </div>
+ <div class="checkboxes">
+ ${h.checkbox('private',value="True")}
+ </div>
+ </div>
+ <div class="buttons">
+ ${h.submit('add','add',class_="ui-button ui-widget ui-state-default ui-corner-all")}
+ </div>
+ </div>
+ </div>
+ ${h.end_form()}
+</div>
</%def>
diff --git a/pylons_app/templates/admin/repos/repo_edit.html b/pylons_app/templates/admin/repos/repo_edit.html
index 24e2b48c..b01e0a3c 100644
--- a/pylons_app/templates/admin/repos/repo_edit.html
+++ b/pylons_app/templates/admin/repos/repo_edit.html
@@ -4,245 +4,271 @@
<%def name="title()">
${_('Repositories administration')}
</%def>
-<%def name="breadcrumbs()">
- ${h.link_to(u'Admin',h.url('admin_home'))}
- /
- ${_('Repos')}
+
+<%def name="breadcrumbs_links()">
+ ${h.link_to(_('Admin'),h.url('admin_home'))}
+ &raquo;
+ ${h.link_to(_('Repositories'),h.url('repos'))}
+ &raquo;
+ ${_('edit')} "${c.repo_name}"
</%def>
+
<%def name="page_nav()">
${self.menu('admin')}
- ${self.submenu('repos')}
</%def>
+
<%def name="main()">
- <div>
- <h2>${_('Repositories')} - ${_('edit')} "${c.repo_name}"</h2>
- ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')}
- <table>
- <tr>
- <td>${_('Name')}</td>
- <td>${h.text('repo_name',size="28")}</td>
- <td>${self.get_form_error('repo_name')}</td>
- </tr>
- <tr>
- <td>${_('Description')}</td>
- <td>${h.textarea('description',cols=32,rows=5)}</td>
- <td>${self.get_form_error('description')}</td>
- </tr>
- <tr>
- <td>${_('Private')}</td>
- <td>${h.checkbox('private',value="True")}</td>
- <td>${self.get_form_error('private')}</td>
- </tr>
- <tr>
- <td>${_('Owner')}</td>
- <td class='ac'>
- <div class="perm_ac">
- ${h.text('user',class_='yui-ac-input')}
- <div id="owner_container"></div>
- </div>
- </td>
- <td>${self.get_form_error('user')}</td>
- </tr>
- <tr>
- <td>${_('Permissions')}</td>
- <td>
- <table>
- <tr>
- <td>${_('none')}</td>
- <td>${_('read')}</td>
- <td>${_('write')}</td>
- <td>${_('admin')}</td>
- <td>${_('user')}</td>
- </tr>
-
- %for r2p in c.repo_info.repo2perm:
- %if r2p.user.username =='default' and c.repo_info.private:
- <tr>
- <td colspan="4">
- <span style="font-size: 0.8em">${_('disabled for private repository')}</span></td>
- <td>${r2p.user.username}</td>
- </tr>
- %else:
- <tr id="id${id(r2p.user.username)}">
- <td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
- <td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
- <td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
- <td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
- <td>${r2p.user.username}</td>
- <td>
- %if r2p.user.username !='default':
- <span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},'${'id%s'%id(r2p.user.username)}')">
- <script type="text/javascript">
- function ajaxAction(user_id,field_id){
- var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
- var callback = { success:function(o){
- var tr = YAHOO.util.Dom.get(String(field_id));
- tr.parentNode.removeChild(tr);}};
- var postData = '_method=delete&user_id='+user_id;
- var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);};
- </script>
- </span>
- %endif
- </td>
- </tr>
- %endif
- %endfor
- <%
- if not hasattr(c,'form_errors'):
- d = 'display:none;'
- else:
- d=''
- %>
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')}
+ <div class="form">
+ <!-- fields -->
+ <div class="fields">
+ <div class="field">
+ <div class="label">
+ <label for="repo_name">${_('Name')}:</label>
+ </div>
+ <div class="input input-medium">
+ ${h.text('repo_name')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label label-textarea">
+ <label for="description">${_('Description')}:</label>
+ </div>
+ <div class="textarea text-area editor">
+ ${h.textarea('description',cols=23,rows=5)}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label label-checkbox">
+ <label for="private">${_('Private')}:</label>
+ </div>
+ <div class="checkboxes">
+ ${h.checkbox('private',value="True")}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label label-checkbox">
+ <label for="user">${_('Owner')}:</label>
+ </div>
+ <div class="input input-small ac">
+ <div class="perm_ac">
+ ${h.text('user',class_='yui-ac-input')}
+ <div id="owner_container"></div>
+ </div>
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="input">${_('Permissions')}:</label>
+ </div>
+ <div class="input">
+ <table id="permissions_manage">
+ <tr>
+ <td>${_('none')}</td>
+ <td>${_('read')}</td>
+ <td>${_('write')}</td>
+ <td>${_('admin')}</td>
+ <td>${_('user')}</td>
+ <td></td>
+ </tr>
+
+ %for r2p in c.repo_info.repo2perm:
+ %if r2p.user.username =='default' and c.repo_info.private:
+ <tr>
+ <td colspan="6">
+ <span class="private_repo_msg">
+ ${_('disabled for private repository')}
+ </span>
+ </td>
+ <td>${r2p.user.username}</td>
+ </tr>
+ %else:
+ <tr id="id${id(r2p.user.username)}">
+ <td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
+ <td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
+ <td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
+ <td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
+ <td>${r2p.user.username}</td>
+ <td>
+ %if r2p.user.username !='default':
+ <span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},'${'id%s'%id(r2p.user.username)}')">
+ <script type="text/javascript">
+ function ajaxAction(user_id,field_id){
+ var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
+ var callback = { success:function(o){
+ var tr = YAHOO.util.Dom.get(String(field_id));
+ tr.parentNode.removeChild(tr);}};
+ var postData = '_method=delete&user_id='+user_id;
+ var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);};
+ </script>
+ </span>
+ %endif
+ </td>
+ </tr>
+ %endif
+ %endfor
- <tr id="add_perm_input" style="${d}">
- <td>${h.radio('perm_new_user','repository.none')}</td>
- <td>${h.radio('perm_new_user','repository.read')}</td>
- <td>${h.radio('perm_new_user','repository.write')}</td>
- <td>${h.radio('perm_new_user','repository.admin')}</td>
- <td class='ac'>
- <div class="perm_ac" id="perm_ac">
- ${h.text('perm_new_user_name',class_='yui-ac-input')}
- <div id="perm_container"></div>
- </div>
- </td>
- <td>${self.get_form_error('perm_new_user_name')}</td>
- </tr>
- <tr>
- <td colspan="4">
- <span id="add_perm" class="add_icon" style="cursor: pointer;">
- ${_('Add another user')}
- </span>
- </td>
- </tr>
- </table>
- </td>
-
- </tr>
- <tr>
- <td></td>
- <td>${h.submit('update','update')}</td>
- </tr>
-
- </table>
- ${h.end_form()}
+ <tr id="add_perm_input" >
+ <td>${h.radio('perm_new_user','repository.none')}</td>
+ <td>${h.radio('perm_new_user','repository.read')}</td>
+ <td>${h.radio('perm_new_user','repository.write')}</td>
+ <td>${h.radio('perm_new_user','repository.admin')}</td>
+ <td class='ac'>
+ <div class="perm_ac" id="perm_ac">
+ ${h.text('perm_new_user_name',class_='yui-ac-input')}
+ <div id="perm_container"></div>
+ </div>
+ </td>
+ <td></td>
+ </tr>
+ <tr>
+ <td colspan="6">
+ <span id="add_perm" class="add_icon" style="cursor: pointer;">
+ ${_('Add another user')}
+ </span>
+ </td>
+ </tr>
+ </table>
+ </div>
+
+ <div class="buttons">
+ ${h.submit('save','save',class_="ui-button ui-widget ui-state-default ui-corner-all")}
+ </div>
+ </div>
+ </div>
+ </div>
+ ${h.end_form()}
<script type="text/javascript">
- YAHOO.util.Event.onDOMReady(function(){
- var D = YAHOO.util.Dom;
- YAHOO.util.Event.addListener('add_perm','click',function(){
- D.setStyle('add_perm_input','display','');
- D.setStyle('add_perm','opacity','0.6');
- D.setStyle('add_perm','cursor','default');
- });
+ YAHOO.util.Event.onDOMReady(function(){
+ var D = YAHOO.util.Dom;
+ if(!D.hasClass('perm_new_user_name','error')){
+ D.setStyle('add_perm_input','display','none');
+ }
+ YAHOO.util.Event.addListener('add_perm','click',function(){
+ D.setStyle('add_perm_input','display','');
+ D.setStyle('add_perm','opacity','0.6');
+ D.setStyle('add_perm','cursor','default');
+ });
});
</script>
- <script type="text/javascript">
- YAHOO.example.FnMultipleFields = function(){
- var myContacts = ${c.users_array|n}
-
- // Define a custom search function for the DataSource
- var matchNames = function(sQuery) {
- // Case insensitive matching
- var query = sQuery.toLowerCase(),
- contact,
- i=0,
- l=myContacts.length,
- matches = [];
-
- // Match against each name of each contact
- for(; i<l; i++) {
- contact = myContacts[i];
- if((contact.fname.toLowerCase().indexOf(query) > -1) ||
- (contact.lname.toLowerCase().indexOf(query) > -1) ||
- (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
- matches[matches.length] = contact;
- }
- }
-
- return matches;
- };
-
- // Use a FunctionDataSource
- var oDS = new YAHOO.util.FunctionDataSource(matchNames);
- oDS.responseSchema = {
- fields: ["id", "fname", "lname", "nname"]
- }
-
- // Instantiate AutoComplete for perms
- var oAC_perms = new YAHOO.widget.AutoComplete("perm_new_user_name", "perm_container", oDS);
- oAC_perms.useShadow = false;
- oAC_perms.resultTypeList = false;
-
- // Instantiate AutoComplete for owner
- var oAC_owner = new YAHOO.widget.AutoComplete("user", "owner_container", oDS);
- oAC_owner.useShadow = false;
- oAC_owner.resultTypeList = false;
-
-
- // Custom formatter to highlight the matching letters
- var custom_formatter = function(oResultData, sQuery, sResultMatch) {
- var query = sQuery.toLowerCase(),
- fname = oResultData.fname,
- lname = oResultData.lname,
- nname = oResultData.nname || "", // Guard against null value
- query = sQuery.toLowerCase(),
- fnameMatchIndex = fname.toLowerCase().indexOf(query),
- lnameMatchIndex = lname.toLowerCase().indexOf(query),
- nnameMatchIndex = nname.toLowerCase().indexOf(query),
- displayfname, displaylname, displaynname;
-
- if(fnameMatchIndex > -1) {
- displayfname = highlightMatch(fname, query, fnameMatchIndex);
- }
- else {
- displayfname = fname;
- }
-
- if(lnameMatchIndex > -1) {
- displaylname = highlightMatch(lname, query, lnameMatchIndex);
- }
- else {
- displaylname = lname;
- }
-
- if(nnameMatchIndex > -1) {
- displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
- }
- else {
- displaynname = nname ? "(" + nname + ")" : "";
- }
-
- return displayfname + " " + displaylname + " " + displaynname;
-
- };
- oAC_perms.formatResult = custom_formatter;
- oAC_owner.formatResult = custom_formatter;
-
- // Helper function for the formatter
- var highlightMatch = function(full, snippet, matchindex) {
- return full.substring(0, matchindex) +
- "<span class='match'>" +
- full.substr(matchindex, snippet.length) +
- "</span>" +
- full.substring(matchindex + snippet.length);
- };
-
- var myHandler = function(sType, aArgs) {
- var myAC = aArgs[0]; // reference back to the AC instance
- var elLI = aArgs[1]; // reference to the selected LI element
- var oData = aArgs[2]; // object literal of selected item's result data
- myAC.getInputEl().value = oData.nname;
- };
+ <script type="text/javascript">
+ YAHOO.example.FnMultipleFields = function(){
+ var myContacts = ${c.users_array|n}
+
+ // Define a custom search function for the DataSource
+ var matchNames = function(sQuery) {
+ // Case insensitive matching
+ var query = sQuery.toLowerCase(),
+ contact,
+ i=0,
+ l=myContacts.length,
+ matches = [];
+
+ // Match against each name of each contact
+ for(; i<l; i++) {
+ contact = myContacts[i];
+ if((contact.fname.toLowerCase().indexOf(query) > -1) ||
+ (contact.lname.toLowerCase().indexOf(query) > -1) ||
+ (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
+ matches[matches.length] = contact;
+ }
+ }
+
+ return matches;
+ };
+
+ // Use a FunctionDataSource
+ var oDS = new YAHOO.util.FunctionDataSource(matchNames);
+ oDS.responseSchema = {
+ fields: ["id", "fname", "lname", "nname"]
+ }
+
+ // Instantiate AutoComplete for perms
+ var oAC_perms = new YAHOO.widget.AutoComplete("perm_new_user_name", "perm_container", oDS);
+ oAC_perms.useShadow = false;
+ oAC_perms.resultTypeList = false;
+
+ // Instantiate AutoComplete for owner
+ var oAC_owner = new YAHOO.widget.AutoComplete("user", "owner_container", oDS);
+ oAC_owner.useShadow = false;
+ oAC_owner.resultTypeList = false;
+
+
+ // Custom formatter to highlight the matching letters
+ var custom_formatter = function(oResultData, sQuery, sResultMatch) {
+ var query = sQuery.toLowerCase(),
+ fname = oResultData.fname,
+ lname = oResultData.lname,
+ nname = oResultData.nname || "", // Guard against null value
+ query = sQuery.toLowerCase(),
+ fnameMatchIndex = fname.toLowerCase().indexOf(query),
+ lnameMatchIndex = lname.toLowerCase().indexOf(query),
+ nnameMatchIndex = nname.toLowerCase().indexOf(query),
+ displayfname, displaylname, displaynname;
+
+ if(fnameMatchIndex > -1) {
+ displayfname = highlightMatch(fname, query, fnameMatchIndex);
+ }
+ else {
+ displayfname = fname;
+ }
+
+ if(lnameMatchIndex > -1) {
+ displaylname = highlightMatch(lname, query, lnameMatchIndex);
+ }
+ else {
+ displaylname = lname;
+ }
+
+ if(nnameMatchIndex > -1) {
+ displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
+ }
+ else {
+ displaynname = nname ? "(" + nname + ")" : "";
+ }
+
+ return displayfname + " " + displaylname + " " + displaynname;
+
+ };
+ oAC_perms.formatResult = custom_formatter;
+ oAC_owner.formatResult = custom_formatter;
+
+ // Helper function for the formatter
+ var highlightMatch = function(full, snippet, matchindex) {
+ return full.substring(0, matchindex) +
+ "<span class='match'>" +
+ full.substr(matchindex, snippet.length) +
+ "</span>" +
+ full.substring(matchindex + snippet.length);
+ };
+
+ var myHandler = function(sType, aArgs) {
+ var myAC = aArgs[0]; // reference back to the AC instance
+ var elLI = aArgs[1]; // reference to the selected LI element
+ var oData = aArgs[2]; // object literal of selected item's result data
+ myAC.getInputEl().value = oData.nname;
+ };
- oAC_perms.itemSelectEvent.subscribe(myHandler);
- oAC_owner.itemSelectEvent.subscribe(myHandler);
-
- return {
- oDS: oDS,
- oAC_perms: oAC_perms,
- oAC_owner: oAC_owner,
- };
- }();
-
- </script>
- </div>
-</%def>
+ oAC_perms.itemSelectEvent.subscribe(myHandler);
+ oAC_owner.itemSelectEvent.subscribe(myHandler);
+
+ return {
+ oDS: oDS,
+ oAC_perms: oAC_perms,
+ oAC_owner: oAC_owner,
+ };
+ }();
+
+ </script>
+
+</div>
+</%def> \ No newline at end of file
diff --git a/pylons_app/templates/admin/repos/repos.html b/pylons_app/templates/admin/repos/repos.html
index db52a7b9..12359295 100644
--- a/pylons_app/templates/admin/repos/repos.html
+++ b/pylons_app/templates/admin/repos/repos.html
@@ -4,42 +4,52 @@
<%def name="title()">
${_('Repositories administration')}
</%def>
-<%def name="breadcrumbs()">
- ${h.link_to(u'Admin',h.url('admin_home'))}
- /
- ${_('Repos')}
+
+
+<%def name="breadcrumbs_links()">
+ ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Repositories')}
</%def>
<%def name="page_nav()">
${self.menu('admin')}
- ${self.submenu('repos')}
</%def>
<%def name="main()">
- <div>
- <h2>${_('Repositories administration')}</h2>
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ <ul class="links">
+ <li>
+ <span>${h.link_to(u'ADD NEW REPO',h.url('new_repo'),class_="add_icon")}</span>
+ </li>
+ </ul>
+ </div>
+ <!-- end box / title -->
+ <div class="table">
<table class="table_disp">
<tr class="header">
- <td>${_('name')}</td>
- <td>${_('last revision')}</td>
- <td>${_('action')}</td>
+ <th class="left">${_('name')}</th>
+ <th class="left">${_('last revision')}</th>
+ <th class="left">${_('action')}</th>
</tr>
- %for cnt,repo in enumerate(c.repos_list):
- <tr class="parity${cnt%2}">
- <td>
- %if repo['repo'].dbrepo.private:
- <img alt="${_('private')}" src="/images/icons/lock.png">
- %else:
- <img alt="${_('public')}" src="/images/icons/lock_open.png">
- %endif
- ${h.link_to(repo['name'],h.url('edit_repo',repo_name=repo['name']))}</td>
- <td>r${repo['rev']}:${repo['tip']}</td>
+ %for cnt,repo in enumerate(c.repos_list):
+ <tr class="parity${cnt%2}">
+ <td>
+ %if repo['repo'].dbrepo.private:
+ <img alt="${_('private')}" src="/images/icons/lock.png"/>
+ %else:
+ <img alt="${_('public')}" src="/images/icons/lock_open.png"/>
+ %endif
+ ${h.link_to(repo['name'],h.url('edit_repo',repo_name=repo['name']))}</td>
+ <td>r${repo['rev']}:${repo['tip']}</td>
<td>
${h.form(url('repo', repo_name=repo['name']),method='delete')}
- ${h.submit('remove','delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
+ ${h.submit('remove','delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
${h.end_form()}
- </td>
- </tr>
- %endfor
- </table>
- <span class="add_icon">${h.link_to(u'add repo',h.url('new_repo'))}</span>
+ </td>
+ </tr>
+ %endfor
+ </table>
</div>
+</div>
+
</%def>
diff --git a/pylons_app/templates/admin/settings/settings.html b/pylons_app/templates/admin/settings/settings.html
index 1f9dd9d0..d3277a6c 100644
--- a/pylons_app/templates/admin/settings/settings.html
+++ b/pylons_app/templates/admin/settings/settings.html
@@ -4,50 +4,81 @@
<%def name="title()">
${_('Settings administration')}
</%def>
-<%def name="breadcrumbs()">
- ${h.link_to(u'Admin',h.url('admin_home'))}
- /
- ${_('Settings')}
+
+
+
+<%def name="breadcrumbs_links()">
+ ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Settings')}
</%def>
+
<%def name="page_nav()">
${self.menu('admin')}
- ${self.submenu('settings')}
</%def>
-<%def name="main()">
- <div>
- <h2>${_('Settings administration')}</h2>
- ${h.form(url('admin_setting', id='mapping'),method='put')}
- <table class="table_disp">
- <tr class="header">
- <td colspan="2">${_('Remap and rescan repositories')}</td>
- </tr>
- <tr align="right">
- <td><span class="tooltip" tooltip_title="${h.tooltip(_('In case a repository was deleted from filesystem and there are leftovers in the database check this option to scan obsolete data in database and remove it.'))}">
- ${_('destroy old data')}</span> ${h.checkbox('destroy',True)}</td>
- <td>${h.submit('rescan','rescan repositories')}</td>
- </table>
- ${h.end_form()}
- <br/>
- ${h.form(url('admin_setting', id='global'),method='put')}
- <table class="table_disp">
- <tr class="header">
- <td colspan="3">${_('Global application settings')}</td>
- </tr>
- <tr>
- <td>${_('Application name')}</td>
- <td>${h.text('app_title',size=30)}${self.get_form_error('app_title')}</td>
- </tr>
- <tr>
- <td>${_('Realm text')}</td>
- <td>${h.text('app_auth_realm',size=30)}${self.get_form_error('app_auth_realm')}</td>
- </tr>
- <tr>
- <td></td>
- <td>${h.submit('save','save settings')}</td>
- </tr>
- </table>
- ${h.end_form()}
-
+<%def name="main()">
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
</div>
+ <!-- end box / title -->
+
+ ${h.form(url('admin_setting', id='mapping'),method='put')}
+ <div class="form">
+ <!-- fields -->
+ <h3>${_('Remap and rescan repositories')}</h3>
+ <div class="fields">
+ <div class="field">
+ <div class="label label-checkbox">
+ <label for="-button">${_('rescan option')}:</label>
+ </div>
+ <div class="checkboxes">
+ <div class="checkbox">
+ ${h.checkbox('destroy',True)}
+ <label for="checkbox-1">
+ <span class="tooltip" tooltip_title="${h.tooltip(_('In case a repository was deleted from filesystem and there are leftovers in the database check this option to scan obsolete data in database and remove it.'))}">
+ ${_('destroy old data')}</span> </label>
+ </div>
+ </div>
+ </div>
+
+ <div class="buttons">
+ ${h.submit('rescan','rescan repositories',class_="ui-button ui-widget ui-state-default ui-corner-all")}</td>
+ </div>
+ </div>
+ </div>
+ ${h.end_form()}
+
+ ${h.form(url('admin_setting', id='global'),method='put')}
+ <div class="form">
+ <!-- fields -->
+ <h3>${_('Global application settings')}</h3>
+ <div class="fields">
+
+ <div class="field">
+ <div class="label">
+ <label for="input-small">${_('Application name')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('app_title',size=30)}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="input-small">${_('Realm text')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('app_auth_realm',size=30)}
+ </div>
+ </div>
+
+ <div class="buttons">
+ ${h.submit('save','save settings',class_="ui-button ui-widget ui-state-default ui-corner-all")}
+ </div>
+ </div>
+ </div>
+ ${h.end_form()}
+
+</div>
</%def>
diff --git a/pylons_app/templates/admin/users/user_add.html b/pylons_app/templates/admin/users/user_add.html
index f93d583a..b8b09505 100644
--- a/pylons_app/templates/admin/users/user_add.html
+++ b/pylons_app/templates/admin/users/user_add.html
@@ -4,55 +4,88 @@
<%def name="title()">
${_('User administration')}
</%def>
-<%def name="breadcrumbs()">
- ${h.link_to(u'Admin',h.url('admin_home'))}
- /
- ${_('Users')}
+<%def name="breadcrumbs_links()">
+ ${h.link_to(_('Admin'),h.url('admin_home'))}
+ &raquo;
+ ${h.link_to(_('Users'),h.url('users'))}
+ &raquo;
+ ${_('add new user')}
</%def>
+
<%def name="page_nav()">
${self.menu('admin')}
- ${self.submenu('users')}
</%def>
+
<%def name="main()">
- <div>
- <h2>${_('User')} - ${_('add new')}</h2>
- ${h.form(url('users'))}
- <table>
- <tr>
- <td>${_('Username')}</td>
- <td>${h.text('username')}</td>
- <td>${self.get_form_error('username')}</td>
- </tr>
- <tr>
- <td>${_('Password')}</td>
- <td>${h.password('password')}</td>
- <td>${self.get_form_error('password')}</td>
- </tr>
- <tr>
- <td>${_('Name')}</td>
- <td>${h.text('name')}</td>
- <td>${self.get_form_error('name')}</td>
- </tr>
- <tr>
- <td>${_('Lastname')}</td>
- <td>${h.text('lastname')}</td>
- <td>${self.get_form_error('lastname')}</td>
- </tr>
- <tr>
- <td>${_('Email')}</td>
- <td>${h.text('email')}</td>
- <td>${self.get_form_error('email')}</td>
- </tr>
- <tr>
- <td>${_('Active')}</td>
- <td>${h.checkbox('active',value=True)}</td>
- <td>${self.get_form_error('active')}</td>
- </tr>
- <tr>
- <td></td>
- <td>${h.submit('save','save')}</td>
- </tr>
- </table>
- ${h.end_form()}
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <!-- end box / title -->
+ ${h.form(url('users'))}
+ <div class="form">
+ <!-- fields -->
+ <div class="fields">
+ <div class="field">
+ <div class="label">
+ <label for="username">${_('Username')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('username')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="password">${_('Password')}:</label>
+ </div>
+ <div class="input">
+ ${h.password('password')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="name">${_('Name')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('name')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="lastname">${_('Lastname')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('lastname')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="email">${_('Email')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('email')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label label-checkbox">
+ <label for="active">${_('Active')}:</label>
+ </div>
+ <div class="checkboxes">
+ ${h.checkbox('active',value=True)}
+ </div>
+ </div>
+
+ <div class="buttons">
+ ${h.submit('save','save',class_="ui-button ui-widget ui-state-default ui-corner-all")}
+ </div>
+ </div>
</div>
+ ${h.end_form()}
+</div>
</%def> \ No newline at end of file
diff --git a/pylons_app/templates/admin/users/user_edit.html b/pylons_app/templates/admin/users/user_edit.html
index 4fec9e2b..7cf2453e 100644
--- a/pylons_app/templates/admin/users/user_edit.html
+++ b/pylons_app/templates/admin/users/user_edit.html
@@ -4,61 +4,98 @@
<%def name="title()">
${_('User administration')}
</%def>
-<%def name="breadcrumbs()">
- ${h.link_to(u'Admin',h.url('admin_home'))}
- /
- ${_('Users')}
+
+<%def name="breadcrumbs_links()">
+ ${h.link_to(_('Admin'),h.url('admin_home'))}
+ &raquo;
+ ${h.link_to(_('Users'),h.url('users'))}
+ &raquo;
+ ${_('edit')} "${c.user.username}"
</%def>
+
<%def name="page_nav()">
${self.menu('admin')}
- ${self.submenu('users')}
</%def>
+
<%def name="main()">
- <div>
- <h2>${_('User')} - ${c.user.username}</h2>
- ${h.form(url('user', id=c.user.user_id),method='put')}
- <table>
- <tr>
- <td>${_('Username')}</td>
- <td>${h.text('username')}</td>
- <td>${self.get_form_error('username')}</td>
- </tr>
- <tr>
- <td>${_('New password')}</td>
- <td>${h.text('new_password')}</td>
- <td>${self.get_form_error('new_password')}</td>
- </tr>
- <tr>
- <td>${_('Name')}</td>
- <td>${h.text('name')}</td>
- <td>${self.get_form_error('name')}</td>
- </tr>
- <tr>
- <td>${_('Lastname')}</td>
- <td>${h.text('lastname')}</td>
- <td>${self.get_form_error('lastname')}</td>
- </tr>
- <tr>
- <td>${_('Email')}</td>
- <td>${h.text('email')}</td>
- <td>${self.get_form_error('email')}</td>
- </tr>
- <tr>
- <td>${_('Active')}</td>
- <td>${h.checkbox('active',value=True)}</td>
- <td>${self.get_form_error('active')}</td>
- </tr>
- <tr>
- <td>${_('Admin')}</td>
- <td>${h.checkbox('admin',value=True)}</td>
- <td>${self.get_form_error('admin')}</td>
- </tr>
- <tr>
- <td></td>
- <td>${h.submit('save','save')}</td>
- </tr>
-
- </table>
- ${h.end_form()}
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <!-- end box / title -->
+ ${h.form(url('user', id=c.user.user_id),method='put')}
+ <div class="form">
+ <!-- fields -->
+ <div class="fields">
+ <div class="field">
+ <div class="label">
+ <label for="username">${_('Username')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('username')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="new_password">${_('New password')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('new_password')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="name">${_('Name')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('name')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="lastname">${_('Lastname')}:</label>
+ </div>
+ <div class="input">
+ ${h.password('lastname')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="email">${_('Email')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('email')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label label-checkbox">
+ <label for="active">${_('Active')}:</label>
+ </div>
+ <div class="checkboxes">
+ ${h.checkbox('active',value=True)}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label label-checkbox">
+ <label for="admin">${_('Admin')}:</label>
+ </div>
+ <div class="checkboxes">
+ ${h.checkbox('admin',value=True)}
+ </div>
+ </div>
+
+ <div class="buttons">
+ ${h.submit('save','save',class_="ui-button ui-widget ui-state-default ui-corner-all")}
+ </div>
+ </div>
</div>
+ ${h.end_form()}
+</div>
</%def> \ No newline at end of file
diff --git a/pylons_app/templates/admin/users/users.html b/pylons_app/templates/admin/users/users.html
index 84dfe184..4182cc82 100644
--- a/pylons_app/templates/admin/users/users.html
+++ b/pylons_app/templates/admin/users/users.html
@@ -4,42 +4,55 @@
<%def name="title()">
${_('Users administration')}
</%def>
-<%def name="breadcrumbs()">
- ${h.link_to(u'Admin',h.url('admin_home'))}
- /
- ${_('Users')}
+
+<%def name="breadcrumbs_links()">
+ ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Users')}
</%def>
+
<%def name="page_nav()">
${self.menu('admin')}
- ${self.submenu('users')}
</%def>
+
<%def name="main()">
- <div>
- <h2>${_('Users administration')}</h2>
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ <ul class="links">
+ <li>
+ <span>${h.link_to(u'ADD NEW USER',h.url('new_user'),class_="add_icon")}</span>
+ </li>
+
+ </ul>
+ </div>
+ <!-- end box / title -->
+ <div class="table">
<table class="table_disp">
- <tr class="header">
- <td>${_('username')}</td>
- <td>${_('name')}</td>
- <td>${_('lastname')}</td>
- <td>${_('active')}</td>
- <td>${_('admin')}</td>
- <td>${_('action')}</td>
- </tr>
- %for user in c.users_list:
- <tr>
+ <tr class="header">
+ <th class="left">${_('username')}</th>
+ <th class="left">${_('name')}</th>
+ <th class="left">${_('lastname')}</th>
+ <th class="left">${_('active')}</th>
+ <th class="left">${_('admin')}</th>
+ <th class="left">${_('action')}</th>
+ </tr>
+ %for cnt,user in enumerate(c.users_list):
+ %if user.name !='default':
+ <tr class="parity${cnt%2}">
<td>${h.link_to(user.username,h.url('edit_user', id=user.user_id))}</td>
<td>${user.name}</td>
<td>${user.lastname}</td>
<td>${user.active}</td>
<td>${user.admin}</td>
<td>
- ${h.form(url('user', id=user.user_id),method='delete')}
- ${h.submit('remove','delete',class_="delete_icon action_button")}
- ${h.end_form()}
- </td>
+ ${h.form(url('user', id=user.user_id),method='delete')}
+ ${h.submit('remove','delete',class_="delete_icon action_button")}
+ ${h.end_form()}
+ </td>
</tr>
+ %endif
%endfor
</table>
- <span class="add_icon">${h.link_to(u'add user',h.url('new_user'))}</span>
</div>
+</div>
</%def>
diff --git a/pylons_app/templates/base/base.html b/pylons_app/templates/base/base.html
index 6ce97e62..6d5b57e2 100644
--- a/pylons_app/templates/base/base.html
+++ b/pylons_app/templates/base/base.html
@@ -2,97 +2,120 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
<head>
+ <title>${next.title()}</title>
<link rel="icon" href="/images/hgicon.png" type="image/png" />
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="robots" content="index, nofollow"/>
- <title>${next.title()}</title>
- ##For future use yui reset for cross browser compatability.
- ##<link rel="stylesheet" href="/js/yui/reset-fonts-grids/reset-fonts-grids.css" type="text/css" />
+ <!-- stylesheets -->
${self.css()}
+ <!-- scripts -->
${self.js()}
</head>
+<body>
+ <!-- header -->
+ <div id="header">
+ <!-- user -->
+ <ul id="logged-user">
+ <li class="first">
+ ${h.link_to('%s %s (%s)'%(c.hg_app_user.name,c.hg_app_user.lastname,c.hg_app_user.username),h.url('edit_user', id=c.hg_app_user.user_id))}
+ </li>
+ <li class="last highlight">${h.link_to(u'Logout',h.url('logout_home'))}</li>
+ </ul>
+ <!-- end user -->
+ <div id="header-inner">
+ <div id="home">
+ <a href="${h.url('hg_home')}"></a>
+ </div>
+ <!-- logo -->
+ <div id="logo">
+ <h1><a href="${h.url('hg_home')}">${c.hg_app_name}</a></h1>
+ </div>
+ <!-- end logo -->
+ <!-- quick menu -->
+ ${self.page_nav()}
+ <!-- end quick -->
+ <div class="corner tl"></div>
+ <div class="corner tr"></div>
+ </div>
+ </div>
+ <!-- end header -->
+
+ <!-- CONTENT -->
+ <div id="content">
+ <div class="flash_msg">
+ <% messages = h.flash.pop_messages() %>
+ % if messages:
+ <ul id="flash-messages">
+ % for message in messages:
+ <li class="${message.category}_msg">${message}</li>
+ % endfor
+ </ul>
+ % endif
+ </div>
+ <div id="main">
+ ${next.main()}
+ </div>
+ </div>
+ <!-- END CONTENT -->
-<body class="mainbody">
-<div id="container">
- <div class="page-header">
- <h1 class="breadcrumbs">${next.breadcrumbs()}</h1>
- ${self.page_nav()}
- <div class="flash_msg">
- <% messages = h.flash.pop_messages() %>
- % if messages:
- <ul id="flash-messages">
- % for message in messages:
- <li class="${message.category}_msg">${message}</li>
- % endfor
- </ul>
- % endif
- </div>
- <div id="main">
- ${next.main()}
- <script type="text/javascript">${h.tooltip.activate()}</script>
- </div>
- <div class="page-footer">
- Hg App ${c.hg_app_version} &copy; 2010 by Marcin Kuzminski
- </div>
-
- <div id="powered-by">
- <p>
- <a href="http://mercurial.selenic.com/" title="Mercurial">
- <img src="/images/hglogo.png" width="75" height="90" alt="mercurial"/></a>
- </p>
- </div>
-
- <div id="corner-top-left"></div>
- <div id="corner-top-right"></div>
- <div id="corner-bottom-left"></div>
- <div id="corner-bottom-right"></div>
-
-</div>
+ <!-- footer -->
+ <div id="footer">
+ <p>Hg App ${c.hg_app_version} &copy; 2010 by Marcin Kuzminski</p>
+ <script type="text/javascript">${h.tooltip.activate()}</script>
+ </div>
+ <!-- end footer -->
</body>
+
</html>
### MAKO DEFS ###
-
<%def name="page_nav()">
${self.menu()}
- ${self.submenu()}
</%def>
-<%def name="menu(current)">
-<%
-def is_current(selected):
- if selected == current:
- return "class='current'"
-%>
+<%def name="menu(current=None)">
+ <%
+ def is_current(selected):
+ if selected == current:
+ return "class='current'"
+ %>
%if current not in ['home','admin']:
- ##regular menu
- <script type="text/javascript">
- YAHOO.util.Event.onDOMReady(function(){
- YAHOO.util.Event.addListener('repo_switcher','click',function(){
- if(YAHOO.util.Dom.hasClass('repo_switcher','selected')){
- YAHOO.util.Dom.setStyle('switch_repos','display','none');
- YAHOO.util.Dom.setStyle('repo_switcher','background','');
- YAHOO.util.Dom.removeClass('repo_switcher','selected');
- YAHOO.util.Dom.get('repo_switcher').removeAttribute('style');
- }
- else{
- YAHOO.util.Dom.setStyle('switch_repos','display','');
- YAHOO.util.Dom.setStyle('repo_switcher','background','#FFFFFF');
- YAHOO.util.Dom.setStyle('repo_switcher','color','#556CB5');
- YAHOO.util.Dom.addClass('repo_switcher','selected');
- }
- });
- YAHOO.util.Event.addListener('repos_list','change',function(e){
- var wa = YAHOO.util.Dom.get('repos_list').value;
-
- var url = "${h.url('summary_home',repo_name='__REPLACE__')}".replace('__REPLACE__',wa);
- window.location = url;
- })
- });
- </script>
- <ul class="page-nav">
+ <script type="text/javascript">
+ YAHOO.util.Event.onDOMReady(function(){
+ YAHOO.util.Event.addListener('repo_switcher','click',function(){
+ if(YAHOO.util.Dom.hasClass('repo_switcher','selected')){
+ YAHOO.util.Dom.setStyle('switch_repos','display','none');
+ YAHOO.util.Dom.setStyle('repo_switcher','background','');
+ YAHOO.util.Dom.removeClass('repo_switcher','selected');
+ YAHOO.util.Dom.get('repo_switcher').removeAttribute('style');
+ }
+ else{
+ YAHOO.util.Dom.setStyle('switch_repos','display','');
+ //YAHOO.util.Dom.setStyle('repo_switcher','background','#FFFFFF');
+ //YAHOO.util.Dom.setStyle('repo_switcher','color','#556CB5');
+ YAHOO.util.Dom.addClass('repo_switcher','selected');
+ }
+ });
+ YAHOO.util.Event.addListener('repos_list','change',function(e){
+ var wa = YAHOO.util.Dom.get('repos_list').value;
+
+ var url = "${h.url('summary_home',repo_name='__REPLACE__')}".replace('__REPLACE__',wa);
+ window.location = url;
+ })
+ });
+ </script>
+
+ ##REGULAR MENU
+ <ul id="quick">
+ <!-- repo switcher -->
<li>
- <a id="repo_switcher" title="${_('Switch repository')}" href="#">&darr;</a>
- <div id="switch_repos" style="display:none;position: absolute;height: 25px">
+ <a id="repo_switcher" title="${_('Switch repository')}" href="#">
+ <span class="icon">
+ <img src="/images/icons/database.png" alt="${_('Products')}" />
+ </span>
+ <span>&darr;</span>
+ </a>
+ <div id="switch_repos" style="display:none;position: absolute;height: 25px;z-index: 1">
<select id="repos_list" size="=10" style="min-width: 150px">
%for repo in sorted(x.name.lower() for x in c.cached_repo_list.values()):
<option value="${repo}">${repo}</option>
@@ -100,65 +123,120 @@ def is_current(selected):
</select>
</div>
</li>
- <li ${is_current('summary')}>${h.link_to(_('summary'),h.url('summary_home',repo_name=c.repo_name))}</li>
- <li ${is_current('shortlog')}>${h.link_to(_('shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}</li>
- <li ${is_current('changelog')}>${h.link_to(_('changelog'),h.url('changelog_home',repo_name=c.repo_name))}</li>
- <li ${is_current('branches')}>${h.link_to(_('branches'),h.url('branches_home',repo_name=c.repo_name))}</li>
- <li ${is_current('tags')}>${h.link_to(_('tags'),h.url('tags_home',repo_name=c.repo_name))}</li>
- <li ${is_current('files')}>${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name))}</li>
+
+ <li ${is_current('summary')}>
+ <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
+ <span class="icon">
+ <img src="/images/icons/clipboard_16.png" alt="${_('Summary')}" />
+ </span>
+ <span>${_('Summary')}</span>
+ </a>
+ </li>
+ <li ${is_current('shortlog')}>
+ <a title="${_('Shortlog')}" href="${h.url('shortlog_home',repo_name=c.repo_name)}">
+ <span class="icon">
+ <img src="/images/icons/application_double.png" alt="${_('Shortlog')}" />
+ </span>
+ <span>${_('Shortlog')}</span>
+ </a>
+ </li>
+ <li ${is_current('changelog')}>
+ <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
+ <span class="icon">
+ <img src="/images/icons/time.png" alt="${_('Changelog')}" />
+ </span>
+ <span>${_('Changelog')}</span>
+ </a>
+ </li>
+ <li ${is_current('branches')}>
+ <a title="${_('Branches')}" href="${h.url('branches_home',repo_name=c.repo_name)}">
+ <span class="icon">
+ <img src="/images/icons/arrow_branch.png" alt="${_('Branches')}" />
+ </span>
+ <span>${_('Branches')}</span>
+ </a>
+ </li>
+ <li ${is_current('tags')}>
+ <a title="${_('Tags')}" href="${h.url('tags_home',repo_name=c.repo_name)}">
+ <span class="icon">
+ <img src="/images/icons/tag_blue.png" alt="${_('Tags')}" />
+ </span>
+ <span>${_('Tags')}</span>
+ </a>
+ </li>
+ <li ${is_current('files')}>
+ <a title="${_('Files')}" href="${h.url('files_home',repo_name=c.repo_name)}">
+ <span class="icon">
+ <img src="/images/icons/file.png" alt="${_('Files')}" />
+ </span>
+ <span>${_('Files')}</span>
+ </a>
+ </li>
%if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
- <li ${is_current('settings')}>${h.link_to(_('settings'),h.url('repo_settings_home',repo_name=c.repo_name))}</li>
+ <li ${is_current('settings')}>
+ <a title="${_('Settings')}" href="${h.url('repo_settings_home',repo_name=c.repo_name)}">
+ <span class="icon">
+ <img src="/images/icons/cog_edit.png" alt="${_('Settings')}" />
+ </span>
+ <span>${_('Settings')}</span>
+ </a>
+ </li>
%endif
</ul>
%else:
- ##Root menu
- <ul class="page-nav">
- <li ${is_current('home')}>${h.link_to(_('Home'),h.url('/'))}</li>
+ ##ROOT MENU
+ <ul id="quick">
+ <li>
+ <a title="${_('Home')}" href="${h.url('hg_home')}">
+ <span class="icon">
+ <img src="/images/icons/home_16.png" alt="${_('Home')}" />
+ </span>
+ <span>${_('Home')}</span>
+ </a>
+ </li>
+
%if h.HasPermissionAll('hg.admin')('access admin main page'):
- <li ${is_current('admin')}>${h.link_to(_('Admin'),h.url('admin_home'))}</li>
+ <li ${is_current('admin')}>
+ <a title="${_('Admin')}" href="${h.url('admin_home')}">
+ <span class="icon">
+ <img src="/images/icons/cog_edit.png" alt="${_('Admin')}" />
+ </span>
+ <span>${_('Admin')}</span>
+ </a>
+ <ul>
+ <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
+ <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
+ ##<li>${h.link_to(_('permissions'),h.url('permissions'),class_='permissions')}</li>
+ <li>${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
+ </ul>
+ </li>
%endif
- <li class="logout">${h.link_to(u'Logout',h.url('logout_home'))}</li>
+
</ul>
%endif
- </div>
-</%def>
-<%def name="submenu(current=None)">
- <%
- def is_current(selected):
- if selected == current:
- return "class='current_submenu'"
- %>
- %if current != None:
- <div>
- <ul class="submenu">
- <li ${is_current('repos')}>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
- <li ${is_current('users')}>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
- ##commented<li ${is_current('permissions')}>${h.link_to(_('permissions'),h.url('permissions'),class_='permissions')}</li>
- <li ${is_current('settings')}>${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
- </ul>
- </div>
- %endif
</%def>
<%def name="css()">
-<link rel="stylesheet" href="/css/monoblue_custom.css" type="text/css" />
+<link rel="stylesheet" type="text/css" href="/css/reset.css" />
+<link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" />
+<link rel="stylesheet" type="text/css" href="/css/style_full.css" />
+<link id="color" rel="stylesheet" type="text/css" href="/css/colors/blue.css" />
+<link rel="stylesheet" type="text/css" href="/css/pygments.css" />
+<link rel="stylesheet" type="text/css" href="/css/diff.css" />
</%def>
<%def name="js()">
<script type="text/javascript" src="/js/yui/utilities/utilities.js"></script>
+<!--[if IE]><script language="javascript" type="text/javascript" src="/js/excanvas.min.js"></script><![endif]-->
<script type="text/javascript" src="/js/yui/container/container-min.js"></script>
<script type="text/javascript" src="/js/yui/datasource/datasource-min.js"></script>
<script type="text/javascript" src="/js/yui/autocomplete/autocomplete-min.js"></script>
+<script type="text/javascript" src="/js/yui.flot.js"></script>
</%def>
-<!-- DEFINITION OF FORM ERROR FETCHER -->
-<%def name="get_form_error(element)">
- %if hasattr(c,'form_errors') and type(c.form_errors) == dict:
- %if c.form_errors.get(element,False):
- <span class="error-message">
- ${c.form_errors.get(element,'')}
- </span>
- %endif
- %endif
+<%def name="breadcrumbs()">
+ <div class="breadcrumbs">
+ ${self.breadcrumbs_links()}
+ </div>
</%def> \ No newline at end of file
diff --git a/pylons_app/templates/branches/branches.html b/pylons_app/templates/branches/branches.html
index 024bd0b0..14357182 100644
--- a/pylons_app/templates/branches/branches.html
+++ b/pylons_app/templates/branches/branches.html
@@ -1,18 +1,31 @@
+## -*- coding: utf-8 -*-
<%inherit file="/base/base.html"/>
+
<%def name="title()">
- ${_('Branches')}
+ ${_('Administration')}
</%def>
-<%def name="breadcrumbs()">
+
+<%def name="breadcrumbs_links()">
${h.link_to(u'Home',h.url('/'))}
- /
+ &raquo;
${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
- /
+ &raquo;
${_('branches')}
</%def>
+
<%def name="page_nav()">
- ${self.menu('branches')}
+ ${self.menu('branches')}
</%def>
+
<%def name="main()">
- <h2 class="no-link no-border">${_('Branches')}</h2>
- <%include file='branches_data.html'/>
-</%def> \ No newline at end of file
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <!-- end box / title -->
+ <div class="table">
+ <%include file='branches_data.html'/>
+ </div>
+</div>
+</%def> \ No newline at end of file
diff --git a/pylons_app/templates/branches/branches_data.html b/pylons_app/templates/branches/branches_data.html
index b2932b5c..a3585001 100644
--- a/pylons_app/templates/branches/branches_data.html
+++ b/pylons_app/templates/branches/branches_data.html
@@ -1,11 +1,11 @@
% if c.repo_branches:
<table class="table_disp">
- <tr class="header">
- <td>${_('date')}</td>
- <td>${_('revision')}</td>
- <td>${_('name')}</td>
- <td>${_('links')}</td>
- </tr>
+ <tr>
+ <th class="left">${_('date')}</th>
+ <th class="left">${_('revision')}</th>
+ <th class="left">${_('name')}</th>
+ <th class="left">${_('links')}</th>
+ </tr>
%for cnt,branch in enumerate(c.repo_branches.items()):
<tr class="parity${cnt%2}">
<td>${h.age(branch[1]._ctx.date())}</td>
diff --git a/pylons_app/templates/changelog/changelog.html b/pylons_app/templates/changelog/changelog.html
index aa2e7d40..7ac1526c 100644
--- a/pylons_app/templates/changelog/changelog.html
+++ b/pylons_app/templates/changelog/changelog.html
@@ -3,106 +3,107 @@
<%def name="title()">
${_('Changelog - %s') % c.repo_name}
</%def>
-<%def name="breadcrumbs()">
+
+<%def name="breadcrumbs_links()">
${h.link_to(u'Home',h.url('/'))}
- /
- ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))}
- /
- ${_('changelog')}
+ &raquo;
+ ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
+ &raquo;
+ ${_('Changelog')} - ${_('showing ')} ${c.size if c.size <= c.total_cs else c.total_cs} ${_('out of')} ${c.total_cs} ${_('revisions')}
</%def>
+
<%def name="page_nav()">
${self.menu('changelog')}
</%def>
<%def name="main()">
-
- <h2 class="no-link no-border">${_('Changelog')} - ${_('showing ')}
- ${c.size if c.size <= c.total_cs else c.total_cs}
- ${_('out of')} ${c.total_cs} ${_('revisions')}
- </h2>
- <noscript>${_('The revision graph only works with JavaScript-enabled browsers.')}</noscript>
-% if c.pagination:
-
-<div id="graph">
- <div id="graph_nodes">
- <canvas id="graph_canvas"></canvas>
- </div>
- <div id="graph_content">
- <div class="container_header">
- ${h.form(h.url.current(),method='get')}
- <div>
- <span>${_('Show')}: </span>
- <span>${h.text('size',size=2,value=c.size)}</span>
- <span>${_('revisions')}</span>
- ${h.submit('set',_('set'))}
- </div>
- ${h.end_form()}
- </div>
- %for cnt,cs in enumerate(c.pagination):
- <div id="chg_${cnt+1}" class="container">
- <div class="left">
- <div class="date">${_('commit')} ${cs.revision}: ${cs.raw_id}@${cs.date}</div>
- <span class="logtags">
- <span class="branchtag">${cs.branch}</span>
- %for tag in cs.tags:
- <span class="tagtag">${tag}</span>
- %endfor
- </span>
- <div class="author">${cs.author}</div>
- <div class="message">
- ${h.link_to(h.wrap_paragraphs(cs.message),
- h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <div class="table">
+ % if c.pagination:
+ <div id="graph">
+ <div id="graph_nodes">
+ <canvas id="graph_canvas"></canvas>
</div>
- </div>
- <div class="right">
- <div class="changes">
- <span class="removed" title="${_('removed')}">${len(cs.removed)}</span>
- <span class="changed" title="${_('changed')}">${len(cs.changed)}</span>
- <span class="added" title="${_('added')}">${len(cs.added)}</span>
- </div>
- %if len(cs.parents)>1:
- <div class="merge">
- ${_('merge')}<img alt="merge" src="/images/icons/arrow_join.png"/>
- </div>
- %endif
- %for p_cs in reversed(cs.parents):
- <div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(p_cs.raw_id,
- h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}
+ <div id="graph_content">
+ <div class="container_header">
+
+ ${h.form(h.url.current(),method='get')}
+ <div class="info_box">
+ <span>${_('Show')}:</span>
+ ${h.text('size',size=1,value=c.size)}
+ <span>${_('revisions')}</span>
+ ${h.submit('set',_('set'))}
+ </div>
+ ${h.end_form()}
+
+ </div>
+ %for cnt,cs in enumerate(c.pagination):
+ <div id="chg_${cnt+1}" class="container">
+ <div class="left">
+ <div class="date">${_('commit')} ${cs.revision}: ${cs.raw_id}@${cs.date}</div>
+ <span class="logtags">
+ <span class="branchtag">${cs.branch}</span>
+ %for tag in cs.tags:
+ <span class="tagtag">${tag}</span>
+ %endfor
+ </span>
+ <div class="author">${cs.author}</div>
+ <div class="message">
+ ${h.link_to(h.wrap_paragraphs(cs.message),
+ h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}
</div>
- %endfor
- </div>
- </div>
-
- %endfor
- </div>
-</div>
-<script type="text/javascript" src="/js/graph.js"></script>
-
-<script type="text/javascript">
-YAHOO.util.Event.onDOMReady(function(){
- function set_canvas() {
- var c = document.getElementById('graph_nodes');
- var t = document.getElementById('graph_content');
- canvas = document.getElementById('graph_canvas');
- var div_h = t.clientHeight;
- c.style.height=div_h+'px';
- canvas.setAttribute('height',div_h);
- canvas.setAttribute('width',160);
- };
-
- set_canvas();
-
- var jsdata = ${c.jsdata|n};
- var r = new BranchRenderer();
- r.render(jsdata);
-
-});
-</script>
-
-<div>
- <h2>${c.pagination.pager('$link_previous ~2~ $link_next')}</h2>
-</div>
-%else:
- ${_('There are no changes yet')}
-%endif
-</%def> \ No newline at end of file
+ </div>
+ <div class="right">
+ <div class="changes">
+ <span class="removed" title="${_('removed')}">${len(cs.removed)}</span>
+ <span class="changed" title="${_('changed')}">${len(cs.changed)}</span>
+ <span class="added" title="${_('added')}">${len(cs.added)}</span>
+ </div>
+ %if len(cs.parents)>1:
+ <div class="merge">
+ ${_('merge')}<img alt="merge" src="/images/icons/arrow_join.png"/>
+ </div>
+ %endif
+ %for p_cs in reversed(cs.parents):
+ <div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(p_cs.raw_id,
+ h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}
+ </div>
+ %endfor
+ </div>
+ </div>
+
+ %endfor
+ <div class="pagination-wh pagination-left">
+ ${c.pagination.pager('$link_previous ~2~ $link_next')}
+ </div>
+ </div>
+ </div>
+
+ <script type="text/javascript" src="/js/graph.js"></script>
+ <script type="text/javascript">
+ YAHOO.util.Event.onDOMReady(function(){
+ function set_canvas() {
+ var c = document.getElementById('graph_nodes');
+ var t = document.getElementById('graph_content');
+ canvas = document.getElementById('graph_canvas');
+ var div_h = t.clientHeight;
+ c.style.height=div_h+'px';
+ canvas.setAttribute('height',div_h);
+ canvas.setAttribute('width',160);
+ };
+ set_canvas();
+ var jsdata = ${c.jsdata|n};
+ var r = new BranchRenderer();
+ r.render(jsdata);
+ });
+ </script>
+ %else:
+ ${_('There are no changes yet')}
+ %endif
+ </div>
+</div>
+</%def> \ No newline at end of file
diff --git a/pylons_app/templates/changeset/changeset.html b/pylons_app/templates/changeset/changeset.html
index 266ee3e5..92da0dc8 100644
--- a/pylons_app/templates/changeset/changeset.html
+++ b/pylons_app/templates/changeset/changeset.html
@@ -3,23 +3,26 @@
<%def name="title()">
${_('Changeset')}
</%def>
-<%def name="breadcrumbs()">
+
+<%def name="breadcrumbs_links()">
${h.link_to(u'Home',h.url('/'))}
- /
- ${h.link_to(c.repo_name,h.url('changeset_home',repo_name=c.repo_name))}
- /
- ${_('changeset')}
+ &raquo;
+ ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
+ &raquo;
+ ${_('Changeset')} - r${c.changeset.revision}:${c.changeset.raw_id}
</%def>
+
<%def name="page_nav()">
${self.menu('changelog')}
</%def>
-<%def name="css()">
-<link rel="stylesheet" href="/css/monoblue_custom.css" type="text/css" />
-<link rel="stylesheet" href="/css/diff.css" type="text/css" />
-</%def>
+
<%def name="main()">
- <h2 class="no-link no-border">${_('Changeset')} - r${c.changeset.revision}:${c.changeset.raw_id}</h2>
-
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <div class="table">
<div id="changeset_content">
<div class="container">
<div class="left">
@@ -84,6 +87,8 @@
</div>
</div>
%endif
- %endfor
-
-</%def> \ No newline at end of file
+ %endfor
+ </div>
+</div>
+
+</%def> \ No newline at end of file
diff --git a/pylons_app/templates/errors/error_document.html b/pylons_app/templates/errors/error_document.html
index 40fb3f49..2578a13f 100755
--- a/pylons_app/templates/errors/error_document.html
+++ b/pylons_app/templates/errors/error_document.html
@@ -1,46 +1,53 @@
## -*- coding: utf-8 -*-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
-<head>
- <link rel="icon" href="/images/hgicon.png" type="image/png" />
- <title>Error - ${c.error_message}</title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-
- %if c.redirect_time:
- <meta http-equiv="refresh" content="${c.redirect_time}; url=${c.url_redirect}"/>
- %endif
+ <head>
+ <title>Error - ${c.error_message}</title>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+ %if c.redirect_time:
+ <meta http-equiv="refresh" content="${c.redirect_time}; url=${c.url_redirect}"/>
+ %endif
+ <link rel="icon" href="/images/hgicon.png" type="image/png" />
+ <meta name="robots" content="index, nofollow"/>
+
+ <!-- stylesheets -->
+ <link rel="stylesheet" type="text/css" href="/css/reset.css" />
+ <link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" />
+ <link id="color" rel="stylesheet" type="text/css" href="/css/colors/blue.css" />
+ <style type="text/css">
+ #main_div{
+ border: 0px solid #000;
+ width: 500px;
+ margin: auto;
+ text-align: center;
+ margin-top: 200px;
+ font-size: 1.8em;
+ }
+ .error_message{
+ text-align: center;
+ color:red;
+ font-size: 1.8em;
+ }
+ </style>
+ </head>
+ <body>
+
+ <div id="login">
+ <div class="table">
+ <div id="main_div">
+ <h1 class="error_message">${c.error_message}</h1>
+
+ <p>${c.error_explanation}</p>
+ %if c.redirect_time:
+ <p>${_('You will be redirected to %s in %s seconds') % (c.redirect_module,c.redirect_time)}</p>
+ %endif
+
+ </div>
+ </div>
+ <!-- end login -->
+ </div>
+ </body>
- <style type="text/css">
-
- body {
- font-family: sans-serif;
- }
- #main_div{
- border: 0px solid #000;
- width: 500px;
- margin: auto;
- text-align: center;
- margin-top: 200px;
- }
- .error_message{
- text-align: center;
- color:red;
- }
- </style>
-</head>
-
-<body>
- <div id="main_div">
- <h1 class="error_message">${c.error_message}</h1>
-
- <p>${c.error_explanation}</p>
- %if c.redirect_time:
- <p>${_('You will be redirected to %s in %s seconds') % (c.redirect_module,c.redirect_time)}</p>
- %endif
-
- </div>
-</body>
</html>
-
diff --git a/pylons_app/templates/files/file_diff.html b/pylons_app/templates/files/file_diff.html
index 30d661cd..b5e3de69 100644
--- a/pylons_app/templates/files/file_diff.html
+++ b/pylons_app/templates/files/file_diff.html
@@ -3,41 +3,47 @@
<%def name="title()">
${_('Repository managment')}
</%def>
-<%def name="breadcrumbs()">
+<%def name="breadcrumbs_links()">
${h.link_to(u'Home',h.url('/'))}
- /
- ${h.link_to(c.repo_name,h.url('files_home',repo_name=c.repo_name))}
- /
- ${_('files')}
+ &raquo;
+ ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
+ &raquo;
+ ${'%s: %s %s %s' % (_('File diff'),c.diff2,'&rarr;',c.diff1)|n}
</%def>
+
<%def name="page_nav()">
${self.menu('files')}
</%def>
-<%def name="css()">
-<link rel="stylesheet" href="/css/monoblue_custom.css" type="text/css" />
-<link rel="stylesheet" href="/css/diff.css" type="text/css" />
-</%def>
<%def name="main()">
- <h2 class="no-link no-border">${'%s: %s %s %s' % (_('File diff'),c.diff2,'&rarr;',c.diff1)|n}</h2>
-<div id="body" class="diffblock">
- <div class="code-header">
- <div>
- <span>${h.link_to(c.f_path,h.url('files_home',repo_name=c.repo_name,
- revision=c.diff2.split(':')[1],f_path=c.f_path))}</span>
- &raquo; <span style="font-size:77%">${h.link_to(_('diff'),
- h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='diff'))}</span>
- &raquo; <span style="font-size:77%">${h.link_to(_('raw diff'),
- h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='raw'))}</span>
- &raquo; <span style="font-size:77%">${h.link_to(_('download diff'),
- h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='download'))}</span>
- </div>
- </div>
- <div class="code-body">
- %if c.no_changes:
- ${_('No changes')}
- %else:
- ${c.cur_diff|n}
- %endif
- </div>
-</div>
-</%def> \ No newline at end of file
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <div class="table">
+ <div id="body" class="diffblock">
+ <div class="code-header">
+ <div>
+ <span>${h.link_to(c.f_path,h.url('files_home',repo_name=c.repo_name,
+ revision=c.diff2.split(':')[1],f_path=c.f_path))}</span>
+ &raquo; <span style="font-size:77%">${h.link_to(_('diff'),
+ h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='diff'))}</span>
+ &raquo; <span style="font-size:77%">${h.link_to(_('raw diff'),
+ h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='raw'))}</span>
+ &raquo; <span style="font-size:77%">${h.link_to(_('download diff'),
+ h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='download'))}</span>
+ </div>
+ </div>
+ <div class="code-body">
+ %if c.no_changes:
+ ${_('No changes')}
+ %else:
+ ${c.cur_diff|n}
+ %endif
+ </div>
+ </div>
+ </div>
+</div>
+</%def>
+
+ \ No newline at end of file
diff --git a/pylons_app/templates/files/files.html b/pylons_app/templates/files/files.html
index 7e54238f..77d2b2cb 100644
--- a/pylons_app/templates/files/files.html
+++ b/pylons_app/templates/files/files.html
@@ -1,38 +1,48 @@
<%inherit file="/base/base.html"/>
<%def name="title()">
- ${_('Repository managment')}
+ ${_('files')}
</%def>
-<%def name="breadcrumbs()">
+
+<%def name="breadcrumbs_links()">
${h.link_to(u'Home',h.url('/'))}
- /
+ &raquo;
${h.link_to(c.repo_name,h.url('files_home',repo_name=c.repo_name))}
- /
+ &raquo;
${_('files')}
+ %if c.files_list:
+ @ R${c.rev_nr}:${c.cur_rev}
+ %endif
</%def>
+
<%def name="page_nav()">
${self.menu('files')}
</%def>
-<%def name="css()">
-<link rel="stylesheet" href="/css/monoblue_custom.css" type="text/css" />
-<link rel="stylesheet" href="/css/pygments.css" type="text/css" />
-</%def>
+
<%def name="main()">
- <h2 class="no-link no-border">${_('Files')}</h2>
- <div id="files_data">
- %if c.files_list:
- <h2>${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cur_rev,c.files_list.path)}</h2>
- %if c.files_list.is_dir():
- <%include file='files_browser.html'/>
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <div class="table">
+ <div id="files_data">
+ %if c.files_list:
+ <h2>${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cur_rev,c.files_list.path)}</h2>
+ %if c.files_list.is_dir():
+ <%include file='files_browser.html'/>
+ %else:
+ <%include file='files_source.html'/>
+ %endif
%else:
- <%include file='files_source.html'/>
- %endif
- %else:
- <h2>
- <a href="#" onClick="javascript:parent.history.back();" target="main">${_('Go back')}</a>
- ${_('No files at given path')}: "${c.f_path or "/"}"
- </h2>
- %endif
-
- </div>
+ <h2>
+ <a href="#" onClick="javascript:parent.history.back();" target="main">${_('Go back')}</a>
+ ${_('No files at given path')}: "${c.f_path or "/"}"
+ </h2>
+ %endif
+
+ </div>
+ </div>
+</div>
+
</%def> \ No newline at end of file
diff --git a/pylons_app/templates/files/files_annotate.html b/pylons_app/templates/files/files_annotate.html
index 263f298c..737e16a3 100644
--- a/pylons_app/templates/files/files_annotate.html
+++ b/pylons_app/templates/files/files_annotate.html
@@ -3,44 +3,49 @@
<%def name="title()">
${_('File annotate')}
</%def>
-<%def name="breadcrumbs()">
+
+<%def name="breadcrumbs_links()">
${h.link_to(u'Home',h.url('/'))}
- /
- ${h.link_to(c.repo_name,h.url('files_home',repo_name=c.repo_name))}
- /
- ${_('files')}
+ &raquo;
+ ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
+ &raquo;
+ ${_('annotate')}
</%def>
+
<%def name="page_nav()">
${self.menu('files')}
</%def>
-<%def name="css()">
- <link rel="stylesheet" href="/css/monoblue_custom.css" type="text/css" />
- <link rel="stylesheet" href="/css/pygments.css" type="text/css" />
-</%def>
<%def name="main()">
- <h2 class="no-link no-border">${_('Annotate')}</h2>
- <div id="files_data">
- <h2>${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cur_rev,c.file.path)}</h2>
- <dl class="overview">
- <dt>${_('Revision')}</dt>
- <dd>r${c.file.last_changeset.revision}:${c.file.last_changeset._short}</dd>
- <dt>${_('Size')}</dt>
- <dd>${h.format_byte_size(c.file.size,binary=True)}</dd>
- <dt>${_('Options')}</dt>
- <dd>${h.link_to(_('show source'),
- h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.f_path))}
- / ${h.link_to(_('download as raw'),
- h.url('files_raw_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.f_path))}
- </dd>
- </dl>
- <div id="body" class="codeblock">
- <div class="code-header">
- <div class="revision">${c.file.name}@r${c.file.last_changeset.revision}:${c.file.last_changeset._short}</div>
- <div class="commit" style="font-size:70%">"${c.file_msg}"</div>
- </div>
- <div class="code-body">
- ${h.pygmentize_annotation(c.file,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")}
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <div class="table">
+ <div id="files_data">
+ <h2>${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cur_rev,c.file.path)}</h2>
+ <dl class="overview">
+ <dt>${_('Revision')}</dt>
+ <dd>r${c.file.last_changeset.revision}:${c.file.last_changeset._short}</dd>
+ <dt>${_('Size')}</dt>
+ <dd>${h.format_byte_size(c.file.size,binary=True)}</dd>
+ <dt>${_('Options')}</dt>
+ <dd>${h.link_to(_('show source'),
+ h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.f_path))}
+ / ${h.link_to(_('download as raw'),
+ h.url('files_raw_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.f_path))}
+ </dd>
+ </dl>
+ <div id="body" class="codeblock">
+ <div class="code-header">
+ <div class="revision">${c.file.name}@r${c.file.last_changeset.revision}:${c.file.last_changeset._short}</div>
+ <div class="commit" style="font-size:70%">"${c.file_msg}"</div>
+ </div>
+ <div class="code-body">
+ ${h.pygmentize_annotation(c.file,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")}
+ </div>
</div>
- </div>
- </div>
-</%def> \ No newline at end of file
+ </div>
+ </div>
+</div>
+</%def> \ No newline at end of file
diff --git a/pylons_app/templates/files/files_browser.html b/pylons_app/templates/files/files_browser.html
index 4b8fb3ea..f8803dbb 100644
--- a/pylons_app/templates/files/files_browser.html
+++ b/pylons_app/templates/files/files_browser.html
@@ -8,9 +8,13 @@
<div id="body" class="browserblock">
<div class="browser-header">
${h.form(h.url.current())}
- <span>${_('view')}@rev <a style="font-size: 1.3em" href="${c.url_prev}">&laquo;</a>${h.text('at_rev',value=c.rev_nr,size='5')}<a style="font-size: 1.3em" href="${c.url_next}">&raquo;</a></span>
- ${c.cur_rev}
- ${h.submit('view','view')}
+ <div class="info_box">
+ <span >${_('view')}@rev</span>
+ <a href="${c.url_prev}">&laquo;</a>
+ ${h.text('at_rev',value=c.rev_nr,size=3)}
+ <a href="${c.url_next}">&raquo;</a>
+ ${h.submit('view','view')}
+ </div>
${h.end_form()}
</div>
<div class="browser-body">
diff --git a/pylons_app/templates/files/files_source.html b/pylons_app/templates/files/files_source.html
index 8d1e923a..529cf15c 100644
--- a/pylons_app/templates/files/files_source.html
+++ b/pylons_app/templates/files/files_source.html
@@ -1,5 +1,5 @@
-<dl class="overview">
- <dt>${_('Revision')}</dt>
+<dl>
+ <dt>${_('Last revision')}</dt>
<dd>r${c.files_list.last_changeset.revision}:${c.files_list.last_changeset._short}</dd>
<dt>${_('Size')}</dt>
<dd>${h.format_byte_size(c.files_list.size,binary=True)}</dd>
@@ -14,11 +14,12 @@
${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='GET')}
${h.hidden('diff2',c.files_list.last_changeset._short)}
${h.select('diff1','',c.file_history)}
- ${h.submit('diff','diff')}
+ ${h.submit('diff','diff',class_="ui-button ui-widget ui-state-default ui-corner-all")}
${h.end_form()}
</dd>
-
-</dl>
+</dl>
+
+
<div id="body" class="codeblock">
<div class="code-header">
<div class="revision">${c.files_list.name}@r${c.files_list.last_changeset.revision}:${c.files_list.last_changeset._short}</div>
diff --git a/pylons_app/templates/index.html b/pylons_app/templates/index.html
index 57f84bd0..905dc662 100644
--- a/pylons_app/templates/index.html
+++ b/pylons_app/templates/index.html
@@ -1,10 +1,10 @@
## -*- coding: utf-8 -*-
<%inherit file="base/base.html"/>
<%def name="title()">
- ${c.repos_prefix}
+ ${c.hg_app_name}
</%def>
<%def name="breadcrumbs()">
- ${c.repos_prefix}
+ ${c.hg_app_name}
</%def>
<%def name="page_nav()">
${self.menu('home')}
@@ -17,46 +17,61 @@
%else:
<span style="font-weight: bold">${name}</span>
%endif
- <a style="color:#FFF" href="?sort=${name_slug}">&darr;</a>
- <a style="color:#FFF" href="?sort=-${name_slug}">&uarr;</a>
+ <a href="?sort=${name_slug}">&darr;</a>
+ <a href="?sort=-${name_slug}">&uarr;</a>
</%def>
- <table class="table_disp">
- <tr class="header">
- <td>${get_sort(_('Name'))}</td>
- <td>${get_sort(_('Description'))}</td>
- <td>${get_sort(_('Last change'))}</td>
- <td>${get_sort(_('Tip'))}</td>
- <td>${get_sort(_('Contact'))}</td>
- <td>${_('RSS')}</td>
- <td>${_('Atom')}</td>
- </tr>
- %for cnt,repo in enumerate(c.repos_list):
- %if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(repo['name'],'main page check'):
-
- <tr class="parity${cnt%2}">
- <td>
- %if repo['repo'].dbrepo.private:
- <img alt="${_('private')}" src="/images/icons/lock.png">
- %else:
- <img alt="${_('public')}" src="/images/icons/lock_open.png">
- %endif
- ${h.link_to(repo['name'],
- h.url('summary_home',repo_name=repo['name']))}</td>
- <td title="${repo['description']}">${h.truncate(repo['description'],60)}</td>
- <td>${h.age(repo['last_change'])}</td>
- <td>${h.link_to_if(repo['rev']>=0,'r%s:%s' % (repo['rev'],repo['tip']),
- h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']),
- class_="tooltip",
- tooltip_title=h.tooltip(repo['last_msg']))}</td>
- <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
- <td>
- <a title="${_('Subscribe to %s rss feed')%repo['name']}" class="rss_logo" href="${h.url('rss_feed_home',repo_name=repo['name'])}"></a>
- </td>
- <td>
- <a title="${_('Subscribe to %s atom feed')%repo['name']}" class="atom_logo" href="${h.url('atom_feed_home',repo_name=repo['name'])}"></a>
- </td>
- </tr>
- %endif
- %endfor
- </table>
+
+
+
+ <div class="box">
+ <!-- box / title -->
+ <div class="title">
+ <h5>${_('Dashboard')}</h5>
+ </div>
+ <!-- end box / title -->
+ <div class="table">
+ <table>
+ <thead>
+ <tr>
+ <th class="left">${get_sort(_('Name'))}</th>
+ <th class="left">${get_sort(_('Description'))}</th>
+ <th class="left">${get_sort(_('Last change'))}</th>
+ <th class="left">${get_sort(_('Tip'))}</th>
+ <th class="left">${get_sort(_('Contact'))}</th>
+ <th class="left">${_('RSS')}</th>
+ <th class="left">${_('Atom')}</th>
+ </tr>
+ </thead>
+ <tbody>
+ %for cnt,repo in enumerate(c.repos_list):
+ %if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(repo['name'],'main page check'):
+ <tr class="parity${cnt%2}">
+ <td>
+ %if repo['repo'].dbrepo.private:
+ <img alt="${_('private')}" src="/images/icons/lock.png"/>
+ %else:
+ <img alt="${_('public')}" src="/images/icons/lock_open.png"/>
+ %endif
+ ${h.link_to(repo['name'],
+ h.url('summary_home',repo_name=repo['name']))}</td>
+ <td title="${repo['description']}">${h.truncate(repo['description'],60)}</td>
+ <td>${h.age(repo['last_change'])}</td>
+ <td>${h.link_to_if(repo['rev']>=0,'r%s:%s' % (repo['rev'],repo['tip']),
+ h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']),
+ class_="tooltip",
+ tooltip_title=h.tooltip(repo['last_msg']))}</td>
+ <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
+ <td>
+ <a title="${_('Subscribe to %s rss feed')%repo['name']}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=repo['name'])}"></a>
+ </td>
+ <td>
+ <a title="${_('Subscribe to %s atom feed')%repo['name']}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=repo['name'])}"></a>
+ </td>
+ </tr>
+ %endif
+ %endfor
+ </tbody>
+ </table>
+ </div>
+ </div>
</%def>
diff --git a/pylons_app/templates/login.html b/pylons_app/templates/login.html
index 24d1dab2..7397fb43 100644
--- a/pylons_app/templates/login.html
+++ b/pylons_app/templates/login.html
@@ -1,38 +1,76 @@
## -*- coding: utf-8 -*-
-<%inherit file="base/base.html"/>
-<%def name="title()">
- ${c.repos_prefix}
-</%def>
-<%def name="breadcrumbs()">
- ${c.repos_prefix}
-</%def>
-<%def name="page_nav()">
- &nbsp;
- </div>
-</%def>
-<%def name="main()">
- <div>
- <br />
- <h2>${_('Login to hg app')}</h2>
- ${h.form(h.url.current())}
- <table>
- <tr>
- <td>${_('Username')}</td>
- <td>${h.text('username')}</td>
- <td>${self.get_form_error('username')}</td>
- </tr>
- <tr>
- <td>${_('Password')}</td>
- <td>${h.password('password')}</td>
- <td>${self.get_form_error('password')}</td>
- </tr>
- <tr>
- <td></td>
- <td>${h.submit('login','login')}</td>
- </tr>
- </table>
- ${h.end_form()}
- </div>
-</%def>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
+ <head>
+ <title>${_('Sign In to hg-app')}</title>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+ <link rel="icon" href="/images/hgicon.png" type="image/png" />
+ <meta name="robots" content="index, nofollow"/>
+
+ <!-- stylesheets -->
+ <link rel="stylesheet" type="text/css" href="/css/reset.css" />
+ <link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" />
+ <link id="color" rel="stylesheet" type="text/css" href="/css/colors/blue.css" />
+
+ <!-- scripts -->
+
+ </head>
+ <body>
+<div id="login">
+ <!-- login -->
+ <div class="title">
+ <h5>${_('Sign In to hg-app')}</h5>
+ <div class="corner tl"></div>
+ <div class="corner tr"></div>
+ </div>
+ <div class="inner">
+ ${h.form(h.url.current())}
+ <div class="form">
+ <!-- fields -->
+ <div class="fields">
+ <div class="field">
+ <div class="label">
+ <label for="username">${_('Username')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('username',class_='focus',size=40)}
+ </div>
+
+ </div>
+ <div class="field">
+ <div class="label">
+ <label for="password">${_('Password')}:</label>
+ </div>
+ <div class="input">
+ ${h.password('password',class_='focus',size=40)}
+ </div>
+
+ </div>
+ ##<div class="field">
+ ## <div class="checkbox">
+ ## <input type="checkbox" id="remember" name="remember" />
+ ## <label for="remember">Remember me</label>
+ ## </div>
+ ##</div>
+ <div class="buttons">
+ ${h.submit('sign_in','Sign In',class_="ui-button ui-widget ui-state-default ui-corner-all")}
+ </div>
+ </div>
+ <!-- end fields -->
+ <!-- links -->
+ <div class="links">
+ ${h.link_to(_('Forgot your password ?'),h.url('#'))}
+ /
+ ${h.link_to(_("Don't have an account ?"),h.url('register'))}
+ </div>
+
+ <!-- end links -->
+ </div>
+ ${h.end_form()}
+ </div>
+ <!-- end login -->
+ </div>
+ </body>
+</html>
diff --git a/pylons_app/templates/register.html b/pylons_app/templates/register.html
new file mode 100644
index 00000000..d0a73841
--- /dev/null
+++ b/pylons_app/templates/register.html
@@ -0,0 +1,88 @@
+## -*- coding: utf-8 -*-
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
+ <head>
+ <title>${_('Sign Up to hg-app')}</title>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+ <link rel="icon" href="/images/hgicon.png" type="image/png" />
+ <meta name="robots" content="index, nofollow"/>
+
+ <!-- stylesheets -->
+ <link rel="stylesheet" type="text/css" href="/css/reset.css" />
+ <link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" />
+ <link id="color" rel="stylesheet" type="text/css" href="/css/colors/blue.css" />
+
+ <!-- scripts -->
+
+ </head>
+ <body>
+ <div id="register">
+
+ <div class="title">
+ <h5>${_('Sign Up to hg-app')}</h5>
+ <div class="corner tl"></div>
+ <div class="corner tr"></div>
+ </div>
+ <div class="inner">
+ ${h.form(url('register'))}
+ <div class="form">
+ <!-- fields -->
+ <div class="fields">
+ <div class="field">
+ <div class="label">
+ <label for="username">${_('Username')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('username')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="password">${_('New Password')}:</label>
+ </div>
+ <div class="input">
+ ${h.password('password')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="name">${_('First Name')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('name')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="lastname">${_('Last Name')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('lastname')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="email">${_('Email')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('email')}
+ </div>
+ </div>
+
+ <div class="buttons">
+ <div class="nohighlight">
+ ${h.submit('sign_up','Sign Up',class_="ui-button ui-widget ui-state-default ui-corner-all")}
+ </div>
+ </div>
+ </div>
+ </div>
+ ${h.end_form()}
+ </div>
+ </div>
+ </body>
+</html>
+
diff --git a/pylons_app/templates/settings/repo_settings.html b/pylons_app/templates/settings/repo_settings.html
index 6faa84de..5b282571 100644
--- a/pylons_app/templates/settings/repo_settings.html
+++ b/pylons_app/templates/settings/repo_settings.html
@@ -2,239 +2,256 @@
<%inherit file="/base/base.html"/>
<%def name="title()">
- ${_('Repository settings')}
+ ${_('Repositories administration')}
</%def>
-<%def name="breadcrumbs()">
- ${h.link_to(u'Home',h.url('/'))}
- /
- ${h.link_to(c.repo_name,h.url('shortlog_home',repo_name=c.repo_name))}
- /
- ${_('settings')}
+
+<%def name="breadcrumbs_links()">
+ ${h.link_to(c.repo_info.repo_name,h.url('summary_home',repo_name=c.repo_info.repo_name))}
+ &raquo;
+ ${_('Settings')}
+
</%def>
<%def name="page_nav()">
- ${self.menu('settings')}
+ ${self.menu('settings')}
</%def>
<%def name="main()">
- <h2 class="no-link no-border">${_('Settings')}</h2>
- <div>
- ${h.form(url('repo_settings_update', repo_name=c.repo_info.repo_name),method='put')}
- <table>
- <tr>
- <td>${_('Name')}</td>
- <td>${h.text('repo_name',size="28")}</td>
- <td>${self.get_form_error('repo_name')}</td>
- </tr>
- <tr>
- <td>${_('Description')}</td>
- <td>${h.textarea('description',cols=32,rows=5)}</td>
- <td>${self.get_form_error('description')}</td>
- </tr>
- <tr>
- <td>${_('Private')}</td>
- <td>${h.checkbox('private',value="True")}</td>
- <td>${self.get_form_error('private')}</td>
- </tr>
- <tr>
- <td>${_('Permissions')}</td>
- <td>
- <table>
- <tr>
- <td>${_('none')}</td>
- <td>${_('read')}</td>
- <td>${_('write')}</td>
- <td>${_('admin')}</td>
- <td>${_('user')}</td>
- </tr>
-
- %for r2p in c.repo_info.repo2perm:
- %if r2p.user.username =='default' and c.repo_info.private:
- <tr>
- <td colspan="4">
- <span style="font-size: 0.8em">${_('disabled for private repository')}</span></td>
- <td>${r2p.user.username}</td>
- </tr>
- %else:
- <tr id=${id(r2p.user.username)}>
- <td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
- <td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
- <td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
- <td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
- <td>${r2p.user.username}</td>
- <td>
- %if r2p.user.username !='default':
- <span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},${id(r2p.user.username)})">
- <script type="text/javascript">
- function ajaxAction(user_id,field_id){
- var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
- var callback = { success:function(o){
- YAHOO.util.Dom.get(String(field_id)).innerHTML = '<td colspan="6"></td>';
- }};
- var postData = '_method=delete&user_id='+user_id;
- var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
- };
- </script>
- </span>
- %endif
- </td>
- </tr>
- %endif
- %endfor
- <%
- if not hasattr(c,'form_errors'):
- d = 'display:none;'
- else:
- d=''
- %>
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ ${h.form(url('repo_settings_update', repo_name=c.repo_info.repo_name),method='put')}
+ <div class="form">
+ <!-- fields -->
+ <div class="fields">
+ <div class="field">
+ <div class="label">
+ <label for="input-medium">${_('Name')}:</label>
+ </div>
+ <div class="input">
+ ${h.text('repo_name')}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label label-textarea">
+ <label for="input-small">${_('Description')}:</label>
+ </div>
+ <div class="textarea text-area editor">
+ ${h.textarea('description',cols=23,rows=5)}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label label-checkbox">
+ <label for="input-small">${_('Private')}:</label>
+ </div>
+ <div class="checkboxes">
+ ${h.checkbox('private',value="True")}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label for="input-small">${_('Permissions')}:</label>
+ </div>
+ <div class="input">
+ <table id="permissions_manage">
+ <tr>
+ <td>${_('none')}</td>
+ <td>${_('read')}</td>
+ <td>${_('write')}</td>
+ <td>${_('admin')}</td>
+ <td>${_('user')}</td>
+ <td></td>
+ </tr>
+
+ %for r2p in c.repo_info.repo2perm:
+ %if r2p.user.username =='default' and c.repo_info.private:
+ <tr>
+ <td colspan="6">
+ <span class="private_repo_msg">
+ ${_('disabled for private repository')}
+ </span>
+ </td>
+ <td>${r2p.user.username}</td>
+ </tr>
+ %else:
+ <tr id="id${id(r2p.user.username)}">
+ <td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
+ <td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
+ <td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
+ <td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
+ <td>${r2p.user.username}</td>
+ <td>
+ %if r2p.user.username !='default':
+ <span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},'${'id%s'%id(r2p.user.username)}')">
+ <script type="text/javascript">
+ function ajaxAction(user_id,field_id){
+ var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
+ var callback = { success:function(o){
+ var tr = YAHOO.util.Dom.get(String(field_id));
+ tr.parentNode.removeChild(tr);}};
+ var postData = '_method=delete&user_id='+user_id;
+ var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);};
+ </script>
+ </span>
+ %endif
+ </td>
+ </tr>
+ %endif
+ %endfor
- <tr id="add_perm_input" style="${d}">
- <td>${h.radio('perm_new_user','repository.none')}</td>
- <td>${h.radio('perm_new_user','repository.read')}</td>
- <td>${h.radio('perm_new_user','repository.write')}</td>
- <td>${h.radio('perm_new_user','repository.admin')}</td>
- <td class='ac'>
- <div id="perm_ac">
- ${h.text('perm_new_user_name',class_='yui-ac-input')}
- <div id="perm_container"></div>
- </div>
- </td>
- <td>${self.get_form_error('perm_new_user_name')}</td>
- </tr>
- <tr>
- <td colspan="4">
- <span id="add_perm" class="add_icon" style="cursor: pointer;">
- ${_('Add another user')}
- </span>
- </td>
- </tr>
- </table>
- </td>
-
- </tr>
- <tr>
- <td></td>
- <td>${h.submit('update','update')}</td>
- </tr>
-
- </table>
- ${h.end_form()}
+
+ <tr id="add_perm_input">
+ <td>${h.radio('perm_new_user','repository.none')}</td>
+ <td>${h.radio('perm_new_user','repository.read')}</td>
+ <td>${h.radio('perm_new_user','repository.write')}</td>
+ <td>${h.radio('perm_new_user','repository.admin')}</td>
+ <td class='ac'>
+ <div class="perm_ac" id="perm_ac">
+ ${h.text('perm_new_user_name',class_='yui-ac-input')}
+ <div id="perm_container"></div>
+ </div>
+ </td>
+ <td></td>
+ </tr>
+ <tr>
+ <td colspan="6">
+ <span id="add_perm" class="add_icon" style="cursor: pointer;">
+ ${_('Add another user')}
+ </span>
+ </td>
+ </tr>
+ </table>
+ </div>
+
+ <div class="buttons">
+ ${h.submit('update','update',class_="ui-button ui-widget ui-state-default ui-corner-all")}
+ </div>
+ </div>
+ </div>
+ ${h.end_form()}
<script type="text/javascript">
- YAHOO.util.Event.onDOMReady(function(){
- var D = YAHOO.util.Dom;
- YAHOO.util.Event.addListener('add_perm','click',function(){
- D.setStyle('add_perm_input','display','');
- D.setStyle('add_perm','opacity','0.6');
- D.setStyle('add_perm','cursor','default');
- });
+ YAHOO.util.Event.onDOMReady(function(){
+ var D = YAHOO.util.Dom;
+ YAHOO.util.Event.addListener('add_perm','click',function(){
+ D.setStyle('add_perm_input','display','');
+ D.setStyle('add_perm','opacity','0.6');
+ D.setStyle('add_perm','cursor','default');
+ });
});
</script>
- <script type="text/javascript">
- YAHOO.example.FnMultipleFields = function(){
- var myContacts = ${c.users_array|n}
-
- // Define a custom search function for the DataSource
- var matchNames = function(sQuery) {
- // Case insensitive matching
- var query = sQuery.toLowerCase(),
- contact,
- i=0,
- l=myContacts.length,
- matches = [];
-
- // Match against each name of each contact
- for(; i<l; i++) {
- contact = myContacts[i];
- if((contact.fname.toLowerCase().indexOf(query) > -1) ||
- (contact.lname.toLowerCase().indexOf(query) > -1) ||
- (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
- matches[matches.length] = contact;
- }
- }
-
- return matches;
- };
-
- // Use a FunctionDataSource
- var oDS = new YAHOO.util.FunctionDataSource(matchNames);
- oDS.responseSchema = {
- fields: ["id", "fname", "lname", "nname"]
- }
-
- // Instantiate AutoComplete for perms
- var oAC_perms = new YAHOO.widget.AutoComplete("perm_new_user_name", "perm_container", oDS);
- oAC_perms.useShadow = false;
- oAC_perms.resultTypeList = false;
-
- // Instantiate AutoComplete for owner
- var oAC_owner = new YAHOO.widget.AutoComplete("user", "owner_container", oDS);
- oAC_owner.useShadow = false;
- oAC_owner.resultTypeList = false;
-
-
- // Custom formatter to highlight the matching letters
- var custom_formatter = function(oResultData, sQuery, sResultMatch) {
- var query = sQuery.toLowerCase(),
- fname = oResultData.fname,
- lname = oResultData.lname,
- nname = oResultData.nname || "", // Guard against null value
- query = sQuery.toLowerCase(),
- fnameMatchIndex = fname.toLowerCase().indexOf(query),
- lnameMatchIndex = lname.toLowerCase().indexOf(query),
- nnameMatchIndex = nname.toLowerCase().indexOf(query),
- displayfname, displaylname, displaynname;
-
- if(fnameMatchIndex > -1) {
- displayfname = highlightMatch(fname, query, fnameMatchIndex);
- }
- else {
- displayfname = fname;
- }
-
- if(lnameMatchIndex > -1) {
- displaylname = highlightMatch(lname, query, lnameMatchIndex);
- }
- else {
- displaylname = lname;
- }
-
- if(nnameMatchIndex > -1) {
- displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
- }
- else {
- displaynname = nname ? "(" + nname + ")" : "";
- }
-
- return displayfname + " " + displaylname + " " + displaynname;
-
- };
- oAC_perms.formatResult = custom_formatter;
- oAC_owner.formatResult = custom_formatter;
-
- // Helper function for the formatter
- var highlightMatch = function(full, snippet, matchindex) {
- return full.substring(0, matchindex) +
- "<span class='match'>" +
- full.substr(matchindex, snippet.length) +
- "</span>" +
- full.substring(matchindex + snippet.length);
- };
-
- var myHandler = function(sType, aArgs) {
- var myAC = aArgs[0]; // reference back to the AC instance
- var elLI = aArgs[1]; // reference to the selected LI element
- var oData = aArgs[2]; // object literal of selected item's result data
- myAC.getInputEl().value = oData.nname;
- };
+ <script type="text/javascript">
+ YAHOO.example.FnMultipleFields = function(){
+ var myContacts = ${c.users_array|n}
+
+ // Define a custom search function for the DataSource
+ var matchNames = function(sQuery) {
+ // Case insensitive matching
+ var query = sQuery.toLowerCase(),
+ contact,
+ i=0,
+ l=myContacts.length,
+ matches = [];
+
+ // Match against each name of each contact
+ for(; i<l; i++) {
+ contact = myContacts[i];
+ if((contact.fname.toLowerCase().indexOf(query) > -1) ||
+ (contact.lname.toLowerCase().indexOf(query) > -1) ||
+ (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
+ matches[matches.length] = contact;
+ }
+ }
+
+ return matches;
+ };
+
+ // Use a FunctionDataSource
+ var oDS = new YAHOO.util.FunctionDataSource(matchNames);
+ oDS.responseSchema = {
+ fields: ["id", "fname", "lname", "nname"]
+ }
+
+ // Instantiate AutoComplete for perms
+ var oAC_perms = new YAHOO.widget.AutoComplete("perm_new_user_name", "perm_container", oDS);
+ oAC_perms.useShadow = false;
+ oAC_perms.resultTypeList = false;
+
+ // Instantiate AutoComplete for owner
+ var oAC_owner = new YAHOO.widget.AutoComplete("user", "owner_container", oDS);
+ oAC_owner.useShadow = false;
+ oAC_owner.resultTypeList = false;
+
+
+ // Custom formatter to highlight the matching letters
+ var custom_formatter = function(oResultData, sQuery, sResultMatch) {
+ var query = sQuery.toLowerCase(),
+ fname = oResultData.fname,
+ lname = oResultData.lname,
+ nname = oResultData.nname || "", // Guard against null value
+ query = sQuery.toLowerCase(),
+ fnameMatchIndex = fname.toLowerCase().indexOf(query),
+ lnameMatchIndex = lname.toLowerCase().indexOf(query),
+ nnameMatchIndex = nname.toLowerCase().indexOf(query),
+ displayfname, displaylname, displaynname;
+
+ if(fnameMatchIndex > -1) {
+ displayfname = highlightMatch(fname, query, fnameMatchIndex);
+ }
+ else {
+ displayfname = fname;
+ }
+
+ if(lnameMatchIndex > -1) {
+ displaylname = highlightMatch(lname, query, lnameMatchIndex);
+ }
+ else {
+ displaylname = lname;
+ }
+
+ if(nnameMatchIndex > -1) {
+ displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
+ }
+ else {
+ displaynname = nname ? "(" + nname + ")" : "";
+ }
+
+ return displayfname + " " + displaylname + " " + displaynname;
+
+ };
+ oAC_perms.formatResult = custom_formatter;
+ oAC_owner.formatResult = custom_formatter;
+
+ // Helper function for the formatter
+ var highlightMatch = function(full, snippet, matchindex) {
+ return full.substring(0, matchindex) +
+ "<span class='match'>" +
+ full.substr(matchindex, snippet.length) +
+ "</span>" +
+ full.substring(matchindex + snippet.length);
+ };
+
+ var myHandler = function(sType, aArgs) {
+ var myAC = aArgs[0]; // reference back to the AC instance
+ var elLI = aArgs[1]; // reference to the selected LI element
+ var oData = aArgs[2]; // object literal of selected item's result data
+ myAC.getInputEl().value = oData.nname;
+ };
- oAC_perms.itemSelectEvent.subscribe(myHandler);
- oAC_owner.itemSelectEvent.subscribe(myHandler);
-
- return {
- oDS: oDS,
- oAC_perms: oAC_perms,
- oAC_owner: oAC_owner,
- };
- }();
-
- </script>
- </div>
-</%def>
+ oAC_perms.itemSelectEvent.subscribe(myHandler);
+ //oAC_owner.itemSelectEvent.subscribe(myHandler);
+
+ return {
+ oDS: oDS,
+ oAC_perms: oAC_perms,
+ oAC_owner: oAC_owner,
+ };
+ }();
+
+ </script>
+</div>
+</%def>
+
+
diff --git a/pylons_app/templates/shortlog/shortlog.html b/pylons_app/templates/shortlog/shortlog.html
index 4bc18300..361c56ba 100644
--- a/pylons_app/templates/shortlog/shortlog.html
+++ b/pylons_app/templates/shortlog/shortlog.html
@@ -2,23 +2,32 @@
<%inherit file="/base/base.html"/>
<%def name="title()">
- ${_('Repository managment')}
+ ${_('Shortlog')}
</%def>
-<%def name="breadcrumbs()">
+
+
+<%def name="breadcrumbs_links()">
${h.link_to(u'Home',h.url('/'))}
- /
- ${h.link_to(c.repo_name,h.url('shortlog_home',repo_name=c.repo_name))}
- /
+ &raquo;
+ ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
+ &raquo;
${_('shortlog')}
</%def>
+
<%def name="page_nav()">
- ${self.menu('shortlog')}
+ ${self.menu('shortlog')}
</%def>
<%def name="main()">
-
- <h2 class="no-link no-border">${_('Shortlog')}</h2>
-
- <div id="shortlog_data">
- ${c.shortlog_data}
- </div>
-</%def> \ No newline at end of file
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <!-- end box / title -->
+ <div class="table">
+ <div id="shortlog_data">
+ ${c.shortlog_data}
+ </div>
+ </div>
+</div>
+</%def> \ No newline at end of file
diff --git a/pylons_app/templates/shortlog/shortlog_data.html b/pylons_app/templates/shortlog/shortlog_data.html
index 9b231f19..ba857afc 100644
--- a/pylons_app/templates/shortlog/shortlog_data.html
+++ b/pylons_app/templates/shortlog/shortlog_data.html
@@ -1,15 +1,14 @@
## -*- coding: utf-8 -*-
% if c.repo_changesets:
-
-<table class="table_disp">
- <tr class="header">
- <td>${_('date')}</td>
- <td>${_('author')}</td>
- <td>${_('revision')}</td>
- <td>${_('commit message')}</td>
- <td>${_('branch')}</td>
- <td>${_('tags')}</td>
- <td>${_('links')}</td>
+<table>
+ <tr>
+ <th class="left">${_('date')}</th>
+ <th class="left">${_('author')}</th>
+ <th class="left">${_('revision')}</th>
+ <th class="left">${_('commit message')}</th>
+ <th class="left">${_('branch')}</th>
+ <th class="left">${_('tags')}</th>
+ <th class="left">${_('links')}</th>
</tr>
%for cnt,cs in enumerate(c.repo_changesets):
@@ -43,22 +42,22 @@
%endfor
</table>
- <div>
- <script type="text/javascript">
- var data_div = 'shortlog_data';
- YAHOO.util.Event.onDOMReady(function(){
- YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
- YAHOO.util.Dom.setStyle('shortlog_data','opacity','0.3');});});
- </script>
- <h2>
- ${c.repo_changesets.pager('$link_previous ~2~ $link_next',
- onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{
- success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText;
- YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
- YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');});
- YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
- </h2>
- </div>
+
+<script type="text/javascript">
+ var data_div = 'shortlog_data';
+ YAHOO.util.Event.onDOMReady(function(){
+ YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
+ YAHOO.util.Dom.setStyle('shortlog_data','opacity','0.3');});});
+</script>
+
+<div class="pagination-wh pagination-left">
+${c.repo_changesets.pager('$link_previous ~2~ $link_next',
+onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{
+success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText;
+YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
+ YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');});
+YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
+</div>
%else:
- ${_('There are no commits yet')}
-%endif \ No newline at end of file
+ ${_('There are no commits yet')}
+%endif
diff --git a/pylons_app/templates/summary/summary.html b/pylons_app/templates/summary/summary.html
index 9c9f957a..06044b19 100644
--- a/pylons_app/templates/summary/summary.html
+++ b/pylons_app/templates/summary/summary.html
@@ -1,71 +1,270 @@
<%inherit file="/base/base.html"/>
+
<%def name="title()">
- ${_('Repository managment')}
+ ${_('Mercurial Repository Overview')}
</%def>
-<%def name="breadcrumbs()">
+
+
+
+<%def name="breadcrumbs_links()">
${h.link_to(u'Home',h.url('/'))}
- /
+ &raquo;
${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
- /
+ &raquo;
${_('summary')}
</%def>
+
<%def name="page_nav()">
${self.menu('summary')}
</%def>
-<%def name="js()">
-<script type="text/javascript" src="/js/yui/utilities/utilities.js"></script>
+<%def name="main()">
<script type="text/javascript">
var E = YAHOO.util.Event;
var D = YAHOO.util.Dom;
E.onDOMReady(function(e){
id = 'clone_url';
- E.addListener(id,'click',function(e){
- D.get('clone_url').select();
- })
+ E.addListener(id,'click',function(e){
+ D.get('clone_url').select();
+ })
})
</script>
-</%def>
-
-<%def name="main()">
- <h2 class="no-link no-border">${_('Mercurial Repository Overview')}</h2>
- <dl class="overview">
- <dt>${_('name')}</dt>
- <dd>${c.repo_info.name}</dd>
- <dt>${_('description')}</dt>
- <dd>${c.repo_info.description}</dd>
- <dt>${_('contact')}</dt>
- <dd>${c.repo_info.contact}</dd>
- <dt>${_('last change')}</dt>
- <dd>${h.age(c.repo_info.last_change)} - ${h.rfc822date(c.repo_info.last_change)}</dd>
- <dt>${_('clone url')}</dt>
- <dd><input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/></dd>
- <dt>${_('download')}</dt>
- <dd>
- %for cnt,archive in enumerate(c.repo_info._get_archives()):
- %if cnt >=1:
- |
- %endif
- ${h.link_to(c.repo_info.name+'.'+archive['type'],
- h.url('files_archive_home',repo_name=c.repo_info.name,
- revision='tip',fileformat=archive['extension']),class_="archive_logo")}
- %endfor
- </dd>
- <dt>${_('feeds')}</dt>
- <dd>
- ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_logo')}
- ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_logo')}
- </dd>
- </dl>
-
- <h2>${h.link_to(_('Last ten changes'),h.url('changelog_home',repo_name=c.repo_name))}</h2>
- <%include file='../shortlog/shortlog_data.html'/>
-
- <h2>${h.link_to(_('Last ten tags'),h.url('tags_home',repo_name=c.repo_name))}</h2>
- <%include file='../tags/tags_data.html'/>
+<div class="box box-left">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <!-- end box / title -->
+ <div class="form">
+ <div class="fields">
+
+ <div class="field">
+ <div class="label">
+ <label>${_('Name')}:</label>
+ </div>
+ <div class="input-short">
+ ${c.repo_info.name}
+ </div>
+ </div>
+
+
+ <div class="field">
+ <div class="label">
+ <label>${_('Description')}:</label>
+ </div>
+ <div class="input-short">
+ ${c.repo_info.description}
+ </div>
+ </div>
+
+
+ <div class="field">
+ <div class="label">
+ <label>${_('Contact')}:</label>
+ </div>
+ <div class="input-short">
+ ${c.repo_info.contact}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label>${_('Last change')}:</label>
+ </div>
+ <div class="input-short">
+ ${h.age(c.repo_info.last_change)} - ${h.rfc822date(c.repo_info.last_change)}
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label>${_('Clone url')}:</label>
+ </div>
+ <div class="input-short">
+ <input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/>
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label>${_('Download')}:</label>
+ </div>
+ <div class="input-short">
+ %for cnt,archive in enumerate(c.repo_info._get_archives()):
+ %if cnt >=1:
+ |
+ %endif
+ ${h.link_to(c.repo_info.name+'.'+archive['type'],
+ h.url('files_archive_home',repo_name=c.repo_info.name,
+ revision='tip',fileformat=archive['extension']),class_="archive_icon")}
+ %endfor
+ </div>
+ </div>
+
+ <div class="field">
+ <div class="label">
+ <label>${_('Feeds')}:</label>
+ </div>
+ <div class="input-short">
+ ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_icon')}
+ ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_icon')}
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+<div class="box box-right">
+ <!-- box / title -->
+ <div class="title">
+ <h5>${_('Last month commit activity')}</h5>
+ </div>
- <h2>${h.link_to(_('Last ten branches'),h.url('branches_home',repo_name=c.repo_name))}</h2>
- <%include file='../branches/branches_data.html'/>
+ <div class="table">
+ <div id="commit_history" style="width:600px;height:370px;float:left"></div>
+ <div id="legend_data">
+ <div id="legend_container"></div>
+ <div id="legend_choices">
+ <table id="legend_choices_tables" style="font-size:smaller;color:#545454">
+
+ </table>
+ </div>
+ </div>
+ <script type="text/javascript">
+
+ (function () {
+ var datasets = {${c.commit_data|n}};
+ var i = 0;
+ var choiceContainer = YAHOO.util.Dom.get("legend_choices");
+ var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables");
+ for(var key in datasets) {
+ datasets[key].color = i;
+ i++;
+ choiceContainerTable.innerHTML += '<tr>'+
+ '<td>'+
+ '<input type="checkbox" name="' + key +'" checked="checked" />'+datasets[key].label+
+ '</td>'+
+ '</tr>';
+ };
+
+
+ function plotAccordingToChoices() {
+ var data = [];
+
+ var inputs = choiceContainer.getElementsByTagName("input");
+ for(var i=0; i<inputs.length; i++) {
+ if(!inputs[i].checked)
+ continue;
+
+ var key = inputs[i].name;
+ if (key && datasets[key])
+ data.push(datasets[key]);
+ };
+
+ if (data.length > 0){
+ var plot = YAHOO.widget.Flot("commit_history", data,
+ { bars: { show: true, align:'left' },
+ points: { show: true, radius:0,fill:true },
+ legend:{show:true, container:"legend_container"},
+ selection: { mode: "xy" },
+ yaxis:{tickSize:[1]},
+ xaxis: { mode: "time", timeformat: "%d",tickSize:[1, "day"],min:${c.ts_min},max:${c.ts_max} },
+ grid: { hoverable: true, clickable: true,autoHighlight:true },
+ });
+
+ function showTooltip(x, y, contents) {
+ var div=document.getElementById('tooltip');
+ if(!div) {
+ div = document.createElement('div');
+ div.id="tooltip";
+ div.style.position="absolute";
+ div.style.border='1px solid #fdd';
+ div.style.padding='2px';
+ div.style.backgroundColor='#fee';
+ document.body.appendChild(div);
+ }
+ YAHOO.util.Dom.setStyle(div, 'opacity', 0);
+ div.innerHTML = contents;
+ div.style.top=(y + 5) + "px";
+ div.style.left=(x + 5) + "px";
+
+ var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
+ anim.animate();
+ }
+
+ var previousPoint = null;
+ plot.subscribe("plothover", function (o) {
+ var pos = o.pos;
+ var item = o.item;
+
+ //YAHOO.util.Dom.get("x").innerHTML = pos.x.toFixed(2);
+ //YAHOO.util.Dom.get("y").innerHTML = pos.y.toFixed(2);
+ if (item) {
+ if (previousPoint != item.datapoint) {
+ previousPoint = item.datapoint;
+
+ var tooltip = YAHOO.util.Dom.get("tooltip");
+ if(tooltip) {
+ tooltip.parentNode.removeChild(tooltip);
+ }
+ var x = item.datapoint.x.toFixed(2);
+ var y = item.datapoint.y.toFixed(2);
+
+ if (!item.series.label){
+ item.series.label = 'commits';
+ }
+ var d = new Date(x*1000);
+ var fd = d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate();
+ var nr_commits = parseInt(y);
+ showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd + ": " + nr_commits+" commits");
+ }
+ }
+ else {
+ var tooltip = YAHOO.util.Dom.get("tooltip");
+
+ if(tooltip) {
+ tooltip.parentNode.removeChild(tooltip);
+ }
+ previousPoint = null;
+ }
+ });
+
+ }
+ }
+
+ YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotAccordingToChoices);
+
+ plotAccordingToChoices();
+ })();
+ </script>
+
+ </div>
+</div>
+
+<div class="box">
+ <div class="title">
+ <div class="breadcrumbs">${h.link_to(_('Last ten changes'),h.url('changelog_home',repo_name=c.repo_name))}</div>
+ </div>
+ <div class="table">
+ <%include file='../shortlog/shortlog_data.html'/>
+ </div>
+</div>
+<div class="box">
+ <div class="title">
+ <div class="breadcrumbs">${h.link_to(_('Last ten tags'),h.url('tags_home',repo_name=c.repo_name))}</div>
+ </div>
+ <div class="table">
+ <%include file='../tags/tags_data.html'/>
+ </div>
+</div>
+<div class="box">
+ <div class="title">
+ <div class="breadcrumbs">${h.link_to(_('Last ten branches'),h.url('branches_home',repo_name=c.repo_name))}</div>
+ </div>
+ <div class="table">
+ <%include file='../branches/branches_data.html'/>
+ </div>
+</div>
</%def> \ No newline at end of file
diff --git a/pylons_app/templates/tags/tags.html b/pylons_app/templates/tags/tags.html
index 2a47573d..243d328c 100644
--- a/pylons_app/templates/tags/tags.html
+++ b/pylons_app/templates/tags/tags.html
@@ -1,20 +1,31 @@
+## -*- coding: utf-8 -*-
<%inherit file="/base/base.html"/>
+
<%def name="title()">
- ${_('Tags')}
+ ${_('Administration')}
</%def>
-<%def name="breadcrumbs()">
+
+
+<%def name="breadcrumbs_links()">
${h.link_to(u'Home',h.url('/'))}
- /
+ &raquo;
${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
- /
+ &raquo;
${_('tags')}
</%def>
+
<%def name="page_nav()">
- ${self.menu('tags')}
+ ${self.menu('tags')}
</%def>
<%def name="main()">
-
- <h2 class="no-link no-border">${_('Tags')}</h2>
- <%include file='tags_data.html'/>
-
-</%def> \ No newline at end of file
+<div class="box">
+ <!-- box / title -->
+ <div class="title">
+ ${self.breadcrumbs()}
+ </div>
+ <!-- end box / title -->
+ <div class="table">
+ <%include file='tags_data.html'/>
+ </div>
+</div>
+</%def> \ No newline at end of file
diff --git a/pylons_app/templates/tags/tags_data.html b/pylons_app/templates/tags/tags_data.html
index 7850f1b1..eb595197 100644
--- a/pylons_app/templates/tags/tags_data.html
+++ b/pylons_app/templates/tags/tags_data.html
@@ -1,10 +1,10 @@
%if c.repo_tags:
- <table class="table_disp">
- <tr class="header">
- <td>${_('date')}</td>
- <td>${_('revision')}</td>
- <td>${_('name')}</td>
- <td>${_('links')}</td>
+ <table>
+ <tr>
+ <th class="left">${_('date')}</th>
+ <th class="left">${_('revision')}</th>
+ <th class="left">${_('name')}</th>
+ <th class="left">${_('links')}</th>
</tr>
%for cnt,tag in enumerate(c.repo_tags.items()):
<tr class="parity${cnt%2}">