Merge github.com:web2py/web2py

This commit is contained in:
Michele Comitini
2012-12-28 15:53:36 +01:00
144 changed files with 6291 additions and 2097 deletions
+6
View File
@@ -0,0 +1,6 @@
web2py is an open source full-stack framework for agile development
of secure database-driven web-based applications, written and programmable in
Python.
Created by Massimo Di Pierro <mdipierro@cs.depaul.edu>
+38
View File
@@ -1,3 +1,41 @@
## 2.4.1
- support for semantic versioning
- new bootstrap based admin, thanks Paolo
- graphiz support added to adm, thanks Jose
- on_failure in grid
- db.table.field.abs()
- geoPoint, getLine, geoPolygon
- better reporting of 500 ajax errors
- bug fixes (including issues with calendar.js and archive tables)
## 2.3.1 - 2.3.2
- new virtual fields syntax:
``db.define_table('person',Field('name'),Field.Virtual('namey',lambda row: row.person.name+'y'))``
- db.thing(name='Cohen',_orderby=db.thing.name), thanks Yair
- made many modules Python 3.3 friendly (compile but not tested)
- better welcome css, thanks Paolo
- jQuery 1.8.3
- Bootstrap 2.2.2
- Modernizr 2.6.2 (custom full options)
- integration with analyitics.js (0.2.0)
- better scheduler, thanks Niphlod
- page and media preview in wiki, thanks Niphlod
- create new auth.wiki page from slug model, thanks Nico
- conditional menus with auth.wiki(menugroups=['wiki_editor'])
- better security in grid/smartgrid
- allow LOADing multiple grids, thanks Niphlod
- auth.settings.login_onfail, thanks Yair
- better handling of session files for speed
- added heroku support (experimental)
- added rocket support for IPV6, thanks Chirs Winebrinner
- more customizable menus with MENU(li_first, li_last..)
- added support for paymentech (gluon/contrib/paymentech.py)
- fixed broken cron
- fixed possible xss with share.js
- many bug fixes. Closed more than 50 tickets since 2.2.1
## 2.2.1
- session.connect(cookie_key='secret', compression_level=9) stores sessions in cookies
View File
+5 -3
View File
@@ -29,7 +29,8 @@ update:
wget -O gluon/contrib/simplejsonrpc.py http://rad2py.googlecode.com/hg/ide2py/simplejsonrpc.py
echo "remember that pymysql was tweaked"
src:
echo 'Version 2.2.1 ('`date +%Y-%m-%d\ %H:%M:%S`') stable' > VERSION
### Use semantic versioning
echo 'Version 2.4.1-alpha.2+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
### rm -f all junk files
make clean
### clean up baisc apps
@@ -42,7 +43,9 @@ src:
rm -f applications/examples/databases/*
rm -f applications/admin/uploads/*
rm -f applications/welcome/uploads/*
rm -f applications/examples/uploads/*
rm -f applications/examples/uploads/*
### make epydoc
make epydoc
### make welcome layout and appadmin the default
cp applications/welcome/views/appadmin.html applications/admin/views
cp applications/welcome/views/appadmin.html applications/examples/views
@@ -54,7 +57,6 @@ src:
cd ..; zip -r web2py/web2py_src.zip web2py/gluon/*.py web2py/gluon/contrib/* web2py/splashlogo.gif web2py/*.py web2py/README.markdown web2py/LICENSE web2py/CHANGELOG web2py/NEWINSTALL web2py/VERSION web2py/Makefile web2py/epydoc.css web2py/epydoc.conf web2py/app.example.yaml web2py/logging.example.conf web2py_exe.conf web2py/queue.example.yaml MANIFEST.in w2p_apps w2p_clone w2p_run startweb2py web2py/scripts/*.sh web2py/scripts/*.py web2py/applications/admin web2py/applications/examples/ web2py/applications/welcome web2py/applications/__init__.py web2py/site-packages/__init__.py web2py/gluon/tests/*.sh web2py/gluon/tests/*.py
mdp:
make epydoc
make src
make app
make win
+1
View File
@@ -0,0 +1 @@
+1 -1
View File
@@ -1 +1 @@
Version 2.2.1 (2012-11-15 14:34:13) stable
Version 2.4.1-alpha.2+timestamp.2012.12.28.01.21.20
+81 -4
View File
@@ -11,6 +11,11 @@ import copy
import gluon.contenttype
import gluon.fileutils
try:
import pygraphviz as pgv
except ImportError:
pgv = None
response.subtitle = 'Database Administration (appadmin)'
# ## critical --- make a copy of the environment
@@ -396,12 +401,13 @@ def ccache():
if value[0] < ram['oldest']:
ram['oldest'] = value[0]
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
locker = open(os.path.join(request.folder,
'cache/cache.lock'), 'a')
folder = os.path.join(request.folder,'cache')
if not os.path.exists(folder):
os.mkdir(folder)
locker = open(os.path.join(folder, 'cache.lock'), 'a')
portalocker.lock(locker, portalocker.LOCK_EX)
disk_storage = shelve.open(
os.path.join(request.folder, 'cache/cache.shelve'))
os.path.join(folder, 'cache.shelve'))
try:
for key, value in disk_storage.items():
if isinstance(value, dict):
@@ -459,3 +465,74 @@ def ccache():
return dict(form=form, total=total,
ram=ram, disk=disk, object_stats=hp != False)
def table_template(table):
from gluon.html import TR, TD, TABLE, TAG
def FONT(*args, **kwargs):
return TAG.font(*args, **kwargs)
def types(field):
f_type = field.type
if not isinstance(f_type,str):
return ' '
elif f_type == 'string':
return field.length
elif f_type == 'id':
return B('pk')
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
return B('fk')
else:
return ' '
# This is horribe HTML but the only one graphiz understands
rows = []
cellpadding = 4
color = "#000000"
bgcolor = "#FFFFFF"
face = "Helvetica"
face_bold = "Helvetica Bold"
border = 0
rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor),
_colspan=3, _cellpadding=cellpadding,
_align="center", _bgcolor=color)))
for row in db[table]:
rows.append(TR(TD(FONT(row.name, _color=color, _face=face_bold),
_align="left", _cellpadding=cellpadding,
_border=border),
TD(FONT(row.type, _color=color, _face=face),
_align="left", _cellpadding=cellpadding,
_border=border),
TD(FONT(types(row), _color=color, _face=face),
_align="center", _cellpadding=cellpadding,
_border=border)))
return "< %s >" % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1,
_cellborder=0, _cellspacing=0)
).xml()
def bg_graph_model():
graph = pgv.AGraph(layout='dot', directed=True, strict=False, rankdir='LR')
for tablename in db.tables:
graph.add_node(tablename, name=tablename, shape='plaintext',
label=table_template(tablename))
for tablename in db.tables:
for field in db[tablename]:
f_type = field.type
if isinstance(f_type,str) and (
f_type.startswith('reference') or
f_type.startswith('list:reference')):
referenced_table = f_type.split()[1].split('.')[0]
n1 = graph.get_node(tablename)
n2 = graph.get_node(referenced_table)
graph.add_edge(n1, n2, color="#4C4C4C", label='')
graph.layout()
return graph.draw(format='png', prog='dot')
def graph_model():
return dict(databases=databases, pgv=pgv)
+4
View File
@@ -176,6 +176,8 @@ def toggle_breakpoint():
try:
filename = os.path.join(request.env['applications_parent'],
'applications', request.vars.filename)
# normalize path name: replace slashes, references, etc...
filename = os.path.normpath(os.path.normcase(filename))
if not request.vars.data:
# ace send us the line number!
lineno = int(request.vars.sel_start) + 1
@@ -192,6 +194,8 @@ def toggle_breakpoint():
if lineno is not None:
for bp in qdb_debugger.do_list_breakpoint():
no, bp_filename, bp_lineno, temporary, enabled, hits, cond = bp
# normalize path name: replace slashes, references, etc...
bp_filename = os.path.normpath(os.path.normcase(bp_filename))
if filename == bp_filename and lineno == bp_lineno:
err = qdb_debugger.do_clear_breakpoint(filename, lineno)
response.flash = T("Removed Breakpoint on %s at line %s", (
+33 -23
View File
@@ -168,7 +168,8 @@ def change_password():
form = SQLFORM.factory(Field('current_admin_password', 'password'),
Field('new_admin_password',
'password', requires=IS_STRONG()),
Field('new_admin_password_again', 'password'))
Field('new_admin_password_again', 'password'),
_class="span4 well")
if form.accepts(request.vars):
if not verify_password(request.vars.current_admin_password):
form.errors.current_admin_password = T('invalid password')
@@ -202,12 +203,14 @@ def site():
is_appname = IS_VALID_APPNAME()
form_create = SQLFORM.factory(Field('name', requires=is_appname),
table_name='appcreate')
table_name='appcreate',
_class='well well-small')
form_update = SQLFORM.factory(Field('name', requires=is_appname),
Field('file', 'upload', uploadfield=False),
Field('url'),
Field('overwrite', 'boolean'),
table_name='appupdate')
table_name='appupdate',
_class='well well-small')
form_create.process()
form_update.process()
@@ -374,6 +377,10 @@ def uninstall():
dialog = FORM.confirm(T('Uninstall'),
{T('Cancel'): URL('site')})
dialog['_id'] = 'confirm_form'
dialog['_class'] = 'well'
for component in dialog.components:
component['_class'] = 'btn'
if dialog.accepted:
if MULTI_USER_MODE:
@@ -791,7 +798,8 @@ def resolve():
diff = TABLE(*[TR(TD(gen_data(i, item)),
TD(item[0]),
TD(leading(item[2:]),
TT(item[2:].rstrip())), _class=getclass(item))
TT(item[2:].rstrip())),
_class=getclass(item))
for (i, item) in enumerate(d) if item[0] != '?'])
return dict(diff=diff, filename=filename)
@@ -834,10 +842,14 @@ def edit_language():
# Making the short circuit compatible with <= python2.4
k = (s != k) and k or B(k)
rows.append(P(prefix, k, BR(), elem, TAG.BUTTON(T('delete'),
_onclick='return delkey("%s")' % name), _id=name))
new_row = DIV(LABEL(prefix, k, _style="font-weight:normal;"),
CAT(elem, '\n', TAG.BUTTON(
T('delete'),
_onclick='return delkey("%s")' % name,
_class='btn')), _id=name, _class='span6 well well-small')
rows.append(INPUT(_type='submit', _value=T('update')))
rows.append(DIV(new_row,_class="row-fluid"))
rows.append(DIV(INPUT(_type='submit', _value=T('update'), _class="btn btn-primary"), _class='controls'))
form = FORM(*rows)
if form.accepts(request.vars, keepvalues=True):
strs = dict()
@@ -868,29 +880,27 @@ def edit_plurals():
keys = sorted(plurals.keys(), lambda x, y: cmp(
unicode(x, 'utf-8').lower(), unicode(y, 'utf-8').lower()))
rows = []
row = [T("Singular Form")]
row.extend([T("Plural Form #%s", n + 1) for n in xnplurals])
table = TABLE(THEAD(TR(row)))
tab_rows = []
for key in keys:
name = md5_hash(key)
forms = plurals[key]
if len(forms) < nplurals:
forms.extend(None for i in xrange(nplurals - len(forms)))
tab_col1 = DIV(CAT(LABEL(T("Singular Form")), B(key,
_class='fake-input')))
tab_inputs = [SPAN(LABEL(T("Plural Form #%s", n + 1)), INPUT(_type='text', _name=name + '_' + str(n), value=forms[n], _size=20), _class='span6') for n in xnplurals]
tab_col2 = DIV(CAT(*tab_inputs))
tab_col3 = DIV(CAT(LABEL(XML('&nbsp;')), TAG.BUTTON(T('delete'), _onclick='return delkey("%s")' % name, _class='btn'), _class='span6'))
tab_row = DIV(DIV(tab_col1, '\n', tab_col2, '\n', tab_col3, _class='well well-small'), _id=name, _class='row-fluid tab_row')
tab_rows.append(tab_row)
row = [B(key)]
row.extend([INPUT(_type='text', _name=name + '_' + str(n),
value=forms[n], _size=20) for n in xnplurals])
row.append(TD(
TAG.BUTTON(T('delete'), _onclick='return delkey("%s")' % name)))
rows.append(TR(row, _id=name))
if rows:
table.append(TBODY(rows))
rows = [table, INPUT(_type='submit', _value=T('update'))]
form = FORM(*rows)
tab_rows.append(DIV(TAG['button'](T('update'), _type='submit',
_class='btn btn-primary'),
_class='controls'))
tab_container = DIV(*tab_rows, **dict(_class="row-fluid"))
form = FORM(tab_container)
if form.accepts(request.vars, keepvalues=True):
new_plurals = dict()
for key in keys:
+1 -1
View File
@@ -35,7 +35,7 @@ def callback():
except ValueError:
return ''
session['commands:' + app].append(command)
environ = env(app, True)
environ = env(app, True, extra_request=dict(is_https=request.is_https))
output = gluon.contrib.shell.run(history, command, environ)
k = len(session['commands:' + app]) - 1
#output = PRE(output)
+20 -18
View File
@@ -55,7 +55,7 @@ def index():
reset(session)
apps = os.listdir(os.path.join(request.folder, '..'))
form = SQLFORM.factory(Field('name', requires=[IS_NOT_EMPTY(),
IS_ALPHANUMERIC()]))
IS_ALPHANUMERIC()]), _class='span5 well well-small')
if form.accepts(request.vars):
app = form.vars.name
session.app['name'] = app
@@ -125,19 +125,20 @@ def step1():
default=params.get('login_method', 'local')),
Field(
'login_config', default=params.get('login_config', None)),
Field('plugins', 'list:string', requires=IS_IN_SET(plugins, multiple=True)))
Field('plugins', 'list:string', requires=IS_IN_SET(plugins, multiple=True)),
_class='span7 well well-small')
if form.accepts(request.vars):
session.app['params'] = [(key, form.vars.get(key, None))
for key, value in session.app['params']]
redirect(URL('step2'))
redirect(URL('step2') + '/#xwizard_form')
return dict(step='1: Setting Parameters', form=form)
def step2():
response.view = 'wizard/step.html'
form = SQLFORM.factory(Field('table_names', 'list:string',
default=session.app['tables']))
default=session.app['tables']), _class="span7 well well-small")
if form.accepts(request.vars):
table_names = [clean(t) for t in listify(form.vars.table_names)
if t.strip()]
@@ -157,21 +158,21 @@ def step2():
session.app['page_' + name] = \
'## Manage %s\n\n{{=form}}' % (table)
if session.app['tables']:
redirect(URL('step3', args=0))
redirect(URL('step3', args=0) + '/#xwizard_form')
else:
redirect(URL('step4'))
redirect(URL('step4') + '/#xwizard_form')
return dict(step='2: Tables', form=form)
def step3():
response.view = 'wizard/step.html'
n = int(request.args(0) or 0)
n = int(request.args(-1) or 0)
m = len(session.app['tables'])
if n >= m:
redirect(URL('step2'))
table = session.app['tables'][n]
form = SQLFORM.factory(Field('field_names', 'list:string',
default=session.app.get('table_' + table, [])))
default=session.app.get('table_' + table, [])), _class="span7 well well-small")
if form.accepts(request.vars) and form.vars.field_names:
fields = listify(form.vars.field_names)
if table == 'auth_user':
@@ -187,9 +188,9 @@ def step3():
response.flash = T('invalid circular reference')
else:
if n < m - 1:
redirect(URL('step3', args=n + 1))
redirect(URL('step3', args=n + 1) + '/#xwizard_form')
else:
redirect(URL('step4'))
redirect(URL('step4') + '/#xwizard_form')
return dict(step='3: Fields for table "%s" (%s of %s)'
% (table, n + 1, m), table=table, form=form)
@@ -197,21 +198,21 @@ def step3():
def step4():
response.view = 'wizard/step.html'
form = SQLFORM.factory(Field('pages', 'list:string',
default=session.app['pages']))
default=session.app['pages']), _class="span7 well well-small")
if form.accepts(request.vars):
session.app['pages'] = [clean(t)
for t in listify(form.vars.pages)
if t.strip()]
if session.app['pages']:
redirect(URL('step5', args=0))
redirect(URL('step5', args=0) + '/#xwizard_form')
else:
redirect(URL('step6'))
redirect(URL('step6') + '/#xwizard_form')
return dict(step='4: Pages', form=form)
def step5():
response.view = 'wizard/step.html'
n = int(request.args(0) or 0)
n = int(request.args(-1) or 0)
m = len(session.app['pages'])
if n >= m:
redirect(URL('step4'))
@@ -221,13 +222,13 @@ def step5():
default=session.app.get('page_' + page, []),
comment=A('use markmin',
_href=markmin_url, _target='_blank')),
formstyle='table2cols')
formstyle='table2cols', _class="span7 well well-small")
if form.accepts(request.vars):
session.app['page_' + page] = form.vars.content
if n < m - 1:
redirect(URL('step5', args=n + 1))
redirect(URL('step5', args=n + 1) + '/#xwizard_form')
else:
redirect(URL('step6'))
redirect(URL('step6') + '/#xwizard_form')
return dict(step='5: View for page "%s" (%s of %s)' % (page, n + 1, m), form=form)
@@ -242,7 +243,8 @@ def step6():
Field('generate_menu', 'boolean', default=True),
Field('apply_layout', 'boolean', default=True),
Field('erase_database', 'boolean', default=True),
Field('populate_database', 'boolean', default=True))
Field('populate_database', 'boolean', default=True),
_id="generate_form", _class="form-horizontal span7 well well-small")
if form.accepts(request.vars):
if DEMO_MODE:
session.flash = T('Application cannot be generated in demo mode')
+3 -3
View File
@@ -1,10 +1,10 @@
EXPIRATION_MINUTES=60
DIGITS=('0','1','2','3','4','5','6','7','8','9')
import os, time, stat, cPickle, logging
path=os.path.join(request.folder,'sessions')
path = os.path.join(request.folder,'sessions')
if not os.path.exists(path):
os.mkdir(path)
now=time.time()
now = time.time()
for filename in os.listdir(path):
fullpath=os.path.join(path,filename)
if os.path.isfile(fullpath) and filename.startswith(DIGITS):
@@ -18,4 +18,4 @@ for filename in os.listdir(path):
if (now - filetime) > expiration:
os.unlink(fullpath)
except:
logging.exception('failure to check %s'%fullpath)
logging.exception('failure to check %s' % fullpath)
+7 -9
View File
@@ -8,35 +8,33 @@ def A_button(*a, **b):
b['_data-inline'] = 'true'
return A(*a, **b)
def button(href, label):
if is_mobile:
ret = A_button(SPAN(label), _href=href)
else:
ret = A(SPAN(label), _class='button', _href=href)
ret = A(SPAN(label), _class='button btn', _href=href)
return ret
def button_enable(href, app):
if os.path.exists(os.path.join(apath(app, r=request), 'DISABLED')):
label = SPAN(T('Enable'), _style='color:red')
else:
label = SPAN(T('Disable'), _style='color:green')
id = 'enable_' + app
return A(label, _class='button', _id=id, callback=href, target=id)
return A(label, _class='button btn', _id=id, callback=href, target=id)
def sp_button(href, label):
if request.user_agent().is_mobile:
ret = A_button(SPAN(label), _href=href)
else:
ret = A(SPAN(label), _class='button special', _href=href)
ret = A(SPAN(label), _class='button special btn btn-inverse', _href=href)
return ret
def helpicon():
return IMG(_src=URL('static', 'images/help.png'), _alt='help')
def searchbox(elementid):
return TAG[''](LABEL(IMG(_id="search_start", _src=URL('static', 'images/search.png'), _alt=T('filter')), _class='icon', _for=elementid), ' ', INPUT(_id=elementid, _type='text', _size=12))
return SPAN(LABEL(IMG(_id="search_start", _src=URL('static', 'images/search.png'), _alt=T('filter')),
_class='icon', _for=elementid), ' ',
INPUT(_id=elementid, _type='text', _size=12, _class="input-medium"),
_class="searchbox")
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+579
View File
@@ -0,0 +1,579 @@
/*=============================================================
GENERAL
==============================================================*/
html,body{height:auto;background:transparent;}
/*=============================================================
CONTROLS
==============================================================*/
label,
input,
button,
select,
textarea,
button.btn
{
font-size:13px;
font-weight:normal;
line-height:18px;
}
textarea,
select
{
margin-bottom:9px;
}
select,
/*textarea,*/
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"],
.uneditable-input,
a.btn-lnk
{
height:18px;
padding:4px;
font-size:13px;
line-height:18px;
}
.design h3,
.plugin h3
{
background-position:0 2px;
}
select,
input[type="file"]
{
height:28px;
line-height:28px;
}
input[type="submit"],
input[type="button"]
{
font-size:13px;
height:28px;
line-height:18px;
padding:4px 10px;
}
input[type="radio"],
input[type="checkbox"]
{
margin-top:2px;
}
.button.btn
{
line-height:1.25em;
font-size:inherit;
border:none;
text-shadow:none;
margin-bottom:0px;
-webkit-border-radius:0px;
-moz-border-radius:0px;
border-radius:0px;
-webkit-box-shadow:none;
-moz-box-shadow:none;
box-shadow:none);
}
.button.btn:hover
{
background-color:transparent;
-webkit-transition: background-position 0s linear;
-moz-transition: background-position 0s linear;
-o-transition: background-position 0s linear;
transition: background-position 0s linear;
}
form label
{
font-weight:bold;
}
.help
{
border-color:transparent;
}
/* tree menu */
.folder
{
border:none;
}
.folder>i
{
display:none;
}
.celled
{
padding-top: 2px;
}
.celled-one
{
padding-top: 1px;
}
.test h3
{
border:0;
padding-left:18px;
}
/*=============================================================
FLASH MESSAGEBOX
==============================================================*/
.flash
{
position:fixed;
width:50%;
top:49px;
left:25%;
right:25%;
cursor:default;
text-align:center;
padding:8px 35px 8px 14px;
z-index:5620;
}
.flash>.close
{
color:inherit;
opacity:0.7;
}
.flash>.close:hover
{
opacity:0.9;
}
/*=============================================================
NAVBAR
==============================================================*/
.navbar-fixed-top .navbar-inner,
.navbar-static-top .navbar-inner
{
/* in place of shadow image */
-webkit-box-shadow:0px 10px 20px rgba(195,195,195,1.0);
-moz-box-shadow: 0px 10px 20px rgba(195,195,195,1.0);
box-shadow: 0px 10px 20px rgba(195,195,195,1.0);
//zoom:1; /* IE6-9 */
filter:progid:DXImageTransform.Microsoft.DropShadow(OffX=0, OffY=10, Color=#000000); /* IE6-9 */
padding:0;
}
.navbar-inverse .navbar-inner
{
min-height:33px; /* required - override */
height:33px;
filter:progid:DXImageTransform.Microsoft.gradient(enabled=false); /* IE6-9 */
background:#292929 url(../images/header_bg.png) repeat-x;
border:none;
}
#header
{
background:transparent;
}
#header.navbar
{
overflow:visible;
}
.navbar-inverse .nav > li > a
{
padding:0;
line-height:1.25;
text-shadow:none;
}
.navbar .btn-navbar
{
padding:4px;
margin:5px 5px 0 5px;
}
#menu{margin-right:-7px;}
/*=============================================================
FOOTER
==============================================================*/
#footer
{
padding-bottom:0;
}
/*=============================================================
MAIN
==============================================================*/
#main
{
position:static;
padding-top:0;
padding-bottom:0;
}
/*=============================================================
SIDEBAR
==============================================================*/
.sidebar_inner
{
background:transparent;
padding:0;
min-width:auto;
}
.sidebar .box {
border-top:1px solid #EEE;
}
/*=============================================================
WIZARD
==============================================================*/
.step div.help li
{
line-height:inherit;
}
.ms-container .ms-selectable li.ms-elem-selectable,
.ms-container .ms-selection li.ms-elem-selected
{
font-size:13px;
}
.input-append a.btn
{
padding:4px;
height:18px;
font-size:13px;
line-height:18px;
}
/*=============================================================
ERRORS TABLE
==============================================================*/
.errors .table th
{
filter:progid:DXImageTransform.Microsoft.gradient(enabled=false); /* IE6-9 */
}
.tablebar span.help
{
font-weight:normal;
line-height:1.25em;
text-shadow:none;
width:auto;
}
/*=============================================================
TOOLTIP
==============================================================*/
.tooltip.in
{
opacity:1;
filter:alpha(opacity=100);
}
.tooltip-inner
{
opacity:1;
text-align:left;
background:#9fb364;
color:#eef1d9;
border:1px solid #eef1d9;
font-style:italic;
padding:0.3em;
-moz-border-radius:0.5em;
border-radius:0.5em;
font-size:13px;
text-transform:none;
}
.tooltip.right .tooltip-arrow,
.tooltip.left .tooltip-arrow
{
border-color:transparent;
}
/*=============================================================
THE GRID
==============================================================*/
.w2p_grid_bottom_bar .w2p_export_menu
{
line-height:18px;
margin-left:0;
}
.w2p_export_menu .dropdown-toggle
{
cursor:pointer;
margin:0;
padding:0;
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(white), to(#E6E6E6));
background-image: -webkit-linear-gradient(top, white, #E6E6E6);
background-image: -o-linear-gradient(top, white, #E6E6E6);
background-image: linear-gradient(to bottom, white, #E6E6E6);
background-image: -moz-linear-gradient(top, white, #E6E6E6);
}
.w2p_export_menu ul
{
margin-top:2px;
display:none;
}
.w2p_export_menu li
{
display:list-item;
margin:0;
}
div.web2py_grid
{
font-size:13px;
line-height:18px;
}
.web2py_grid a.btn
{
font-size:13px;
line-height:18px;
padding:4px 10px;
margin-left:0;
margin-right:4px;
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
}
.web2py_grid .input-append .btn
{
padding:4px 10px;
margin-right:0;
font-family:inherit;
color:#333;
text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);
border:1px solid #c5c5c5;
}
.web2py_grid select:focus
{
border-color:rgba(232,149,60,0.8);
outline:0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(232, 149, 60, 0.6);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(232,149,60,0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(232, 149, 60, 0.6);
}
.web2py_console input[type="button"],
.web2py_grid .row_buttons a.btn
{
color:#333;
line-height:18px;
padding:4px 10px;
text-shadow:rgba(255, 255, 255, 0.74902) 0px 1px 1px;
border-color:rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.web2py_console input[type="button"]:hover,
.web2py_grid .row_buttons a.btn:hover
{
color:#333;
border-color:rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);
background:#E6E6E6;
background-position: 0 -15px !important;
-webkit-transition: background-position .1s linear;
-moz-transition: background-position .1s linear;
-o-transition: background-position .1s linear;
transition: background-position .1s linear;
}
.web2py_table
{
border:none;
}
.web2py_table table
{
/*table-layout:fixed;*/
margin-bottom:4px;
}
.web2py_table table td
{
/*word-wrap:break-word;*/ /*uncomment when "table-layout:fixed" is applied */
}
.web2py_grid thead th
{
background-color:transparent;
padding:4px 5px;
line-height:18px;
vertical-align:bottom;
border-right:0;
border-bottom:0;
word-wrap:break-word;
}
.web2py_grid .btn-group > .dropdown-menu
{
font-size:13px;
}
.web2py_grid .dropdown-menu li > a:hover,
.web2py_grid .dropdown-menu li > a:focus
{
filter:progid:DXImageTransform.Microsoft.gradient(enabled=false); /* IE6-9 */
background-image:none;
background-color:#E8953C;
}
.pagination
{
margin:0;
height:30px;
}
.pagination ul > li > a
{
line-height:28px;
}
#w2p_grid_addbtn:focus,
#w2p_search-form :focus,
.btn:focus
{
outline:none;
}
.web2py_console input[type="button"]:focus,
.web2py_grid .row_buttons a.btn:focus
{
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15) inset, 0 1px 2px rgba(0, 0, 0, 0.05);
}
div.web2py_counter.span6
{
min-height:20px;
}
.web2py_paginator
{
border:0;
margin:0;
padding:0;
background-color:transparent;
}
.web2py_paginator ul li a
{
margin-right:0;
padding:0 14px;
border:1px solid #DDD;
border-left-width:0;
color:#E8953C;
}
.web2py_paginator ul li a:hover
{
background: whiteSmoke;
border: 1px solid #DDD;
border-left-width:0;
color:#e2821b;
}
.web2py_paginator ul li:first-child a,
.web2py_paginator ul li:first-child a:hover
{
border-left-width:1px;
}
.web2py_paginator .current
{
font-weight:normal;
}
.web2py_paginator ul li.current a:hover
{
color:#999;
}
.editor-bar-column a[name="save"]
{
background-color: whiteSmoke;
background-image: -webkit-gradient(linear,0 0,0 100%,from(white),to(#E6E6E6));
background-image: -webkit-linear-gradient(top,white,#E6E6E6);
background-image: -o-linear-gradient(top,white,#E6E6E6);
background-image: linear-gradient(to bottom,white,#E6E6E6);
background-image: -moz-linear-gradient(top,white,#E6E6E6);
background-repeat: repeat-x;
padding:2px 6px;
font-size:11px;
line-height:17px;
margin:0;
}
.editor-bar-column a[name="save"]:hover
{
background-color: #E6E6E6;
background-position: 0 -15px;
-webkit-transition: background-position .1s linear;
-moz-transition: background-position .1s linear;
-o-transition: background-position .1s linear;
transition: background-position .1s linear;
}
.keybindings
{
padding:0 18px 10px;
}
.keybindings li
{
margin-bottom:0;
}
/*----- translate page ---*/
.languageform input
{
margin-bottom:0;
}
.languageform div
{
margin-bottom:9px;
}
.languageform input.untranslated
{
background-color:#FC0;
}
.step #wizard_nav .first-box
{
padding-top:0;
}
/*=============================================================
MEDIA QUERIES
==============================================================*/
@media (max-width: 979px)
{
/*-----------------------------------
Navbar
-------------------------------------*/
#header .navbar-inner
{
padding:0;
}
/*collapsed menu*/
.navbar .nav-collapse .nav
{
background:#222;
padding:8px 2px 8px 8px;
-webkit-border-bottom-right-radius:8px;
-webkit-border-bottom-left-radius:8px;
-moz-border-radius-bottomright:8px;
-moz-border-radius-bottomleft:8px;
border-bottom-right-radius:8px;
border-bottom-left-radius:8px;
}
#menu
{
margin-right:0;
}
#menu li
{
float:none;
}
#menu a.button,
#menu a.button span
{
background-image:url(../images/menu_responsive.png);
}
#menu a.button
{
padding:0 1em 0 0;
}
}
@media(max-width:632px)
{
/*-----------------------------------
footer
-------------------------------------*/
#footer
{
height:auto;
}
#footer select
{
margin-top:8px;
}
}
+822
View File
@@ -0,0 +1,822 @@
/*=============================================================
GENERAL
==============================================================*/
body
{
/*remember to account for the hidden area underneath
fixed navbar by adding at least 40px padding to the <body>.
Be sure to add this after the core Bootstrap CSS
and before the optional responsive CSS.
An alternative solution is to set top-margin to div#main*/
/*padding-top:60px;*/ /*comment this for alternative solution*/
height:auto; /*uncomment this for alternative solution */
}
/*=============================================================
BOOTSTRAP ICONS FOLDER FIX
==============================================================*/
[class^="icon-"],[class*=" icon-"]
{
/* right folder for bootstrap black images/icons */
background-image:url("../images/glyphicons-halflings.png")
}
.icon-white,
.nav-tabs>.active >a>[class^="icon-"],
.nav-tabs>.active>a>[class*=" icon-"],
.nav-pills>.active>a>[class^="icon-"],
.nav-pills>.active>a>[class*=" icon-"],
.nav-list>.active>a>[class^="icon-"],
.nav-list>.active>a>[class*=" icon-"],
.navbar-inverse .nav>.active>a>[class^="icon-"],
.navbar-inverse .nav>.active>a>[class*=" icon-"],
.dropdown-menu>li>a:hover>[class^="icon-"],
.dropdown-menu>li>a:hover>[class*=" icon-"],
.dropdown-menu>.active>a>[class^="icon-"],
.dropdown-menu>.active>a>[class*=" icon-"]
{
/* right folder for bootstrap white images/icons */
background-image:url("../images/glyphicons-halflings-white.png");
}
/*=============================================================
INPUT BORDER HIGHLIGHT WHEN INPUT IS FOCUSED
==============================================================*/
textarea:focus,
input[type="text"]:focus,
input[type="password"]:focus,
input[type="datetime"]:focus,
input[type="datetime-local"]:focus,
input[type="date"]:focus,
input[type="month"]:focus,
input[type="time"]:focus,
input[type="week"]:focus,
input[type="number"]:focus,
input[type="email"]:focus,
input[type="url"]:focus,
input[type="search"]:focus,
input[type="tel"]:focus,
input[type="color"]:focus,
input[type="file"]:focus,
select:focus,
.uneditable-input:focus
{
/* outline color */
border-color:rgba(232,149,60,0.8);
outline:0;
/*outline:thin dotted \9;*/
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(232, 149, 60, 0.6);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(232,149,60,0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(232, 149, 60, 0.6);
}
.web2py_grid .dropdown-menu li > a:hover,
.web2py_grid .dropdown-menu li > a:focus
{
filter:progid:DXImageTransform.Microsoft.gradient(enabled=false); /* IE6-9 */
background-image:none;
background-color:#E8953C;
}
/*=============================================================
COLOR OF LINKS
==============================================================*/
a,
a:hover
{
color:#E8953C;
text-decoration:none;
}
a:hover
{
color:#e2821b;
}
/*=============================================================
CONTROLS and CONTAINERS
==============================================================*/
.row-buttons .btn
{
margin-bottom:7px;
}
.sidebar .box
{
clear:right;
margin-top:2em;
border-top:1px dotted;
padding:0 1em;
}
.pwdchange>.button{margin-bottom:10px;}
input[type="file"] {
margin-bottom:9px;
}
.form-inline input[type="file"] {
margin-bottom:0px;
}
input + .help-block
{
margin-top:-5px;
margin-bottom:4px;
}
#confirm_form input.btn,
.generatedbyw2p input
{
margin-right:4px;
}
a[rel='tooltip'] span,
div[rel='tooltip'] span
{
display:none;
margin-left:-9999px;
}
/*in-page browsing*/
[rel="pagebookmark"]
{
position:relative;
}
[rel="pagebookmark"]>.component
{
cursor:pointer;
}
[rel="pagebookmark"]>.hashstick
{
position:absolute;
top:-54px;
left:-9999px;
visibility:visible;
}
/* following 2 rules set the style of a small button for going to top of page */
.tophashlink.btn
{
padding:2px 3px;
visibility:hidden;
}
.hashstick:target+.tophashlink.btn
{
visibility:visible;
}
ul.act_edit
{
margin-top:4px;
margin-left:20px;
}
ul.act_edit .btn
{
margin-top:4px;
margin-bottom:4px;
}
ul.act_edit .file>a
{
white-space:pre;
}
.right-full
{
text-align:right;
}
.searchbox,
.searchbox label,
.searchbox input
{
display:inline-block;
}
.buttons-row .btn
{
margin-bottom:9px;
}
.li-controls
{
display:inline-block;
width:180px;
vertical-align:middle;
}
.celled
{
display:inline-block;
padding: 4px 0 0 0;
vertical-align:top;
margin-top:4px;
width:700px;
}
.folder
{
border-left: 1px dotted #AAA;
}
.folder li
{
list-style-type:none;
}
.folder>i
{
display:inline-block;
width:5px;
height:5px;
border:1px solid;
background-color:#FAA732;
margin-left:-4px;
margin-top:-2px;
border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
border-radius:1px;
}
.folder>i+a
{
padding-left:0.5em;
}
.folder ul
{
margin-top:0.5em;
margin-bottom:0.5em;
}
.controls-inline .btn
{
margin-right:5px;
}
div.web2py_counter.span6
{
min-height:24px;
text-align:right;
}
.pagination
{
margin:0;
}
.table
{
margin-bottom:10px;
}
.row_buttons .btn
{
margin-right:4px;
}
.editor-bar-column
{
display:inline-block;
vertical-align:top;
margin-right:4px;
}
.editor-bar-column .input-long
{
width:270px;
}
.editor-bar-column .input-normal
{
width:206px;
}
.keybindings li
{
margin-bottom:0.5em;
}
.keybindings span
{
padding:0.3em;
border:1px solid transparent;
vertical-align:middle;
}
.teletype-text
{
font-family:monospace;
font-weight:bold;
font-style:normal;
border-color:#999;
background:#333;
color:#DDD;
-moz-border-radius:0.3em;
border-radius:0.3em;
}
.edit_language .tab_row div
{
display:inline-block;
vertical-align:top;
margin-right:4px;
}
.edit_language .fake-input
{
height:18px;
padding:4px;
font-size:13px;
line-height:18px;
overflow:hidden;
white-space:nowrap;
display:inline-block;
margin-bottom:9px;
}
.test h3
{
padding-left:9px;
margin:0;
font-size:16px;
line-height:1;
border-left:9px solid transparent;
}
.test h3.passed
{
border-color:#009900;
}
.test h3.failed
{
border-color:#CC0000;
}
.test h3.nodoctests
{
border-color:#CCCC99;
}
.test .test_report
{
width:100%;
overflow:auto;
}
.test_report pre
{
white-space:pre;
}
.test div[id^="output_"]>h2
{
font-size:18px;
line-height:1;
color:grey;
}
div.center
{
text-align:center;
}
.delete h2
{
word-wrap:break-word;
}
/*=============================================================
SHELL
==============================================================*/
.shell .output-wrapper
{
width:100%;
height:30em;
border:1px solid #333;
}
.shell .prompt-wrapper
{
float:left;
width:100%;
overflow:hidden;
height:auto;
border:1px solid #333;
}
.shell .prompt-container
{
margin-left:2.5em;
}
.shell #caret
{
width:2.5em;
float:left;
margin-left:-100%;
}
.shell #shellwrapper
{
background:white;
color:#E8953C;
width:100%;
margin:1em 0;
border:0;
}
.shell #output,
.shell .prompt
{
color:#E8953C;
background:white;
resize:none;
border:none;
width:100%;
height:100%;
cursor:default;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.shell #output:focus,
.shell .prompt:focus
{
border-color:transparent;
outline:0;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.shell #output pre
{
color: #E8953C;
}
.shell #autoscroll
{
cursor:pointer;
float:right;
}
.shell .prompt,
.shell #output,
.shell #caret
{
font-size: 11pt;
padding: 6px;
padding-right: 0em;
}
.shell #caret
{
padding-top:9px;
}
.shell .prompt,
.shell #output,
.shell pre,
.shell #caret
{
font-family: monospace;
}
.shell a[rel="tooltip"]
{
margin-left:8px;
}
/*=============================================================
PEEK
==============================================================*/
.peek .code-wrapper
{
width:100%;
overflow:auto;
white-space:pre;
}
.peek table td pre
{
word-break:normal;
white-space:pre;
}
/*=============================================================
FOOTER
==============================================================*/
#footer
{
border-top:1px solid;
text-align:center;
padding:1em 0;
}
#footer span,
#footer select
{
display:inline-block;
margin-bottom:0;
vertical-align:middle;
}
#footer select
{
width:auto;
}
/*=============================================================
MAIN
==============================================================*/
#main
{
margin-top:60px; /*uncomment this for alternative solution to hidden area underneath fixed navbar issue*/
margin-bottom:60px;
}
/*=============================================================
WIZARD
==============================================================*/
#wizard_nav .box
{
border-bottom:1px dotted;
}
#wizard_nav li
{
margin-left:1em;
margin-top:0.5em;
}
.step textarea
{
width:auto;
}
select[name='layout_theme']
{
vertical-align:top;
}
img#preview
{
margin-bottom:9px;
}
/* multiselect customization */
.ms-container
{
margin-bottom:5px;
}
.ms-selectable,
.step .ms-selection
{
text-align:center;
}
.ms-list
{
text-align:left;
background:white;
}
.ms-container li.ms-elem-selectable:not(.disabled).ms-hover,
.ms-container .ms-selection li:not(.disabled).ms-hover
{
background-color:#E8953C;
}
.ms-container .ms-selectable
{
margin-right:25px;
}
.ms-container .ms-selectable,
.ms-container .ms-selection
{
background:transparent;
}
.ms-container .ms-list.ms-focus
{
border-color:rgba(232,149,60,0.8);
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(232, 149, 60, 0.6);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(232,149,60,0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(232, 149, 60, 0.6);
}
/* grow_input */
ul[id$="_grow_input"]
{
margin-left:0;
}
/* generate_form*/
#generate_form .control-group
{
margin-bottom:0;
}
#generate_form .control-label
{
text-align:left;
}
#generate_form .controls
{
padding-left:18px;
margin-left:0;
}
#generate_form .control-label.empty
{
width:142px;
}
.step [rel="pagebookmark"]>.hashstick
{
display:none;
}
/*generated page*/
.generated iframe
{
border:1px inset #e3e3e3;
}
/*=============================================================
ERRORS TABLE / TICKET PAGE
==============================================================*/
.tablebar
{
margin:7px 0 7px 0;
}
.tablebar input
{
margin-right:27px;
}
.tablebar span
{
vertical-align:bottom;
}
.table th
{
background: #e9e9e9;
background: -moz-linear-gradient(top, #FAFAFA 0%, #E9E9E9 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FAFAFA), color-stop(100%,#E9E9E9));
background: -webkit-linear-gradient(top, #FAFAFA 0%,#E9E9E9 100%);
background: -o-linear-gradient(top, #FAFAFA 0%,#E9E9E9 100%);
background: -ms-linear-gradient(top, #FAFAFA 0%,#E9E9E9 100%);
background: linear-gradient(top, #FAFAFA 0%,#E9E9E9 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FAFAFA', endColorstr='#E9E9E9');
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#FAFAFA', endColorstr='#E9E9E9')";
/*font-size:10px;
color:#444;
text-transform:uppercase;*/
}
td.cbcentered,
th.cbcentered
{
text-align:center;
}
td.cbcentered>input,
th.cbcentered>input
{
margin-top:-1px;
}
.traceback div
{
}
.ticket_code>table td:first-child
{
border-left:0;
}
#trck_errors table td pre
{
word-break:normal;
white-space:pre;
}
.inspect pre,
.errorsource pre
{
word-break:normal;
white-space:pre;
}
.ticket_code
{
background-color:lightyellow;
}
.ticket_code table,
.ticket_code td
{
border-width:0px;
border-collapse:collapse;
width:100%;
}
.ticket_code tbody tr:hover td
{
background-color:transparent;
}
/*=============================================================
FLOT GRAPHS
==============================================================*/
.about #placeholder
{
width:auto;
max-width:600px;
height:300px;
position:relative;
margin:0 auto; /* for centering */
}
/*=============================================================
THE GRID
==============================================================*/
#w2p_query_panel
{
min-width:20px;
min-height:20px;
padding:10px;
margin-top:1em;
background-color:#f5f5f5;
border: 1px solid #e3e3e3;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
}
#w2p_query_panel select,
#w2p_query_panel input
{
margin-bottom:0;
margin-right:4px;
}
.web2py_grid .hidden
{
visibility:visible;
}
.qry_pnl_btns
{
display:inline-block;
}
#w2p_grid_addbtn,
#w2p_search-form
{
margin-top:9px;
margin-bottom:9px;
}
#w2p_search-form
{
margin-bottom:0;
}
#w2p_search-form form
{
margin-bottom:0;
}
/*----- translate page ---*/
.languageform input
{
margin-bottom:0;
}
.languageform input.untranslated
{
background-color:#FC0;
}
/*=============================================================
MEDIA QUERIES
==============================================================*/
@media (max-width: 800px)
{
.step [rel="pagebookmark"]>.hashstick
{
/*top:-54px;*/
display:block;
}
}
@media (max-width: 767px)
{
[rel="pagebookmark"]>.hashstick{top:0;}
/*-----------------------------------
main
-------------------------------------*/
#main
{
margin-top:0;
}
/*-----------------------------------
footer
-------------------------------------*/
#footer
{
margin-left: -20px;
margin-right: -20px;
padding-left: 20px;
padding-right: 20px;
}
/*-----------------------------------
errors page
-------------------------------------*/
#trck_errors
{
table-layout:fixed;
}
#trck_errors .column1
{
width:20px;
}
#trck_errors .column2
{
width:45px;
}
#trck_errors .column3
{
width:150px;
}
#trck_errors .columnN
{
width:55px;
}
#trck_errors .columnN1
{
width:138px;
}
.ticket_code,
.inspect.resp1,
.inspect.controls pre,
.errorsource
{
width:100%;
overflow:auto;
}
.ticket_code>table
{
width:100%;
}
.celled
{
width:320px;
}
}
@media (max-width: 480px)
{
.qry_pnl_btns
{
display:block;
margin-top:4px;
}
/*-----------------------------------
wizard
-------------------------------------*/
#generate_form .control-label
{
float:left;
width:160px;
padding-top:5px;
}
.inspect>code
{
display:block;
white-space:normal;
}
.li-controls
{
}
.celled
{
width:165px;
}
}
+58 -2
View File
@@ -1166,7 +1166,7 @@ ul#snapshot > li {
font-size: 1em;
color: #3C3C3D;
text-shadow: 1px 1px 0 #FFFFFF;
background:#ECECEC;
//background:#ECECEC;
white-space: nowrap; overflow: visible;
cursor: pointer; text-decoration: none;
border: 1px solid #CACACA;
@@ -1244,8 +1244,64 @@ color: #222;
border-radius:2px;
}
.ie9 #query_panel {padding-bottom:2px;}
.error, .error a {color:red}
.pluralsform thead td {font-weight:bold; font-size:1.2em; padding-bottom:5px}
.pluralsform td {padding-left:5px}
.tm_ftag {color:blue}
/*-----------------------------------*/
/* due to bootstrap layout
/*-----------------------------------*/
.navbar .btn-navbar{display:none;}
label{display:block;}
input{margin-bottom:5px;}
.login input{width:210px;}
.change_password input{width:210px;}
div.flash .close{color:inherit;float:right;}
label.checkbox{margin-bottom:5px;}
.control-group{margin-bottom:5px;}
.step #menu li{margin-left:0;margin-top:0;}
.step #wizard_nav{padding-top:0.5em;}
.hashstick{visibility:hidden;}
#generate_form .control-label{float:left;width:160px;padding-top:5px;text-align:left;}
#generate_form .controls > .checkbox:first-child{padding-top:7px;}
/* from default/errors.html */
table.sortable{border-spacing:0px;}
table.sortable td, table.sortable th{padding:2px 5px 2px 5px;}
table.sortable thead{background-color:#eee;color:#666666;font-weight:bold;cursor:default;}
tr.error_ticket:hover{background-color:#eee;}
.controls a.button.unavailable{color:#ff0000;}
/* end from default/errors.html */
/* new errors table */
.tablebar{margin:7px 0 7px 0;}
.cbcentered{text-align:center;}
/* new tooltip */
a[rel='tooltip']:hover{background:transparent;text-decoration:none;}
a[rel='tooltip'] span{display:none;padding:5px;margin-left:10px;width:150px;}
a[rel='tooltip']:hover span{cursor:default;display:inline;position:absolute;}
a[rel='tooltip'] span{background:#9fb364;color:#eef1d9;border:1px solid #eef1d9;font-style:italic;width:20%;padding:0.3em;-moz-border-radius:0.5em;border-radius:0.5em;font-size:13px;text-transform:none;}
/* flot graph */
.about #placeholder{width:600px;height:300px;margin:0 auto;}
.tophashlink.btn{visibility:hidden;}
.help-block{display:block;}
.w2p_grid_bottom_bar .w2p_export_menu{float:left;line-height:39px;margin-left:10px;}
.w2p_export_menu .dropdown-toggle{cursor:default;color:#333;margin:0;padding:0;background-image:none;}
.w2p_export_menu ul{display:inline-block;margin:0;vertical-align:middle;}
.w2p_export_menu li{list-style:none;display:inline-block;margin-right:4px;margin-left:2px;}
.edit_language .tab_row div{display:inline-block;vertical-align:top;margin-right:4px;}
.edit_language .tab_row>div{border:1px solid #e3e3e3;margin-bottom:20px;background-color:#f5f5f5;}
/* shell*/
.shell .output-wrapper{width:75%;height:30em;border:1px solid #333;}
.shell .prompt-wrapper{float:left;width:100%;overflow:hidden;height:auto;border:1px solid #333;}
.shell .prompt-container{margin-left:2.5em;}
.shell #caret{width:2.5em;float:left;margin-left:-100%;}
.shell #shellwrapper{background:white;color:#E8953C;width:75%;margin:1em 0;border:0;}
.shell #output,.shell .prompt{color:#E8953C;background:white;resize:none;border:none;width:100%;height:100%;cursor:default;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
.shell #output:focus,.shell .prompt:focus{border-color:transparent;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
.shell #output pre{color:#E8953C;}
.shell #autoscroll{cursor:pointer;float:right;}
.shell .prompt,.shell #output,.shell #caret{font-size:11pt;padding:6px;padding-right:0em;}
.shell .prompt,.shell #output,.shell pre,.shell #caret{font-family:monospace;}
.shell a[rel="tooltip"]{margin-left:8px;}
.shell .clearfix{clear:both;}
.shell #caret{padding-top:9px;}
+6 -2
View File
@@ -61,7 +61,7 @@ input[type=text],input[type=password],select{width:300px; margin-right:5px}
border-top:1px #DEDEDE solid;
}
.header {
// background:<fill here for header image>;
/* background:<fill here for header image>; */
}
@@ -115,6 +115,10 @@ div.flash {
z-index:2000;
}
div.flash #closeflash{color:inherit; float:right; margin-left:15px;}
.ie-lte7 div.flash #closeflash
{color:expression(this.parentNode.currentStyle['color']);float:none;position:absolute;right:4px;}
div.flash:hover { opacity:0.25; }
div.error_wrapper {display:block}
@@ -182,7 +186,7 @@ div.error {
* will look better with the declarations below
* if needed to remove base.css consider keeping these following lines in some css file.
*/
// .web2py_table {border:1px solid #ccc}
/* .web2py_table {border:1px solid #ccc} */
.web2py_paginator {}
.web2py_grid {width:100%}
.web2py_grid table {width:100%}
@@ -0,0 +1,231 @@
/*=============================================================
CUSTOM RULES
==============================================================*/
body{height:auto;} /* to avoid vertical scroll bar */
div.flash.flash-center{left:25%;right:25%;}
div.flash.flash-top,div.flash.flash-top:hover{
position:relative;
display:block;
margin:0;
padding:1em;
top:0;
left:0;
width:100%;
text-align:center;
text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);
color:#865100;
background:#feea9a;
border:1px solid;
border-top:0px;
border-left:0px;
border-right:0px;
border-radius:0;
opacity:1;
}
#header{margin-top:60px;}
.mastheader h1 {
margin-bottom:9px;
font-size:81px;
font-weight:bold;
letter-spacing:-1px;
line-height:1;
font-size:54px;
}
.mastheader small {
font-size:20px;
font-weight:300;
}
/* auth navbar - primitive style */
.auth_navbar,.auth_navbar a{color:inherit;}
.ie-lte7 .auth_navbar,.auth_navbar a{color:expression(this.parentNode.currentStyle['color']); /* ie7 doesn't support inherit */}
.auth_navbar a{white-space:nowrap;} /* to avoid the nav split on more lines */
.auth_navbar a:hover{color:white;text-decoration:none;}
ul#navbar>.auth_navbar{
display:inline-block;
padding:5px;
}
/* form errors message box customization */
div.error_wrapper{margin-bottom:9px;}
div.error_wrapper .error{
border-radius: 4px;
-o-border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
/* below rules are only for formstyle = bootstrap
trying to make errors look like bootstrap ones */
div.controls .error_wrapper{
display:inline-block;
margin-bottom:0;
vertical-align:middle;
}
div.controls .error{
min-width:5px;
background:inherit;
color:#B94A48;
border:none;
padding:0;
margin:0;
/*display:inline;*/ /* uncommenting this, the animation effect is lost */
}
div.controls .help-inline{color:#3A87AD;}
div.controls .error_wrapper +.help-inline {margin-left:-99999px;}
div.controls select +.error_wrapper {margin-left:5px;}
.ie-lte7 div.error{color:#fff;}
/* beautify brand */
.navbar-inverse .brand{color:#c6cecc;}
.navbar-inverse .brand b{display:inline-block;margin-top:-1px;}
.navbar-inverse .brand b>span{font-size:22px;color:white}
.navbar-inverse .brand:hover b>span{color:white}
/* beautify web2py link in navbar */
span.highlighted{color:#d8d800;}
.open span.highlighted{color:#ffff00;}
/*=============================================================
OVERRIDING WEB2PY.CSS RULES
==============================================================*/
/* reset to default */
a{white-space:normal;}
li{margin-bottom:0;}
textarea,button{display:block;}
/*reset ul padding */
ul#navbar{padding:0;}
/* label aligned to related input */
td.w2p_fl,td.w2p_fc {padding:0;}
#web2py_user_form td{vertical-align:middle;}
/*=============================================================
OVERRIDING BOOTSTRAP.CSS RULES
==============================================================*/
/* because web2py handles this via js */
.hidden{visibility:visible;}
/* right folder for bootstrap black images/icons */
[class^="icon-"],[class*=" icon-"]{
background-image:url("../images/glyphicons-halflings.png")
}
/* right folder for bootstrap white images/icons */
.icon-white,
.nav-tabs > .active > a > [class^="icon-"],
.nav-tabs > .active > a > [class*=" icon-"],
.nav-pills > .active > a > [class^="icon-"],
.nav-pills > .active > a > [class*=" icon-"],
.nav-list > .active > a > [class^="icon-"],
.nav-list > .active > a > [class*=" icon-"],
.navbar-inverse .nav > .active > a > [class^="icon-"],
.navbar-inverse .nav > .active > a > [class*=" icon-"],
.dropdown-menu > li > a:hover > [class^="icon-"],
.dropdown-menu > li > a:hover > [class*=" icon-"],
.dropdown-menu > .active > a > [class^="icon-"],
.dropdown-menu > .active > a > [class*=" icon-"] {
background-image:url("../images/glyphicons-halflings-white.png");
}
/* bootstrap has a label as input's wrapper while web2py has a div */
div>input[type="radio"],div>input[type="checkbox"]{margin:0;}
/* bootstrap has button instead of input */
input[type="button"], input[type="submit"]{margin-right:8px;}
/*=============================================================
RULES FOR SOLVING CONFLICTS BETWEEN WEB2PY.CSS AND BOOTSTRAP.CSS
==============================================================*/
/*when formstyle=table3cols*/
tr#auth_user_remember__row>td.w2p_fw>div{padding-bottom:8px;}
td.w2p_fw div>label{vertical-align:middle;}
td.w2p_fc {padding-bottom:5px;}
/*when formstyle=divs*/
div#auth_user_remember__row{margin-top:4px;}
div#auth_user_remember__row>.w2p_fl{display:none;}
div#auth_user_remember__row>.w2p_fw{min-height:39px;}
div.w2p_fw,div.w2p_fc{
display:inline-block;
vertical-align:middle;
margin-bottom:0;
}
div.w2p_fc{
padding-left:5px;
margin-top:-8px;
}
/*when formstyle=ul*/
form>ul{
list-style:none;
margin:0;
}
li#auth_user_remember__row{margin-top:4px;}
li#auth_user_remember__row>.w2p_fl{display:none;}
li#auth_user_remember__row>.w2p_fw{min-height:39px;}
/*when formstyle=bootstrap*/
#auth_user_remember__row label.checkbox{display:block;}
span.inline-help{display:inline-block;}
input[type="text"].input-xlarge,input[type="password"].input-xlarge{width:270px;}
/*when recaptcha is used*/
#recaptcha{min-height:30px;display:inline-block;margin-bottom:0;line-height:30px;vertical-align:middle;}
td>#recaptcha{margin-bottom:6px;}
div>#recaptcha{margin-bottom:9px;}
div.control-group.error{
width:auto;
background:transparent;
border:0;
color:inherit;
padding:0;
background-repeat:repeat;
}
/*=============================================================
OTHER RULES
==============================================================*/
/* Massimo Di Pierro fixed alignment in forms with list:string */
form table tr{margin-bottom:9px;}
td.w2p_fw ul{margin-left:0px;}
/* web2py_console in grid and smartgrid */
.hidden{visibility:visible;}
.web2py_console input{
display: inline-block;
margin-bottom: 0;
vertical-align: middle;
}
.web2py_console input[type="submit"],
.web2py_console input[type="button"],
.web2py_console button{
padding-top:4px;
padding-bottom:4px;
margin:3px 0 0 2px;
}
.web2py_console a,
.web2py_console select,
.web2py_console input
{
margin:3px 0 0 2px;
}
.web2py_grid form table{width:auto;}
/* auth_user_remember checkbox extrapadding in IE fix */
.ie-lte9 input#auth_user_remember.checkbox {padding-left:0;}
/*=============================================================
MEDIA QUERIES
==============================================================*/
@media only screen and (max-width:979px){
body{padding-top:0px;}
#navbar{top:5px;}
div.flash{right:5px;}
.dropdown-menu ul{visibility:visible;}
}
@media only screen and (max-width:479px){
body{
padding-left:10px;
padding-right:10px;
}
.navbar-fixed-top,.navbar-fixed-bottom {
margin-left:-10px;
margin-right:-10px;
}
input[type="text"],input[type="password"],select{
width:95%;
}
}
@@ -0,0 +1,122 @@
/*=============================================================
BOOTSTRAP DROPDOWN MENU
==============================================================*/
.dropdown-menu ul{
left:100%;
position:absolute;
top:0;
visibility:hidden;
margin-top:-1px;
}
.dropdown-menu li:hover ul{visibility:visible;}
.navbar .dropdown-menu ul:before{
border-bottom:7px solid transparent;
border-left:none;
border-right:7px solid rgba(0, 0, 0, 0.2);
border-top:7px solid transparent;
left:-7px;
top:5px;
}
.nav > li.dropdown > a:after {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid #000000;
content: "";
display: inline-block;
height: 0;
opacity: 0.7;
vertical-align: top;
width: 0;
margin-left: 2px;
margin-top: 8px;
border-bottom-color: #FFFFFF;
border-top-color: #FFFFFF;
}
.dropdown-menu span{display:inline-block;}
ul.dropdown-menu li.dropdown > a:after {
border-left: 4px solid #000;
border-right: 4px solid transparent;
border-bottom: 4px solid transparent;
border-top: 4px solid transparent;
content: "";
display: inline-block;
height: 0;
opacity: 0.7;
vertical-align: top;
width: 0;
margin-left: 8px;
margin-top: 6px;
}
ul.nav li.dropdown:hover ul.dropdown-menu {
display: block;
}
.open >.dropdown-menu ul{display:block;} /* fix menu issue when BS2.0.4 is applied */
/*=============================================================
BOOTSTRAP SUBMIT BUTTON
==============================================================*/
input[type='submit']:not(.btn) {
display: inline-block;
padding: 4px 14px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
color: #333;
text-align: center;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
vertical-align: middle;
cursor: pointer;
background-color: whiteSmoke;
background-image: -webkit-gradient(linear,0 0,0 100%,from(white),to(#E6E6E6));
background-image: -webkit-linear-gradient(top,white,#E6E6E6);
background-image: -o-linear-gradient(top,white,#E6E6E6);
background-image: linear-gradient(to bottom,white,#E6E6E6);
background-image: -moz-linear-gradient(top,white,#E6E6E6);
background-repeat: repeat-x;
border: 1px solid #BBB;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
border-bottom-color: #A2A2A2;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);
filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);
}
input[type='submit']:not(.btn):hover {
color: #333;
text-decoration: none;
background-color: #E6E6E6;
background-position: 0 -15px;
-webkit-transition: background-position .1s linear;
-moz-transition: background-position .1s linear;
-o-transition: background-position .1s linear;
transition: background-position .1s linear;
}
input[type='submit']:not(.btn).active, input[type='submit']:not(.btn):active {
background-color: #E6E6E6;
background-color: #D9D9D9 9;
background-image: none;
outline: 0;
-webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
}
/*=============================================================
OTHER
==============================================================*/
.ie-lte8 .navbar-fixed-top {position:static;}
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+15 -4
View File
@@ -170,15 +170,26 @@ function doToggleBreakpoint(filename, url) {
success: function(json,text,xhr){
// show flash message (if any)
var flash=xhr.getResponseHeader('web2py-component-flash');
if (flash) jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
if (flash) {
jQuery('.flash').html(decodeURIComponent(flash))
.append('<a href="#" class="close">&times;</a>')
.slideDown();
}
else jQuery('.flash').hide();
try {
if (json.error) {
window.location.href=json.redirect;
} else {
// mark the breakpoint if ok=True
// remove mark if ok=False
// do nothing if ok = null
if (json.ok==true && window.mirror) {
// mark the breakpoint if ok=True
editor.setMarker(json.lineno-1,
"<span style='color: red'>●</span> %N%")
} else if (json.ok==false && window.mirror) {
// remove mark if ok=False
editor.setMarker(json.lineno-1, "%N%")
} else {
// do nothing if ok = null
}
// alert(json.ok + json.lineno);
}
} catch(e) { on_error(); }
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,60 @@
/*
Flot plugin for automatically redrawing plots when the placeholder
size changes, e.g. on window resizes.
It works by listening for changes on the placeholder div (through the
jQuery resize event plugin) - if the size changes, it will redraw the
plot.
There are no options. If you need to disable the plugin for some
plots, you can just fix the size of their placeholders.
*/
/* Inline dependency:
* jQuery resize event - v1.1 - 3/14/2010
* http://benalman.com/projects/jquery-resize-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
(function ($) {
var options = { }; // no options
function init(plot) {
function onResize() {
var placeholder = plot.getPlaceholder();
// somebody might have hidden us and we can't plot
// when we don't have the dimensions
if (placeholder.width() == 0 || placeholder.height() == 0)
return;
plot.resize();
plot.setupGrid();
plot.draw();
}
function bindEvents(plot, eventHolder) {
plot.getPlaceholder().resize(onResize);
}
function shutdown(plot, eventHolder) {
plot.getPlaceholder().unbind("resize", onResize);
}
plot.hooks.bindEvents.push(bindEvents);
plot.hooks.shutdown.push(shutdown);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'resize',
version: '1.0'
});
})(jQuery);
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+44
View File
@@ -0,0 +1,44 @@
/**
Created and copyrighted by Massimo Di Pierro <massimo.dipierro@gmail.com>
(MIT license)
Example:
<script src="share.js"></script>
**/
jQuery(function(){
var script_source = jQuery('script[src*="share.js"]').attr('src');
var params = function(name,default_value) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(script_source);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '))||default_value;
}
var path = params('static','social');
var url = encodeURIComponent(window.location.href);
var host = window.location.hostname;
var title = escape(jQuery('title').text());
var twit = 'http://twitter.com/home?status='+title+'%20'+url;
var facebook = 'http://www.facebook.com/sharer.php?u='+url;
var gplus = 'https://plus.google.com/share?url='+url;
var tbar = '<div id="socialdrawer"><span>Share<br/></span><div id="sicons"><a href="'+twit+'" id="twit" title="Share on twitter"><img src="'+path+'/twitter.png" alt="Share on Twitter" width="32" height="32" /></a><a href="'+facebook+'" id="facebook" title="Share on Facebook"><img src="'+path+'/facebook.png" alt="Share on facebook" width="32" height="32" /></a><a href="'+gplus+'" id="gplus" title="Share on Google Plus"><img src="'+path+'/gplus-32.png" alt="Share on Google Plus" width="32" height="32" /></a></div></div>';
// Add the share tool bar.
jQuery('body').append(tbar);
var st = jQuery('#socialdrawer');
st.css({'opacity':'.7','z-index':'3000','background':'#FFF','border':'solid 1px #666','border-width':' 1px 0 0 1px','height':'20px','width':'40px','position':'fixed','bottom':'0','right':'0','padding':'2px 5px','overflow':'hidden','-webkit-border-top-left-radius':' 12px','-moz-border-radius-topleft':' 12px','border-top-left-radius':' 12px','-moz-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','-webkit-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)'});
jQuery('#socialdrawer a').css({'float':'left','width':'32px','margin':'3px 2px 2px 2px','padding':'0','cursor':'pointer'});
jQuery('#socialdrawer span').css({'float':'left','margin':'2px 3px','text-shadow':' 1px 1px 1px #FFF','color':'#444','font-size':'12px','line-height':'1em'});
jQuery('#socialdrawer img').hide();
// hover
st.click(function(){
jQuery(this).animate({height:'40px', width:'160px', opacity: 0.95}, 300);
jQuery('#socialdrawer img').show();
});
//leave
st.mouseleave(function(){
st.animate({height:'20px', width: '40px', opacity: .7}, 300);
jQuery('#socialdrawer img').hide();
return false;
} );
});
+17 -4
View File
@@ -50,12 +50,19 @@ function web2py_event_handlers() {
window.location = redirect;
};
});
doc.ajaxError(function(e, xhr, settings, exception) {
doc.off('click', '.flash')
switch(xhr.status){
case 500:
$('.flash').html(ajax_error_500).slideDown();
}
});
};
jQuery(function() {
var flash = jQuery('.flash');
flash.hide();
if(flash.html()) flash.append('<span style="float:right;">&times;</span>').slideDown();
if(flash.html()) flash.append('<span id="closeflash">&times;</span>').slideDown();
web2py_ajax_init(document);
web2py_event_handlers();
});
@@ -102,15 +109,20 @@ function web2py_ajax_page(method, action, data, target) {
web2py_ajax_init('#'+target);
if(command)
eval(decodeURIComponent(command));
if(flash)
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
if(flash) {
jQuery('.flash')
.html(decodeURIComponent(flash))
.append('<span id="closeflash">&times;</span>')
.slideDown();
}
}
});
}
function web2py_component(action, target, timeout, times){
jQuery(function(){
var element = jQuery("#" + target).get(0);
var jelement = jQuery("#" + target);
var element = jelement.get(0);
var statement = "jQuery('#" + target + "').get(0).reload();";
element.reload = function (){
// Continue if times is Infinity or
@@ -119,6 +131,7 @@ function web2py_component(action, target, timeout, times){
web2py_ajax_page('get', action, null, target);} }; // reload
// Method to check timing limit
element.reload_check = function (){
if (jelement.hasClass('w2p_component_stop')) {return false;}
if (this.reload_counter == Infinity){return true;}
else {
if (!isNaN(this.reload_counter)){
@@ -0,0 +1,28 @@
// this code improves bootstrap menus and adds dropdown support
jQuery(function(){
jQuery('.nav>li>a').each(function(){
if(jQuery(this).parent().find('ul').length)
jQuery(this).attr({'class':'dropdown-toggle','data-toggle':'dropdown'}).append('<b class="caret"></b>');
});
jQuery('.nav li li').each(function(){
if(jQuery(this).find('ul').length)
jQuery(this).addClass('dropdown-submenu');
});
function hoverMenu(){
var wid = document.documentElement.clientWidth; //faster than $(window).width() and cross browser
if (wid>=980){
jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
mi = jQuery(this).addClass('open');
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400);
}, function(){
mi = jQuery(this);
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')});
});
};
}
hoverMenu(); // first page load
jQuery(window).resize(hoverMenu); // on resize event
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
// make all buttons bootstrap buttons
jQuery('button, form input[type="submit"], form input[type="button"]').addClass('btn');
});
File diff suppressed because one or more lines are too long
@@ -0,0 +1,173 @@
/*! jQuery Mobile v1.0 jquerymobile.com | jquery.org/license */
(function(a,e){if(a.cleanData){var b=a.cleanData;a.cleanData=function(f){for(var c=0,h;(h=f[c])!=null;c++)a(h).triggerHandler("remove");b(f)}}else{var d=a.fn.remove;a.fn.remove=function(b,c){return this.each(function(){c||(!b||a.filter(b,[this]).length)&&a("*",this).add([this]).each(function(){a(this).triggerHandler("remove")});return d.call(a(this),b,c)})}}a.widget=function(b,c,h){var d=b.split(".")[0],e,b=b.split(".")[1];e=d+"-"+b;if(!h)h=c,c=a.Widget;a.expr[":"][e]=function(c){return!!a.data(c,
b)};a[d]=a[d]||{};a[d][b]=function(a,b){arguments.length&&this._createWidget(a,b)};c=new c;c.options=a.extend(true,{},c.options);a[d][b].prototype=a.extend(true,c,{namespace:d,widgetName:b,widgetEventPrefix:a[d][b].prototype.widgetEventPrefix||b,widgetBaseClass:e},h);a.widget.bridge(b,a[d][b])};a.widget.bridge=function(b,c){a.fn[b]=function(d){var g=typeof d==="string",i=Array.prototype.slice.call(arguments,1),k=this,d=!g&&i.length?a.extend.apply(null,[true,d].concat(i)):d;if(g&&d.charAt(0)==="_")return k;
g?this.each(function(){var c=a.data(this,b);if(!c)throw"cannot call methods on "+b+" prior to initialization; attempted to call method '"+d+"'";if(!a.isFunction(c[d]))throw"no such method '"+d+"' for "+b+" widget instance";var g=c[d].apply(c,i);if(g!==c&&g!==e)return k=g,false}):this.each(function(){var e=a.data(this,b);e?e.option(d||{})._init():a.data(this,b,new c(d,this))});return k}};a.Widget=function(a,b){arguments.length&&this._createWidget(a,b)};a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",
options:{disabled:false},_createWidget:function(b,c){a.data(c,this.widgetName,this);this.element=a(c);this.options=a.extend(true,{},this.options,this._getCreateOptions(),b);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){var b={};a.metadata&&(b=a.metadata.get(element)[this.widgetName]);return b},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);
this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(b,c){var d=b;if(arguments.length===0)return a.extend({},this.options);if(typeof b==="string"){if(c===e)return this.options[b];d={};d[b]=c}this._setOptions(d);return this},_setOptions:function(b){var c=this;a.each(b,function(a,b){c._setOption(a,b)});return this},_setOption:function(a,b){this.options[a]=b;a==="disabled"&&
this.widget()[b?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",b);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(b,c,d){var e=this.options[b],c=a.Event(c);c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase();d=d||{};if(c.originalEvent)for(var b=a.event.props.length,i;b;)i=a.event.props[--b],c[i]=c.originalEvent[i];this.element.trigger(c,
d);return!(a.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
(function(a,e){a.widget("mobile.widget",{_createWidget:function(){a.Widget.prototype._createWidget.apply(this,arguments);this._trigger("init")},_getCreateOptions:function(){var b=this.element,d={};a.each(this.options,function(a){var c=b.jqmData(a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()}));c!==e&&(d[a]=c)});return d},enhanceWithin:function(b){var d=a(b).closest(":jqmData(role='page')").data("page"),d=d&&d.keepNativeSelector()||"";a(this.options.initSelector,b).not(d)[this.widgetName]()}})})(jQuery);
(function(a){a(window);var e=a("html");a.mobile.media=function(){var b={},d=a("<div id='jquery-mediatest'>"),f=a("<body>").append(d);return function(a){if(!(a in b)){var h=document.createElement("style"),g="@media "+a+" { #jquery-mediatest { position:absolute; } }";h.type="text/css";h.styleSheet?h.styleSheet.cssText=g:h.appendChild(document.createTextNode(g));e.prepend(f).prepend(h);b[a]=d.css("position")==="absolute";f.add(h).remove()}return b[a]}}()})(jQuery);
(function(a,e){function b(a){var b=a.charAt(0).toUpperCase()+a.substr(1),a=(a+" "+c.join(b+" ")+b).split(" "),d;for(d in a)if(f[a[d]]!==e)return true}var d=a("<body>").prependTo("html"),f=d[0].style,c=["Webkit","Moz","O"],h="palmGetResource"in window,g=window.operamini&&{}.toString.call(window.operamini)==="[object OperaMini]",i=window.blackberry;a.mobile.browser={};a.mobile.browser.ie=function(){for(var a=3,b=document.createElement("div"),c=b.all||[];b.innerHTML="<\!--[if gt IE "+ ++a+"]><br><![endif]--\>",
c[0];);return a>4?a:!a}();a.extend(a.support,{orientation:"orientation"in window&&"onorientationchange"in window,touch:"ontouchend"in document,cssTransitions:"WebKitTransitionEvent"in window,pushState:"pushState"in history&&"replaceState"in history,mediaquery:a.mobile.media("only all"),cssPseudoElement:!!b("content"),touchOverflow:!!b("overflowScrolling"),boxShadow:!!b("boxShadow")&&!i,scrollTop:("pageXOffset"in window||"scrollTop"in document.documentElement||"scrollTop"in d[0])&&!h&&!g,dynamicBaseTag:function(){var b=
location.protocol+"//"+location.host+location.pathname+"ui-dir/",c=a("head base"),f=null,e="",h;c.length?e=c.attr("href"):c=f=a("<base>",{href:b}).appendTo("head");h=a("<a href='testurl' />").prependTo(d)[0].href;c[0].href=e||location.pathname;f&&f.remove();return h.indexOf(b)===0}()});d.remove();h=function(){var a=window.navigator.userAgent;return a.indexOf("Nokia")>-1&&(a.indexOf("Symbian/3")>-1||a.indexOf("Series60/5")>-1)&&a.indexOf("AppleWebKit")>-1&&a.match(/(BrowserNG|NokiaBrowser)\/7\.[0-3]/)}();
a.mobile.ajaxBlacklist=window.blackberry&&!window.WebKitPoint||g||h;h&&a(function(){a("head link[rel='stylesheet']").attr("rel","alternate stylesheet").attr("rel","stylesheet")});a.support.boxShadow||a("html").addClass("ui-mobile-nosupport-boxshadow")})(jQuery);
(function(a,e,b,d){function f(a){for(;a&&typeof a.originalEvent!=="undefined";)a=a.originalEvent;return a}function c(b){for(var c={},f,d;b;){f=a.data(b,n);for(d in f)if(f[d])c[d]=c.hasVirtualBinding=true;b=b.parentNode}return c}function h(){v&&(clearTimeout(v),v=0);v=setTimeout(function(){E=v=0;u.length=0;D=false;y=true},a.vmouse.resetTimerDuration)}function g(b,c,r){var e,h;if(!(h=r&&r[b])){if(r=!r)a:{for(r=c.target;r;){if((h=a.data(r,n))&&(!b||h[b]))break a;r=r.parentNode}r=null}h=r}if(h){e=c;var r=
e.type,j,g;e=a.Event(e);e.type=b;h=e.originalEvent;j=a.event.props;if(h)for(g=j.length;g;)b=j[--g],e[b]=h[b];if(r.search(/mouse(down|up)|click/)>-1&&!e.which)e.which=1;if(r.search(/^touch/)!==-1&&(b=f(h),r=b.touches,b=b.changedTouches,r=r&&r.length?r[0]:b&&b.length?b[0]:d))for(h=0,len=z.length;h<len;h++)b=z[h],e[b]=r[b];a(c.target).trigger(e)}return e}function i(b){var c=a.data(b.target,A);if(!D&&(!E||E!==c))if(c=g("v"+b.type,b))c.isDefaultPrevented()&&b.preventDefault(),c.isPropagationStopped()&&
b.stopPropagation(),c.isImmediatePropagationStopped()&&b.stopImmediatePropagation()}function k(b){var d=f(b).touches,e;if(d&&d.length===1&&(e=b.target,d=c(e),d.hasVirtualBinding))E=r++,a.data(e,A,E),v&&(clearTimeout(v),v=0),w=y=false,e=f(b).touches[0],x=e.pageX,t=e.pageY,g("vmouseover",b,d),g("vmousedown",b,d)}function l(a){y||(w||g("vmousecancel",a,c(a.target)),w=true,h())}function o(b){if(!y){var d=f(b).touches[0],r=w,e=a.vmouse.moveDistanceThreshold;w=w||Math.abs(d.pageX-x)>e||Math.abs(d.pageY-
t)>e;flags=c(b.target);w&&!r&&g("vmousecancel",b,flags);g("vmousemove",b,flags);h()}}function m(a){if(!y){y=true;var b=c(a.target),d;g("vmouseup",a,b);if(!w&&(d=g("vclick",a,b))&&d.isDefaultPrevented())d=f(a).changedTouches[0],u.push({touchID:E,x:d.clientX,y:d.clientY}),D=true;g("vmouseout",a,b);w=false;h()}}function p(b){var b=a.data(b,n),c;if(b)for(c in b)if(b[c])return true;return false}function j(){}function q(b){var c=b.substr(1);return{setup:function(){p(this)||a.data(this,n,{});a.data(this,
n)[b]=true;s[b]=(s[b]||0)+1;s[b]===1&&B.bind(c,i);a(this).bind(c,j);if(C)s.touchstart=(s.touchstart||0)+1,s.touchstart===1&&B.bind("touchstart",k).bind("touchend",m).bind("touchmove",o).bind("scroll",l)},teardown:function(){--s[b];s[b]||B.unbind(c,i);C&&(--s.touchstart,s.touchstart||B.unbind("touchstart",k).unbind("touchmove",o).unbind("touchend",m).unbind("scroll",l));var d=a(this),f=a.data(this,n);f&&(f[b]=false);d.unbind(c,j);p(this)||d.removeData(n)}}}var n="virtualMouseBindings",A="virtualTouchID",
e="vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split(" "),z="clientX clientY pageX pageY screenX screenY".split(" "),s={},v=0,x=0,t=0,w=false,u=[],D=false,y=false,C="addEventListener"in b,B=a(b),r=1,E=0;a.vmouse={moveDistanceThreshold:10,clickDistanceThreshold:10,resetTimerDuration:1500};for(var F=0;F<e.length;F++)a.event.special[e[F]]=q(e[F]);C&&b.addEventListener("click",function(b){var c=u.length,d=b.target,f,r,e,h,j;if(c){f=b.clientX;r=b.clientY;threshold=a.vmouse.clickDistanceThreshold;
for(e=d;e;){for(h=0;h<c;h++)if(j=u[h],e===d&&Math.abs(j.x-f)<threshold&&Math.abs(j.y-r)<threshold||a.data(e,A)===j.touchID){b.preventDefault();b.stopPropagation();return}e=e.parentNode}}},true)})(jQuery,window,document);
(function(a,e,b){function d(b,c,d){var f=d.type;d.type=c;a.event.handle.call(b,d);d.type=f}a.each("touchstart touchmove touchend orientationchange throttledresize tap taphold swipe swipeleft swiperight scrollstart scrollstop".split(" "),function(b,c){a.fn[c]=function(a){return a?this.bind(c,a):this.trigger(c)};a.attrFn[c]=true});var f=a.support.touch,c=f?"touchstart":"mousedown",h=f?"touchend":"mouseup",g=f?"touchmove":"mousemove";a.event.special.scrollstart={enabled:true,setup:function(){function b(a,
e){f=e;d(c,f?"scrollstart":"scrollstop",a)}var c=this,f,e;a(c).bind("touchmove scroll",function(c){a.event.special.scrollstart.enabled&&(f||b(c,true),clearTimeout(e),e=setTimeout(function(){b(c,false)},50))})}};a.event.special.tap={setup:function(){var b=this,c=a(b);c.bind("vmousedown",function(f){function e(){clearTimeout(q)}function h(){e();c.unbind("vclick",g).unbind("vmouseup",e).unbind("vmousecancel",h)}function g(a){h();j==a.target&&d(b,"tap",a)}if(f.which&&f.which!==1)return false;var j=f.target,
q;c.bind("vmousecancel",h).bind("vmouseup",e).bind("vclick",g);q=setTimeout(function(){d(b,"taphold",a.Event("taphold"))},750)})}};a.event.special.swipe={scrollSupressionThreshold:10,durationThreshold:1E3,horizontalDistanceThreshold:30,verticalDistanceThreshold:75,setup:function(){var d=a(this);d.bind(c,function(c){function f(b){if(m){var c=b.originalEvent.touches?b.originalEvent.touches[0]:b;p={time:(new Date).getTime(),coords:[c.pageX,c.pageY]};Math.abs(m.coords[0]-p.coords[0])>a.event.special.swipe.scrollSupressionThreshold&&
b.preventDefault()}}var e=c.originalEvent.touches?c.originalEvent.touches[0]:c,m={time:(new Date).getTime(),coords:[e.pageX,e.pageY],origin:a(c.target)},p;d.bind(g,f).one(h,function(){d.unbind(g,f);m&&p&&p.time-m.time<a.event.special.swipe.durationThreshold&&Math.abs(m.coords[0]-p.coords[0])>a.event.special.swipe.horizontalDistanceThreshold&&Math.abs(m.coords[1]-p.coords[1])<a.event.special.swipe.verticalDistanceThreshold&&m.origin.trigger("swipe").trigger(m.coords[0]>p.coords[0]?"swipeleft":"swiperight");
m=p=b})})}};(function(a,b){function c(){var a=f();a!==e&&(e=a,d.trigger("orientationchange"))}var d=a(b),f,e;a.event.special.orientationchange={setup:function(){if(a.support.orientation&&a.mobile.orientationChangeEnabled)return false;e=f();d.bind("throttledresize",c)},teardown:function(){if(a.support.orientation&&a.mobile.orientationChangeEnabled)return false;d.unbind("throttledresize",c)},add:function(a){var b=a.handler;a.handler=function(a){a.orientation=f();return b.apply(this,arguments)}}};a.event.special.orientationchange.orientation=
f=function(){var c=true,c=document.documentElement;return(c=a.support.orientation?b.orientation%180==0:c&&c.clientWidth/c.clientHeight<1.1)?"portrait":"landscape"}})(jQuery,e);(function(){a.event.special.throttledresize={setup:function(){a(this).bind("resize",b)},teardown:function(){a(this).unbind("resize",b)}};var b=function(){f=(new Date).getTime();e=f-c;e>=250?(c=f,a(this).trigger("throttledresize")):(d&&clearTimeout(d),d=setTimeout(b,250-e))},c=0,d,f,e})();a.each({scrollstop:"scrollstart",taphold:"tap",
swipeleft:"swipe",swiperight:"swipe"},function(b,c){a.event.special[b]={setup:function(){a(this).bind(c,a.noop)}}})})(jQuery,this);
(function(a,e,b){function d(a){a=a||location.href;return"#"+a.replace(/^[^#]*#?(.*)$/,"$1")}var f="hashchange",c=document,h,g=a.event.special,i=c.documentMode,k="on"+f in e&&(i===b||i>7);a.fn[f]=function(a){return a?this.bind(f,a):this.trigger(f)};a.fn[f].delay=50;g[f]=a.extend(g[f],{setup:function(){if(k)return false;a(h.start)},teardown:function(){if(k)return false;a(h.stop)}});h=function(){function h(){var b=d(),c=n(p);if(b!==p)q(p=b,c),a(e).trigger(f);else if(c!==p)location.href=location.href.replace(/#.*/,
"")+c;i=setTimeout(h,a.fn[f].delay)}var g={},i,p=d(),j=function(a){return a},q=j,n=j;g.start=function(){i||h()};g.stop=function(){i&&clearTimeout(i);i=b};a.browser.msie&&!k&&function(){var b,e;g.start=function(){if(!b)e=(e=a.fn[f].src)&&e+d(),b=a('<iframe tabindex="-1" title="empty"/>').hide().one("load",function(){e||q(d());h()}).attr("src",e||"javascript:0").insertAfter("body")[0].contentWindow,c.onpropertychange=function(){try{if(event.propertyName==="title")b.document.title=c.title}catch(a){}}};
g.stop=j;n=function(){return d(b.location.href)};q=function(d,e){var h=b.document,g=a.fn[f].domain;if(d!==e)h.title=c.title,h.open(),g&&h.write('<script>document.domain="'+g+'"<\/script>'),h.close(),b.location.hash=d}}();return g}()})(jQuery,this);
(function(a){a.widget("mobile.page",a.mobile.widget,{options:{theme:"c",domCache:false,keepNativeDefault:":jqmData(role='none'), :jqmData(role='nojs')"},_create:function(){this._trigger("beforecreate");this.element.attr("tabindex","0").addClass("ui-page ui-body-"+this.options.theme)},keepNativeSelector:function(){var e=this.options;return e.keepNative&&a.trim(e.keepNative)&&e.keepNative!==e.keepNativeDefault?[e.keepNative,e.keepNativeDefault].join(", "):e.keepNativeDefault}})})(jQuery);
(function(a,e){var b={};a.extend(a.mobile,{ns:"",subPageUrlKey:"ui-page",activePageClass:"ui-page-active",activeBtnClass:"ui-btn-active",ajaxEnabled:true,hashListeningEnabled:true,linkBindingEnabled:true,defaultPageTransition:"slide",minScrollBack:250,defaultDialogTransition:"pop",loadingMessage:"loading",pageLoadErrorMessage:"Error Loading Page",autoInitializePage:true,pushStateEnabled:true,orientationChangeEnabled:true,gradeA:function(){return a.support.mediaquery||a.mobile.browser.ie&&a.mobile.browser.ie>=
7},keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91},silentScroll:function(b){if(a.type(b)!=="number")b=a.mobile.defaultHomeScroll;a.event.special.scrollstart.enabled=false;
setTimeout(function(){e.scrollTo(0,b);a(document).trigger("silentscroll",{x:0,y:b})},20);setTimeout(function(){a.event.special.scrollstart.enabled=true},150)},nsNormalizeDict:b,nsNormalize:function(c){return!c?void 0:b[c]||(b[c]=a.camelCase(a.mobile.ns+c))},getInheritedTheme:function(a,b){for(var d=a[0],f="",e=/ui-(bar|body)-([a-z])\b/,l,o;d;){l=d.className||"";if((o=e.exec(l))&&(f=o[2]))break;d=d.parentNode}return f||b||"a"}});a.fn.jqmData=function(b,d){var f;typeof b!="undefined"&&(f=this.data(b?
a.mobile.nsNormalize(b):b,d));return f};a.jqmData=function(b,d,f){var e;typeof d!="undefined"&&(e=a.data(b,d?a.mobile.nsNormalize(d):d,f));return e};a.fn.jqmRemoveData=function(b){return this.removeData(a.mobile.nsNormalize(b))};a.jqmRemoveData=function(b,d){return a.removeData(b,a.mobile.nsNormalize(d))};a.fn.removeWithDependents=function(){a.removeWithDependents(this)};a.removeWithDependents=function(b){b=a(b);(b.jqmData("dependents")||a()).remove();b.remove()};a.fn.addDependents=function(b){a.addDependents(a(this),
b)};a.addDependents=function(b,d){var f=a(b).jqmData("dependents")||a();a(b).jqmData("dependents",a.merge(f,d))};a.fn.getEncodedText=function(){return a("<div/>").text(a(this).text()).html()};var d=a.find,f=/:jqmData\(([^)]*)\)/g;a.find=function(b,e,g,i){b=b.replace(f,"[data-"+(a.mobile.ns||"")+"$1]");return d.call(this,b,e,g,i)};a.extend(a.find,d);a.find.matches=function(b,d){return a.find(b,null,null,d)};a.find.matchesSelector=function(b,d){return a.find(d,null,null,[b]).length>0}})(jQuery,this);
(function(a,e){function b(a){var b=a.find(".ui-title:eq(0)");b.length?b.focus():a.focus()}function d(b){q&&(!q.closest(".ui-page-active").length||b)&&q.removeClass(a.mobile.activeBtnClass);q=null}function f(){z=false;A.length>0&&a.mobile.changePage.apply(null,A.pop())}function c(c,d,f,e){var g=a.mobile.urlHistory.getActive(),j=a.support.touchOverflow&&a.mobile.touchOverflowEnabled,i=g.lastScroll||(j?0:a.mobile.defaultHomeScroll),g=h();window.scrollTo(0,a.mobile.defaultHomeScroll);d&&d.data("page")._trigger("beforehide",
null,{nextPage:c});j||c.height(g+i);c.data("page")._trigger("beforeshow",null,{prevPage:d||a("")});a.mobile.hidePageLoadingMsg();j&&i&&(c.addClass("ui-mobile-pre-transition"),b(c),c.is(".ui-native-fixed")?c.find(".ui-content").scrollTop(i):c.scrollTop(i));f=(a.mobile.transitionHandlers[f||"none"]||a.mobile.defaultTransitionHandler)(f,e,c,d);f.done(function(){j||(c.height(""),b(c));j||a.mobile.silentScroll(i);d&&(j||d.height(""),d.data("page")._trigger("hide",null,{nextPage:c}));c.data("page")._trigger("show",
null,{prevPage:d||a("")})});return f}function h(){var b=a.event.special.orientationchange.orientation()==="portrait",c=b?screen.availHeight:screen.availWidth,b=Math.max(b?480:320,a(window).height());return Math.min(c,b)}function g(){(!a.support.touchOverflow||!a.mobile.touchOverflowEnabled)&&a("."+a.mobile.activePageClass).css("min-height",h())}function i(b,c){c&&b.attr("data-"+a.mobile.ns+"role",c);b.page()}function k(a){for(;a;){if(typeof a.nodeName==="string"&&a.nodeName.toLowerCase()=="a")break;
a=a.parentNode}return a}function l(b){var b=a(b).closest(".ui-page").jqmData("url"),c=t.hrefNoHash;if(!b||!j.isPath(b))b=c;return j.makeUrlAbsolute(b,c)}var o=a(window),m=a("html"),p=a("head"),j={urlParseRE:/^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,parseUrl:function(b){if(a.type(b)==="object")return b;b=j.urlParseRE.exec(b||"")||[];return{href:b[0]||"",hrefNoHash:b[1]||
"",hrefNoSearch:b[2]||"",domain:b[3]||"",protocol:b[4]||"",doubleSlash:b[5]||"",authority:b[6]||"",username:b[8]||"",password:b[9]||"",host:b[10]||"",hostname:b[11]||"",port:b[12]||"",pathname:b[13]||"",directory:b[14]||"",filename:b[15]||"",search:b[16]||"",hash:b[17]||""}},makePathAbsolute:function(a,b){if(a&&a.charAt(0)==="/")return a;for(var a=a||"",c=(b=b?b.replace(/^\/|(\/[^\/]*|[^\/]+)$/g,""):"")?b.split("/"):[],d=a.split("/"),f=0;f<d.length;f++){var e=d[f];switch(e){case ".":break;case "..":c.length&&
c.pop();break;default:c.push(e)}}return"/"+c.join("/")},isSameDomain:function(a,b){return j.parseUrl(a).domain===j.parseUrl(b).domain},isRelativeUrl:function(a){return j.parseUrl(a).protocol===""},isAbsoluteUrl:function(a){return j.parseUrl(a).protocol!==""},makeUrlAbsolute:function(a,b){if(!j.isRelativeUrl(a))return a;var c=j.parseUrl(a),d=j.parseUrl(b),f=c.protocol||d.protocol,e=c.protocol?c.doubleSlash:c.doubleSlash||d.doubleSlash,h=c.authority||d.authority,g=c.pathname!=="",i=j.makePathAbsolute(c.pathname||
d.filename,d.pathname);return f+e+h+i+(c.search||!g&&d.search||"")+c.hash},addSearchParams:function(b,c){var d=j.parseUrl(b),f=typeof c==="object"?a.param(c):c,e=d.search||"?";return d.hrefNoSearch+e+(e.charAt(e.length-1)!=="?"?"&":"")+f+(d.hash||"")},convertUrlToDataUrl:function(a){var b=j.parseUrl(a);if(j.isEmbeddedPage(b))return b.hash.split(s)[0].replace(/^#/,"");else if(j.isSameDomain(b,t))return b.hrefNoHash.replace(t.domain,"");return a},get:function(a){if(a===e)a=location.hash;return j.stripHash(a).replace(/[^\/]*\.[^\/*]+$/,
"")},getFilePath:function(b){var c="&"+a.mobile.subPageUrlKey;return b&&b.split(c)[0].split(s)[0]},set:function(a){location.hash=a},isPath:function(a){return/\//.test(a)},clean:function(a){return a.replace(t.domain,"")},stripHash:function(a){return a.replace(/^#/,"")},cleanHash:function(a){return j.stripHash(a.replace(/\?.*$/,"").replace(s,""))},isExternal:function(a){a=j.parseUrl(a);return a.protocol&&a.domain!==x.domain?true:false},hasProtocol:function(a){return/^(:?\w+:)/.test(a)},isFirstPageUrl:function(b){var b=
j.parseUrl(j.makeUrlAbsolute(b,t)),c=a.mobile.firstPage,c=c&&c[0]?c[0].id:e;return(b.hrefNoHash===x.hrefNoHash||w&&b.hrefNoHash===t.hrefNoHash)&&(!b.hash||b.hash==="#"||c&&b.hash.replace(/^#/,"")===c)},isEmbeddedPage:function(a){a=j.parseUrl(a);return a.protocol!==""?a.hash&&(a.hrefNoHash===x.hrefNoHash||w&&a.hrefNoHash===t.hrefNoHash):/^#/.test(a.href)}},q=null,n={stack:[],activeIndex:0,getActive:function(){return n.stack[n.activeIndex]},getPrev:function(){return n.stack[n.activeIndex-1]},getNext:function(){return n.stack[n.activeIndex+
1]},addNew:function(a,b,c,d,f){n.getNext()&&n.clearForward();n.stack.push({url:a,transition:b,title:c,pageUrl:d,role:f});n.activeIndex=n.stack.length-1},clearForward:function(){n.stack=n.stack.slice(0,n.activeIndex+1)},directHashChange:function(b){var c,d,f;this.getActive();a.each(n.stack,function(a,e){b.currentUrl===e.url&&(c=a<n.activeIndex,d=!c,f=a)});this.activeIndex=f!==e?f:this.activeIndex;c?(b.either||b.isBack)(true):d&&(b.either||b.isForward)(false)},ignoreNextHashChange:false},A=[],z=false,
s="&ui-state=dialog",v=p.children("base"),x=j.parseUrl(location.href),t=v.length?j.parseUrl(j.makeUrlAbsolute(v.attr("href"),x.href)):x,w=x.hrefNoHash!==t.hrefNoHash,u=a.support.dynamicBaseTag?{element:v.length?v:a("<base>",{href:t.hrefNoHash}).prependTo(p),set:function(a){u.element.attr("href",j.makeUrlAbsolute(a,t))},reset:function(){u.element.attr("href",t.hrefNoHash)}}:e,D=true,y,C,B;y=function(){var b=o;a.support.touchOverflow&&a.mobile.touchOverflowEnabled&&(b=a(".ui-page-active"),b=b.is(".ui-native-fixed")?
b.find(".ui-content"):b);return b};C=function(b){if(D){var c=a.mobile.urlHistory.getActive();if(c)b=b&&b.scrollTop(),c.lastScroll=b<a.mobile.minScrollBack?a.mobile.defaultHomeScroll:b}};B=function(){setTimeout(C,100,a(this))};o.bind(a.support.pushState?"popstate":"hashchange",function(){D=false});o.one(a.support.pushState?"popstate":"hashchange",function(){D=true});o.one("pagecontainercreate",function(){a.mobile.pageContainer.bind("pagechange",function(){var a=y();D=true;a.unbind("scrollstop",B);
a.bind("scrollstop",B)})});y().bind("scrollstop",B);a.mobile.getScreenHeight=h;a.fn.animationComplete=function(b){return a.support.cssTransitions?a(this).one("webkitAnimationEnd",b):(setTimeout(b,0),a(this))};a.mobile.path=j;a.mobile.base=u;a.mobile.urlHistory=n;a.mobile.dialogHashKey=s;a.mobile.noneTransitionHandler=function(b,c,d,f){f&&f.removeClass(a.mobile.activePageClass);d.addClass(a.mobile.activePageClass);return a.Deferred().resolve(b,c,d,f).promise()};a.mobile.defaultTransitionHandler=a.mobile.noneTransitionHandler;
a.mobile.transitionHandlers={none:a.mobile.defaultTransitionHandler};a.mobile.allowCrossDomainPages=false;a.mobile.getDocumentUrl=function(b){return b?a.extend({},x):x.href};a.mobile.getDocumentBase=function(b){return b?a.extend({},t):t.href};a.mobile._bindPageRemove=function(){var b=a(this);!b.data("page").options.domCache&&b.is(":jqmData(external-page='true')")&&b.bind("pagehide.remove",function(){var b=a(this),c=new a.Event("pageremove");b.trigger(c);c.isDefaultPrevented()||b.removeWithDependents()})};
a.mobile.loadPage=function(b,c){var d=a.Deferred(),f=a.extend({},a.mobile.loadPage.defaults,c),h=null,g=null,m=j.makeUrlAbsolute(b,a.mobile.activePage&&l(a.mobile.activePage)||t.hrefNoHash);if(f.data&&f.type==="get")m=j.addSearchParams(m,f.data),f.data=e;if(f.data&&f.type==="post")f.reloadPage=true;var s=j.getFilePath(m),p=j.convertUrlToDataUrl(m);f.pageContainer=f.pageContainer||a.mobile.pageContainer;h=f.pageContainer.children(":jqmData(url='"+p+"')");h.length===0&&p&&!j.isPath(p)&&(h=f.pageContainer.children("#"+
p).attr("data-"+a.mobile.ns+"url",p));if(h.length===0)if(a.mobile.firstPage&&j.isFirstPageUrl(s))a.mobile.firstPage.parent().length&&(h=a(a.mobile.firstPage));else if(j.isEmbeddedPage(s))return d.reject(m,c),d.promise();u&&u.reset();if(h.length){if(!f.reloadPage)return i(h,f.role),d.resolve(m,c,h),d.promise();g=h}var n=f.pageContainer,k=new a.Event("pagebeforeload"),q={url:b,absUrl:m,dataUrl:p,deferred:d,options:f};n.trigger(k,q);if(k.isDefaultPrevented())return d.promise();if(f.showLoadMsg)var v=
setTimeout(function(){a.mobile.showPageLoadingMsg()},f.loadMsgDelay);!a.mobile.allowCrossDomainPages&&!j.isSameDomain(x,m)?d.reject(m,c):a.ajax({url:s,type:f.type,data:f.data,dataType:"html",success:function(e,n,k){var o=a("<div></div>"),l=e.match(/<title[^>]*>([^<]*)/)&&RegExp.$1,t=RegExp("\\bdata-"+a.mobile.ns+"url=[\"']?([^\"'>]*)[\"']?");RegExp("(<[^>]+\\bdata-"+a.mobile.ns+"role=[\"']?page[\"']?[^>]*>)").test(e)&&RegExp.$1&&t.test(RegExp.$1)&&RegExp.$1&&(b=s=j.getFilePath(RegExp.$1));u&&u.set(s);
o.get(0).innerHTML=e;h=o.find(":jqmData(role='page'), :jqmData(role='dialog')").first();h.length||(h=a("<div data-"+a.mobile.ns+"role='page'>"+e.split(/<\/?body[^>]*>/gmi)[1]+"</div>"));l&&!h.jqmData("title")&&(~l.indexOf("&")&&(l=a("<div>"+l+"</div>").text()),h.jqmData("title",l));if(!a.support.dynamicBaseTag){var x=j.get(s);h.find("[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]").each(function(){var b=a(this).is("[href]")?"href":a(this).is("[src]")?"src":"action",c=a(this).attr(b),
c=c.replace(location.protocol+"//"+location.host+location.pathname,"");/^(\w+:|#|\/)/.test(c)||a(this).attr(b,x+c)})}h.attr("data-"+a.mobile.ns+"url",j.convertUrlToDataUrl(s)).attr("data-"+a.mobile.ns+"external-page",true).appendTo(f.pageContainer);h.one("pagecreate",a.mobile._bindPageRemove);i(h,f.role);m.indexOf("&"+a.mobile.subPageUrlKey)>-1&&(h=f.pageContainer.children(":jqmData(url='"+p+"')"));f.showLoadMsg&&(clearTimeout(v),a.mobile.hidePageLoadingMsg());q.xhr=k;q.textStatus=n;q.page=h;f.pageContainer.trigger("pageload",
q);d.resolve(m,c,h,g)},error:function(b,e,h){u&&u.set(j.get());q.xhr=b;q.textStatus=e;q.errorThrown=h;b=new a.Event("pageloadfailed");f.pageContainer.trigger(b,q);b.isDefaultPrevented()||(f.showLoadMsg&&(clearTimeout(v),a.mobile.hidePageLoadingMsg(),a("<div class='ui-loader ui-overlay-shadow ui-body-e ui-corner-all'><h1>"+a.mobile.pageLoadErrorMessage+"</h1></div>").css({display:"block",opacity:0.96,top:o.scrollTop()+100}).appendTo(f.pageContainer).delay(800).fadeOut(400,function(){a(this).remove()})),
d.reject(m,c))}});return d.promise()};a.mobile.loadPage.defaults={type:"get",data:e,reloadPage:false,role:e,showLoadMsg:false,pageContainer:e,loadMsgDelay:50};a.mobile.changePage=function(b,h){if(z)A.unshift(arguments);else{var g=a.extend({},a.mobile.changePage.defaults,h);g.pageContainer=g.pageContainer||a.mobile.pageContainer;g.fromPage=g.fromPage||a.mobile.activePage;var p=g.pageContainer,k=new a.Event("pagebeforechange"),q={toPage:b,options:g};p.trigger(k,q);if(!k.isDefaultPrevented())if(b=q.toPage,
z=true,typeof b=="string")a.mobile.loadPage(b,g).done(function(b,c,d,f){z=false;c.duplicateCachedPage=f;a.mobile.changePage(d,c)}).fail(function(){z=false;d(true);f();g.pageContainer.trigger("pagechangefailed",q)});else{if(b[0]===a.mobile.firstPage[0]&&!g.dataUrl)g.dataUrl=x.hrefNoHash;var k=g.fromPage,l=g.dataUrl&&j.convertUrlToDataUrl(g.dataUrl)||b.jqmData("url"),v=l;j.getFilePath(l);var o=n.getActive(),t=n.activeIndex===0,w=0,u=document.title,y=g.role==="dialog"||b.jqmData("role")==="dialog";if(k&&
k[0]===b[0]&&!g.allowSamePageTransition)z=false,p.trigger("pagechange",q);else{i(b,g.role);g.fromHashChange&&n.directHashChange({currentUrl:l,isBack:function(){w=-1},isForward:function(){w=1}});try{document.activeElement&&document.activeElement.nodeName.toLowerCase()!="body"?a(document.activeElement).blur():a("input:focus, textarea:focus, select:focus").blur()}catch(B){}y&&o&&(l=(o.url||"")+s);if(g.changeHash!==false&&l)n.ignoreNextHashChange=true,j.set(l);var C=!o?u:b.jqmData("title")||b.children(":jqmData(role='header')").find(".ui-title").getEncodedText();
C&&u==document.title&&(u=C);b.jqmData("title")||b.jqmData("title",u);g.transition=g.transition||(w&&!t?o.transition:e)||(y?a.mobile.defaultDialogTransition:a.mobile.defaultPageTransition);w||n.addNew(l,g.transition,u,v,g.role);document.title=n.getActive().title;a.mobile.activePage=b;g.reverse=g.reverse||w<0;c(b,k,g.transition,g.reverse).done(function(){d();g.duplicateCachedPage&&g.duplicateCachedPage.remove();m.removeClass("ui-mobile-rendering");f();p.trigger("pagechange",q)})}}}};a.mobile.changePage.defaults=
{transition:e,reverse:false,changeHash:true,fromHashChange:false,role:e,duplicateCachedPage:e,pageContainer:e,showLoadMsg:true,dataUrl:e,fromPage:e,allowSamePageTransition:false};a.mobile._registerInternalEvents=function(){a("form").live("submit",function(b){var c=a(this);if(a.mobile.ajaxEnabled&&!c.is(":jqmData(ajax='false')")){var d=c.attr("method"),f=c.attr("target"),e=c.attr("action");if(!e&&(e=l(c),e===t.hrefNoHash))e=x.hrefNoSearch;e=j.makeUrlAbsolute(e,l(c));!j.isExternal(e)&&!f&&(a.mobile.changePage(e,
{type:d&&d.length&&d.toLowerCase()||"get",data:c.serialize(),transition:c.jqmData("transition"),direction:c.jqmData("direction"),reloadPage:true}),b.preventDefault())}});a(document).bind("vclick",function(b){if(!(b.which>1)&&a.mobile.linkBindingEnabled&&(b=k(b.target))&&j.parseUrl(b.getAttribute("href")||"#").hash!=="#")d(true),q=a(b).closest(".ui-btn").not(".ui-disabled"),q.addClass(a.mobile.activeBtnClass),a("."+a.mobile.activePageClass+" .ui-btn").not(b).blur()});a(document).bind("click",function(b){if(a.mobile.linkBindingEnabled){var c=
k(b.target);if(c&&!(b.which>1)){var f=a(c),h=function(){window.setTimeout(function(){d(true)},200)};if(f.is(":jqmData(rel='back')"))return window.history.back(),false;var g=l(f),c=j.makeUrlAbsolute(f.attr("href")||"#",g);if(!a.mobile.ajaxEnabled&&!j.isEmbeddedPage(c))h();else{if(c.search("#")!=-1)if(c=c.replace(/[^#]*#/,""))c=j.isPath(c)?j.makeUrlAbsolute(c,g):j.makeUrlAbsolute("#"+c,x.hrefNoHash);else{b.preventDefault();return}var g=f.is("[rel='external']")||f.is(":jqmData(ajax='false')")||f.is("[target]"),
i=a.mobile.allowCrossDomainPages&&x.protocol==="file:"&&c.search(/^https?:/)!=-1;g||j.isExternal(c)&&!i?h():(h=f.jqmData("transition"),g=(g=f.jqmData("direction"))&&g==="reverse"||f.jqmData("back"),f=f.attr("data-"+a.mobile.ns+"rel")||e,a.mobile.changePage(c,{transition:h,reverse:g,role:f}),b.preventDefault())}}}});a(".ui-page").live("pageshow.prefetch",function(){var b=[];a(this).find("a:jqmData(prefetch)").each(function(){var c=a(this),f=c.attr("href");f&&a.inArray(f,b)===-1&&(b.push(f),a.mobile.loadPage(f,
{role:c.attr("data-"+a.mobile.ns+"rel")}))})});a.mobile._handleHashChange=function(b){var c=j.stripHash(b),f={transition:a.mobile.urlHistory.stack.length===0?"none":e,changeHash:false,fromHashChange:true};if(!a.mobile.hashListeningEnabled||n.ignoreNextHashChange)n.ignoreNextHashChange=false;else{if(n.stack.length>1&&c.indexOf(s)>-1)if(a.mobile.activePage.is(".ui-dialog"))n.directHashChange({currentUrl:c,either:function(b){var d=a.mobile.urlHistory.getActive();c=d.pageUrl;a.extend(f,{role:d.role,transition:d.transition,
reverse:b})}});else{n.directHashChange({currentUrl:c,isBack:function(){window.history.back()},isForward:function(){window.history.forward()}});return}c?(c=typeof c==="string"&&!j.isPath(c)?j.makeUrlAbsolute("#"+c,t):c,a.mobile.changePage(c,f)):a.mobile.changePage(a.mobile.firstPage,f)}};o.bind("hashchange",function(){a.mobile._handleHashChange(location.hash)});a(document).bind("pageshow",g);a(window).bind("throttledresize",g)}})(jQuery);
(function(a,e){var b={},d=a(e),f=a.mobile.path.parseUrl(location.href);a.extend(b,{initialFilePath:f.pathname+f.search,initialHref:f.hrefNoHash,hashchangeFired:false,state:function(){return{hash:location.hash||"#"+b.initialFilePath,title:document.title,initialHref:b.initialHref}},resetUIKeys:function(b){var f="&"+a.mobile.subPageUrlKey,d=b.indexOf(a.mobile.dialogHashKey);d>-1?b=b.slice(0,d)+"#"+b.slice(d):b.indexOf(f)>-1&&(b=b.split(f).join("#"+f));return b},nextHashChangePrevented:function(c){a.mobile.urlHistory.ignoreNextHashChange=
c;b.onHashChangeDisabled=c},onHashChange:function(){if(!b.onHashChangeDisabled){var c,f;c=location.hash;var d=a.mobile.path.isPath(c),e=d?location.href:a.mobile.getDocumentUrl();c=d?c.replace("#",""):c;f=b.state();c=a.mobile.path.makeUrlAbsolute(c,e);d&&(c=b.resetUIKeys(c));history.replaceState(f,document.title,c)}},onPopState:function(c){var f=c.originalEvent.state;f&&(b.nextHashChangePrevented(true),setTimeout(function(){b.nextHashChangePrevented(false);a.mobile._handleHashChange(f.hash)},100))},
init:function(){d.bind("hashchange",b.onHashChange);d.bind("popstate",b.onPopState);location.hash===""&&history.replaceState(b.state(),document.title,location.href)}});a(function(){a.mobile.pushStateEnabled&&a.support.pushState&&b.init()})})(jQuery,this);
(function(a){function e(b,d,f,c){var e=new a.Deferred,g=d?" reverse":"",i="ui-mobile-viewport-transitioning viewport-"+b;f.animationComplete(function(){f.add(c).removeClass("out in reverse "+b);c&&c[0]!==f[0]&&c.removeClass(a.mobile.activePageClass);f.parent().removeClass(i);e.resolve(b,d,f,c)});f.parent().addClass(i);c&&c.addClass(b+" out"+g);f.addClass(a.mobile.activePageClass+" "+b+" in"+g);return e.promise()}a.mobile.css3TransitionHandler=e;if(a.mobile.defaultTransitionHandler===a.mobile.noneTransitionHandler)a.mobile.defaultTransitionHandler=
e})(jQuery,this);
(function(a){a.mobile.page.prototype.options.degradeInputs={color:false,date:false,datetime:false,"datetime-local":false,email:false,month:false,number:false,range:"number",search:"text",tel:false,time:false,url:false,week:false};a(document).bind("pagecreate create",function(e){var b=a(e.target).closest(':jqmData(role="page")').data("page"),d;if(b)d=b.options,a(e.target).find("input").not(b.keepNativeSelector()).each(function(){var b=a(this),c=this.getAttribute("type"),e=d.degradeInputs[c]||"text";
if(d.degradeInputs[c]){var g=a("<div>").html(b.clone()).html(),i=g.indexOf(" type=")>-1;b.replaceWith(g.replace(i?/\s+type=["']?\w+['"]?/:/\/?>/,' type="'+e+'" data-'+a.mobile.ns+'type="'+c+'"'+(i?"":">")))}})})})(jQuery);
(function(a,e){a.widget("mobile.dialog",a.mobile.widget,{options:{closeBtnText:"Close",overlayTheme:"a",initSelector:":jqmData(role='dialog')"},_create:function(){var b=this,d=this.element,f=a("<a href='#' data-"+a.mobile.ns+"icon='delete' data-"+a.mobile.ns+"iconpos='notext'>"+this.options.closeBtnText+"</a>");d.addClass("ui-overlay-"+this.options.overlayTheme);d.attr("role","dialog").addClass("ui-dialog").find(":jqmData(role='header')").addClass("ui-corner-top ui-overlay-shadow").prepend(f).end().find(":jqmData(role='content'),:jqmData(role='footer')").addClass("ui-overlay-shadow").last().addClass("ui-corner-bottom");
f.bind("vclick",function(){b.close()});d.bind("vclick submit",function(b){var b=a(b.target).closest(b.type==="vclick"?"a":"form"),f;b.length&&!b.jqmData("transition")&&(f=a.mobile.urlHistory.getActive()||{},b.attr("data-"+a.mobile.ns+"transition",f.transition||a.mobile.defaultDialogTransition).attr("data-"+a.mobile.ns+"direction","reverse"))}).bind("pagehide",function(){a(this).find("."+a.mobile.activeBtnClass).removeClass(a.mobile.activeBtnClass)})},close:function(){e.history.back()}});a(a.mobile.dialog.prototype.options.initSelector).live("pagecreate",
function(){a(this).dialog()})})(jQuery,this);
(function(a){a.mobile.page.prototype.options.backBtnText="Back";a.mobile.page.prototype.options.addBackBtn=false;a.mobile.page.prototype.options.backBtnTheme=null;a.mobile.page.prototype.options.headerTheme="a";a.mobile.page.prototype.options.footerTheme="a";a.mobile.page.prototype.options.contentTheme=null;a(":jqmData(role='page'), :jqmData(role='dialog')").live("pagecreate",function(){var e=a(this),b=e.data("page").options,d=e.jqmData("role"),f=b.theme;a(":jqmData(role='header'), :jqmData(role='footer'), :jqmData(role='content')",
this).each(function(){var c=a(this),e=c.jqmData("role"),g=c.jqmData("theme"),i=g||b.contentTheme||d==="dialog"&&f,k;c.addClass("ui-"+e);if(e==="header"||e==="footer"){var l=g||(e==="header"?b.headerTheme:b.footerTheme)||f;c.addClass("ui-bar-"+l).attr("role",e==="header"?"banner":"contentinfo");g=c.children("a");i=g.hasClass("ui-btn-left");k=g.hasClass("ui-btn-right");i=i||g.eq(0).not(".ui-btn-right").addClass("ui-btn-left").length;k||g.eq(1).addClass("ui-btn-right");b.addBackBtn&&e==="header"&&a(".ui-page").length>
1&&c.jqmData("url")!==a.mobile.path.stripHash(location.hash)&&!i&&a("<a href='#' class='ui-btn-left' data-"+a.mobile.ns+"rel='back' data-"+a.mobile.ns+"icon='arrow-l'>"+b.backBtnText+"</a>").attr("data-"+a.mobile.ns+"theme",b.backBtnTheme||l).prependTo(c);c.children("h1, h2, h3, h4, h5, h6").addClass("ui-title").attr({tabindex:"0",role:"heading","aria-level":"1"})}else e==="content"&&(i&&c.addClass("ui-body-"+i),c.attr("role","main"))})})})(jQuery);
(function(a){a.widget("mobile.collapsible",a.mobile.widget,{options:{expandCueText:" click to expand contents",collapseCueText:" click to collapse contents",collapsed:true,heading:"h1,h2,h3,h4,h5,h6,legend",theme:null,contentTheme:null,iconTheme:"d",initSelector:":jqmData(role='collapsible')"},_create:function(){var e=this.element,b=this.options,d=e.addClass("ui-collapsible"),f=e.children(b.heading).first(),c=d.wrapInner("<div class='ui-collapsible-content'></div>").find(".ui-collapsible-content"),
h=e.closest(":jqmData(role='collapsible-set')").addClass("ui-collapsible-set"),e=h.children(":jqmData(role='collapsible')");f.is("legend")&&(f=a("<div role='heading'>"+f.html()+"</div>").insertBefore(f),f.next().remove());if(h.length){if(!b.theme)b.theme=h.jqmData("theme");if(!b.contentTheme)b.contentTheme=h.jqmData("content-theme")}c.addClass(b.contentTheme?"ui-body-"+b.contentTheme:"");f.insertBefore(c).addClass("ui-collapsible-heading").append("<span class='ui-collapsible-heading-status'></span>").wrapInner("<a href='#' class='ui-collapsible-heading-toggle'></a>").find("a").first().buttonMarkup({shadow:false,
corners:false,iconPos:"left",icon:"plus",theme:b.theme});h.length?(h.jqmData("collapsiblebound")||h.jqmData("collapsiblebound",true).bind("expand",function(b){a(b.target).closest(".ui-collapsible").siblings(".ui-collapsible").trigger("collapse")}),e.first().find("a").first().addClass("ui-corner-top").find(".ui-btn-inner").addClass("ui-corner-top"),e.last().jqmData("collapsible-last",true).find("a").first().addClass("ui-corner-bottom").find(".ui-btn-inner").addClass("ui-corner-bottom"),d.jqmData("collapsible-last")&&
f.find("a").first().add(f.find(".ui-btn-inner")).addClass("ui-corner-bottom")):f.find("a").first().add(f.find(".ui-btn-inner")).addClass("ui-corner-top ui-corner-bottom");d.bind("expand collapse",function(e){if(!e.isDefaultPrevented()){e.preventDefault();var i=a(this),e=e.type==="collapse",k=b.contentTheme;f.toggleClass("ui-collapsible-heading-collapsed",e).find(".ui-collapsible-heading-status").text(e?b.expandCueText:b.collapseCueText).end().find(".ui-icon").toggleClass("ui-icon-minus",!e).toggleClass("ui-icon-plus",
e);i.toggleClass("ui-collapsible-collapsed",e);c.toggleClass("ui-collapsible-content-collapsed",e).attr("aria-hidden",e);if(k&&(!h.length||d.jqmData("collapsible-last")))f.find("a").first().add(f.find(".ui-btn-inner")).toggleClass("ui-corner-bottom",e),c.toggleClass("ui-corner-bottom",!e);c.trigger("updatelayout")}}).trigger(b.collapsed?"collapse":"expand");f.bind("click",function(a){var b=f.is(".ui-collapsible-heading-collapsed")?"expand":"collapse";d.trigger(b);a.preventDefault()})}});a(document).bind("pagecreate create",
function(e){a(a.mobile.collapsible.prototype.options.initSelector,e.target).collapsible()})})(jQuery);(function(a){a.fn.fieldcontain=function(){return this.addClass("ui-field-contain ui-body ui-br")};a(document).bind("pagecreate create",function(e){a(":jqmData(role='fieldcontain')",e.target).fieldcontain()})})(jQuery);
(function(a){a.fn.grid=function(e){return this.each(function(){var b=a(this),d=a.extend({grid:null},e),f=b.children(),c={solo:1,a:2,b:3,c:4,d:5},d=d.grid;if(!d)if(f.length<=5)for(var h in c)c[h]===f.length&&(d=h);else d="a";c=c[d];b.addClass("ui-grid-"+d);f.filter(":nth-child("+c+"n+1)").addClass("ui-block-a");c>1&&f.filter(":nth-child("+c+"n+2)").addClass("ui-block-b");c>2&&f.filter(":nth-child(3n+3)").addClass("ui-block-c");c>3&&f.filter(":nth-child(4n+4)").addClass("ui-block-d");c>4&&f.filter(":nth-child(5n+5)").addClass("ui-block-e")})}})(jQuery);
(function(a,e){a.widget("mobile.navbar",a.mobile.widget,{options:{iconpos:"top",grid:null,initSelector:":jqmData(role='navbar')"},_create:function(){var b=this.element,d=b.find("a"),f=d.filter(":jqmData(icon)").length?this.options.iconpos:e;b.addClass("ui-navbar").attr("role","navigation").find("ul").grid({grid:this.options.grid});f||b.addClass("ui-navbar-noicons");d.buttonMarkup({corners:false,shadow:false,iconpos:f});b.delegate("a","vclick",function(){d.not(".ui-state-persist").removeClass(a.mobile.activeBtnClass);
a(this).addClass(a.mobile.activeBtnClass)})}});a(document).bind("pagecreate create",function(b){a(a.mobile.navbar.prototype.options.initSelector,b.target).navbar()})})(jQuery);
(function(a){var e={};a.widget("mobile.listview",a.mobile.widget,{options:{theme:null,countTheme:"c",headerTheme:"b",dividerTheme:"b",splitIcon:"arrow-r",splitTheme:"b",inset:false,initSelector:":jqmData(role='listview')"},_create:function(){var a=this;a.element.addClass(function(d,f){return f+" ui-listview "+(a.options.inset?" ui-listview-inset ui-corner-all ui-shadow ":"")});a.refresh(true)},_removeCorners:function(a,d){a=a.add(a.find(".ui-btn-inner, .ui-li-link-alt, .ui-li-thumb"));d==="top"?a.removeClass("ui-corner-top ui-corner-tr ui-corner-tl"):
d==="bottom"?a.removeClass("ui-corner-bottom ui-corner-br ui-corner-bl"):a.removeClass("ui-corner-top ui-corner-tr ui-corner-tl ui-corner-bottom ui-corner-br ui-corner-bl")},_refreshCorners:function(a){var d,f;this.options.inset&&(d=this.element.children("li"),f=a?d.not(".ui-screen-hidden"):d.filter(":visible"),this._removeCorners(d),d=f.first().addClass("ui-corner-top"),d.add(d.find(".ui-btn-inner").not(".ui-li-link-alt span:first-child")).addClass("ui-corner-top").end().find(".ui-li-link-alt, .ui-li-link-alt span:first-child").addClass("ui-corner-tr").end().find(".ui-li-thumb").not(".ui-li-icon").addClass("ui-corner-tl"),
f=f.last().addClass("ui-corner-bottom"),f.add(f.find(".ui-btn-inner")).find(".ui-li-link-alt").addClass("ui-corner-br").end().find(".ui-li-thumb").not(".ui-li-icon").addClass("ui-corner-bl"));a||this.element.trigger("updatelayout")},_findFirstElementByTagName:function(a,d,f,c){var e={};for(e[f]=e[c]=true;a;){if(e[a.nodeName])return a;a=a[d]}return null},_getChildrenByTagName:function(b,d,f){var c=[],e={};e[d]=e[f]=true;for(b=b.firstChild;b;)e[b.nodeName]&&c.push(b),b=b.nextSibling;return a(c)},_addThumbClasses:function(b){var d,
f,c=b.length;for(d=0;d<c;d++)f=a(this._findFirstElementByTagName(b[d].firstChild,"nextSibling","img","IMG")),f.length&&(f.addClass("ui-li-thumb"),a(this._findFirstElementByTagName(f[0].parentNode,"parentNode","li","LI")).addClass(f.is(".ui-li-icon")?"ui-li-has-icon":"ui-li-has-thumb"))},refresh:function(b){this.parentPage=this.element.closest(".ui-page");this._createSubPages();var d=this.options,f=this.element,c=f.jqmData("dividertheme")||d.dividerTheme,e=f.jqmData("splittheme"),g=f.jqmData("spliticon"),
i=this._getChildrenByTagName(f[0],"li","LI"),k=a.support.cssPseudoElement||!a.nodeName(f[0],"ol")?0:1,l={},o,m,p,j,q;k&&f.find(".ui-li-dec").remove();if(!d.theme)d.theme=a.mobile.getInheritedTheme(this.element,"c");for(var n=0,A=i.length;n<A;n++){o=i.eq(n);m="ui-li";if(b||!o.hasClass("ui-li"))p=o.jqmData("theme")||d.theme,j=this._getChildrenByTagName(o[0],"a","A"),j.length?(q=o.jqmData("icon"),o.buttonMarkup({wrapperEls:"div",shadow:false,corners:false,iconpos:"right",icon:j.length>1||q===false?false:
q||"arrow-r",theme:p}),q!=false&&j.length==1&&o.addClass("ui-li-has-arrow"),j.first().addClass("ui-link-inherit"),j.length>1&&(m+=" ui-li-has-alt",j=j.last(),q=e||j.jqmData("theme")||d.splitTheme,j.appendTo(o).attr("title",j.getEncodedText()).addClass("ui-li-link-alt").empty().buttonMarkup({shadow:false,corners:false,theme:p,icon:false,iconpos:false}).find(".ui-btn-inner").append(a(document.createElement("span")).buttonMarkup({shadow:true,corners:true,theme:q,iconpos:"notext",icon:g||j.jqmData("icon")||
d.splitIcon})))):o.jqmData("role")==="list-divider"?(m+=" ui-li-divider ui-btn ui-bar-"+c,o.attr("role","heading"),k&&(k=1)):m+=" ui-li-static ui-body-"+p;k&&m.indexOf("ui-li-divider")<0&&(p=o.is(".ui-li-static:first")?o:o.find(".ui-link-inherit"),p.addClass("ui-li-jsnumbering").prepend("<span class='ui-li-dec'>"+k++ +". </span>"));l[m]||(l[m]=[]);l[m].push(o[0])}for(m in l)a(l[m]).addClass(m).children(".ui-btn-inner").addClass(m);f.find("h1, h2, h3, h4, h5, h6").addClass("ui-li-heading").end().find("p, dl").addClass("ui-li-desc").end().find(".ui-li-aside").each(function(){var b=
a(this);b.prependTo(b.parent())}).end().find(".ui-li-count").each(function(){a(this).closest("li").addClass("ui-li-has-count")}).addClass("ui-btn-up-"+(f.jqmData("counttheme")||this.options.countTheme)+" ui-btn-corner-all");this._addThumbClasses(i);this._addThumbClasses(f.find(".ui-link-inherit"));this._refreshCorners(b)},_idStringEscape:function(a){return a.replace(/[^a-zA-Z0-9]/g,"-")},_createSubPages:function(){var b=this.element,d=b.closest(".ui-page"),f=d.jqmData("url"),c=f||d[0][a.expando],
h=b.attr("id"),g=this.options,i="data-"+a.mobile.ns,k=this,l=d.find(":jqmData(role='footer')").jqmData("id"),o;typeof e[c]==="undefined"&&(e[c]=-1);h=h||++e[c];a(b.find("li>ul, li>ol").toArray().reverse()).each(function(c){var d=a(this),e=d.attr("id")||h+"-"+c,c=d.parent(),k=a(d.prevAll().toArray().reverse()),k=k.length?k:a("<span>"+a.trim(c.contents()[0].nodeValue)+"</span>"),n=k.first().getEncodedText(),e=(f||"")+"&"+a.mobile.subPageUrlKey+"="+e,A=d.jqmData("theme")||g.theme,z=d.jqmData("counttheme")||
b.jqmData("counttheme")||g.countTheme;o=true;d.detach().wrap("<div "+i+"role='page' "+i+"url='"+e+"' "+i+"theme='"+A+"' "+i+"count-theme='"+z+"'><div "+i+"role='content'></div></div>").parent().before("<div "+i+"role='header' "+i+"theme='"+g.headerTheme+"'><div class='ui-title'>"+n+"</div></div>").after(l?a("<div "+i+"role='footer' "+i+"id='"+l+"'>"):"").parent().appendTo(a.mobile.pageContainer).page();d=c.find("a:first");d.length||(d=a("<a/>").html(k||n).prependTo(c.empty()));d.attr("href","#"+e)}).listview();
o&&d.is(":jqmData(external-page='true')")&&d.data("page").options.domCache===false&&d.unbind("pagehide.remove").bind("pagehide.remove",function(b,c){var e=c.nextPage;c.nextPage&&(e=e.jqmData("url"),e.indexOf(f+"&"+a.mobile.subPageUrlKey)!==0&&(k.childPages().remove(),d.remove()))})},childPages:function(){var b=this.parentPage.jqmData("url");return a(":jqmData(url^='"+b+"&"+a.mobile.subPageUrlKey+"')")}});a(document).bind("pagecreate create",function(b){a(a.mobile.listview.prototype.options.initSelector,
b.target).listview()})})(jQuery);
(function(a){a.mobile.listview.prototype.options.filter=false;a.mobile.listview.prototype.options.filterPlaceholder="Filter items...";a.mobile.listview.prototype.options.filterTheme="c";a.mobile.listview.prototype.options.filterCallback=function(a,b){return a.toLowerCase().indexOf(b)===-1};a(":jqmData(role='listview')").live("listviewcreate",function(){var e=a(this),b=e.data("listview");if(b.options.filter){var d=a("<form>",{"class":"ui-listview-filter ui-bar-"+b.options.filterTheme,role:"search"});
a("<input>",{placeholder:b.options.filterPlaceholder}).attr("data-"+a.mobile.ns+"type","search").jqmData("lastval","").bind("keyup change",function(){var d=a(this),c=this.value.toLowerCase(),h=null,h=d.jqmData("lastval")+"",g=false,i="";d.jqmData("lastval",c);i=c.substr(0,h.length-1).replace(h,"");h=c.length<h.length||i.length!=c.length-h.length?e.children():e.children(":not(.ui-screen-hidden)");if(c){for(var k=h.length-1;k>=0;k--)d=a(h[k]),i=d.jqmData("filtertext")||d.text(),d.is("li:jqmData(role=list-divider)")?
(d.toggleClass("ui-filter-hidequeue",!g),g=false):b.options.filterCallback(i,c)?d.toggleClass("ui-filter-hidequeue",true):g=true;h.filter(":not(.ui-filter-hidequeue)").toggleClass("ui-screen-hidden",false);h.filter(".ui-filter-hidequeue").toggleClass("ui-screen-hidden",true).toggleClass("ui-filter-hidequeue",false)}else h.toggleClass("ui-screen-hidden",false);b._refreshCorners()}).appendTo(d).textinput();a(this).jqmData("inset")&&d.addClass("ui-listview-filter-inset");d.bind("submit",function(){return false}).insertBefore(e)}})})(jQuery);
(function(a){a(document).bind("pagecreate create",function(e){a(":jqmData(role='nojs')",e.target).addClass("ui-nojs")})})(jQuery);
(function(a,e){a.widget("mobile.checkboxradio",a.mobile.widget,{options:{theme:null,initSelector:"input[type='checkbox'],input[type='radio']"},_create:function(){var b=this,d=this.element,f=d.closest("form,fieldset,:jqmData(role='page')").find("label[for='"+d[0].id+"']"),c=d.attr("type"),h=c+"-on",g=c+"-off",i=d.parents(":jqmData(type='horizontal')").length?e:g;if(!(c!=="checkbox"&&c!=="radio")){a.extend(this,{label:f,inputtype:c,checkedClass:"ui-"+h+(i?"":" "+a.mobile.activeBtnClass),uncheckedClass:"ui-"+
g,checkedicon:"ui-icon-"+h,uncheckedicon:"ui-icon-"+g});if(!this.options.theme)this.options.theme=this.element.jqmData("theme");f.buttonMarkup({theme:this.options.theme,icon:i,shadow:false});d.add(f).wrapAll("<div class='ui-"+c+"'></div>");f.bind({vmouseover:function(b){a(this).parent().is(".ui-disabled")&&b.stopPropagation()},vclick:function(a){if(d.is(":disabled"))a.preventDefault();else return b._cacheVals(),d.prop("checked",c==="radio"&&true||!d.prop("checked")),d.triggerHandler("click"),b._getInputSet().not(d).prop("checked",
false),b._updateAll(),false}});d.bind({vmousedown:function(){b._cacheVals()},vclick:function(){var c=a(this);c.is(":checked")?(c.prop("checked",true),b._getInputSet().not(c).prop("checked",false)):c.prop("checked",false);b._updateAll()},focus:function(){f.addClass("ui-focus")},blur:function(){f.removeClass("ui-focus")}});this.refresh()}},_cacheVals:function(){this._getInputSet().each(function(){var b=a(this);b.jqmData("cacheVal",b.is(":checked"))})},_getInputSet:function(){return this.inputtype==
"checkbox"?this.element:this.element.closest("form,fieldset,:jqmData(role='page')").find("input[name='"+this.element.attr("name")+"'][type='"+this.inputtype+"']")},_updateAll:function(){var b=this;this._getInputSet().each(function(){var d=a(this);(d.is(":checked")||b.inputtype==="checkbox")&&d.trigger("change")}).checkboxradio("refresh")},refresh:function(){var b=this.element,d=this.label,f=d.find(".ui-icon");a(b[0]).prop("checked")?(d.addClass(this.checkedClass).removeClass(this.uncheckedClass),
f.addClass(this.checkedicon).removeClass(this.uncheckedicon)):(d.removeClass(this.checkedClass).addClass(this.uncheckedClass),f.removeClass(this.checkedicon).addClass(this.uncheckedicon));b.is(":disabled")?this.disable():this.enable()},disable:function(){this.element.prop("disabled",true).parent().addClass("ui-disabled")},enable:function(){this.element.prop("disabled",false).parent().removeClass("ui-disabled")}});a(document).bind("pagecreate create",function(b){a.mobile.checkboxradio.prototype.enhanceWithin(b.target)})})(jQuery);
(function(a,e){a.widget("mobile.button",a.mobile.widget,{options:{theme:null,icon:null,iconpos:null,inline:null,corners:true,shadow:true,iconshadow:true,initSelector:"button, [type='button'], [type='submit'], [type='reset'], [type='image']"},_create:function(){var b=this.element,d=this.options,f,c;this.button=a("<div></div>").text(b.text()||b.val()).insertBefore(b).buttonMarkup({theme:d.theme,icon:d.icon,iconpos:d.iconpos,inline:d.inline,corners:d.corners,shadow:d.shadow,iconshadow:d.iconshadow}).append(b.addClass("ui-btn-hidden"));
d=b.attr("type");f=b.attr("name");d!=="button"&&d!=="reset"&&f&&b.bind("vclick",function(){c===e&&(c=a("<input>",{type:"hidden",name:b.attr("name"),value:b.attr("value")}).insertBefore(b),a(document).one("submit",function(){c.remove();c=e}))});this.refresh()},enable:function(){this.element.attr("disabled",false);this.button.removeClass("ui-disabled").attr("aria-disabled",false);return this._setOption("disabled",false)},disable:function(){this.element.attr("disabled",true);this.button.addClass("ui-disabled").attr("aria-disabled",
true);return this._setOption("disabled",true)},refresh:function(){var a=this.element;a.prop("disabled")?this.disable():this.enable();this.button.data("textWrapper").text(a.text()||a.val())}});a(document).bind("pagecreate create",function(b){a.mobile.button.prototype.enhanceWithin(b.target)})})(jQuery);
(function(a,e){a.widget("mobile.slider",a.mobile.widget,{options:{theme:null,trackTheme:null,disabled:false,initSelector:"input[type='range'], :jqmData(type='range'), :jqmData(role='slider')"},_create:function(){var b=this,d=this.element,f=a.mobile.getInheritedTheme(d,"c"),c=this.options.theme||f,h=this.options.trackTheme||f,g=d[0].nodeName.toLowerCase(),f=g=="select"?"ui-slider-switch":"",i=d.attr("id"),k=i+"-label",i=a("[for='"+i+"']").attr("id",k),l=function(){return g=="input"?parseFloat(d.val()):
d[0].selectedIndex},o=g=="input"?parseFloat(d.attr("min")):0,m=g=="input"?parseFloat(d.attr("max")):d.find("option").length-1,p=window.parseFloat(d.attr("step")||1),j=a("<div class='ui-slider "+f+" ui-btn-down-"+h+" ui-btn-corner-all' role='application'></div>"),q=a("<a href='#' class='ui-slider-handle'></a>").appendTo(j).buttonMarkup({corners:true,theme:c,shadow:true}).attr({role:"slider","aria-valuemin":o,"aria-valuemax":m,"aria-valuenow":l(),"aria-valuetext":l(),title:l(),"aria-labelledby":k});
a.extend(this,{slider:j,handle:q,dragging:false,beforeStart:null,userModified:false,mouseMoved:false});g=="select"&&(j.wrapInner("<div class='ui-slider-inneroffset'></div>"),q.addClass("ui-slider-handle-snapping"),d.find("option"),d.find("option").each(function(b){var c=!b?"b":"a",d=!b?"right":"left",b=!b?" ui-btn-down-"+h:" "+a.mobile.activeBtnClass;a("<div class='ui-slider-labelbg ui-slider-labelbg-"+c+b+" ui-btn-corner-"+d+"'></div>").prependTo(j);a("<span class='ui-slider-label ui-slider-label-"+
c+b+" ui-btn-corner-"+d+"' role='img'>"+a(this).getEncodedText()+"</span>").prependTo(q)}));i.addClass("ui-slider");d.addClass(g==="input"?"ui-slider-input":"ui-slider-switch").change(function(){b.mouseMoved||b.refresh(l(),true)}).keyup(function(){b.refresh(l(),true,true)}).blur(function(){b.refresh(l(),true)});a(document).bind("vmousemove",function(a){if(b.dragging)return b.mouseMoved=true,g==="select"&&q.removeClass("ui-slider-handle-snapping"),b.refresh(a),b.userModified=b.beforeStart!==d[0].selectedIndex,
false});j.bind("vmousedown",function(a){b.dragging=true;b.userModified=false;b.mouseMoved=false;if(g==="select")b.beforeStart=d[0].selectedIndex;b.refresh(a);return false});j.add(document).bind("vmouseup",function(){if(b.dragging)return b.dragging=false,g==="select"&&(q.addClass("ui-slider-handle-snapping"),b.mouseMoved?b.userModified?b.refresh(b.beforeStart==0?1:0):b.refresh(b.beforeStart):b.refresh(b.beforeStart==0?1:0)),b.mouseMoved=false});j.insertAfter(d);this.handle.bind("vmousedown",function(){a(this).focus()}).bind("vclick",
false);this.handle.bind("keydown",function(c){var d=l();if(!b.options.disabled){switch(c.keyCode){case a.mobile.keyCode.HOME:case a.mobile.keyCode.END:case a.mobile.keyCode.PAGE_UP:case a.mobile.keyCode.PAGE_DOWN:case a.mobile.keyCode.UP:case a.mobile.keyCode.RIGHT:case a.mobile.keyCode.DOWN:case a.mobile.keyCode.LEFT:if(c.preventDefault(),!b._keySliding)b._keySliding=true,a(this).addClass("ui-state-active")}switch(c.keyCode){case a.mobile.keyCode.HOME:b.refresh(o);break;case a.mobile.keyCode.END:b.refresh(m);
break;case a.mobile.keyCode.PAGE_UP:case a.mobile.keyCode.UP:case a.mobile.keyCode.RIGHT:b.refresh(d+p);break;case a.mobile.keyCode.PAGE_DOWN:case a.mobile.keyCode.DOWN:case a.mobile.keyCode.LEFT:b.refresh(d-p)}}}).keyup(function(){if(b._keySliding)b._keySliding=false,a(this).removeClass("ui-state-active")});this.refresh(e,e,true)},refresh:function(a,d,f){(this.options.disabled||this.element.attr("disabled"))&&this.disable();var c=this.element,e,g=c[0].nodeName.toLowerCase(),i=g==="input"?parseFloat(c.attr("min")):
0,k=g==="input"?parseFloat(c.attr("max")):c.find("option").length-1;if(typeof a==="object"){if(!this.dragging||a.pageX<this.slider.offset().left-8||a.pageX>this.slider.offset().left+this.slider.width()+8)return;e=Math.round((a.pageX-this.slider.offset().left)/this.slider.width()*100)}else a==null&&(a=g==="input"?parseFloat(c.val()):c[0].selectedIndex),e=(parseFloat(a)-i)/(k-i)*100;if(!isNaN(e)&&(e<0&&(e=0),e>100&&(e=100),a=Math.round(e/100*(k-i))+i,a<i&&(a=i),a>k&&(a=k),this.handle.css("left",e+"%"),
this.handle.attr({"aria-valuenow":g==="input"?a:c.find("option").eq(a).attr("value"),"aria-valuetext":g==="input"?a:c.find("option").eq(a).getEncodedText(),title:a}),g==="select"&&(a===0?this.slider.addClass("ui-slider-switch-a").removeClass("ui-slider-switch-b"):this.slider.addClass("ui-slider-switch-b").removeClass("ui-slider-switch-a")),!f))f=false,g==="input"?(f=c.val()!==a,c.val(a)):(f=c[0].selectedIndex!==a,c[0].selectedIndex=a),!d&&f&&c.trigger("change")},enable:function(){this.element.attr("disabled",
false);this.slider.removeClass("ui-disabled").attr("aria-disabled",false);return this._setOption("disabled",false)},disable:function(){this.element.attr("disabled",true);this.slider.addClass("ui-disabled").attr("aria-disabled",true);return this._setOption("disabled",true)}});a(document).bind("pagecreate create",function(b){a.mobile.slider.prototype.enhanceWithin(b.target)})})(jQuery);
(function(a){a.widget("mobile.textinput",a.mobile.widget,{options:{theme:null,initSelector:"input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea, input[type='time'], input[type='date'], input[type='month'], input[type='week'], input[type='datetime'], input[type='datetime-local'], input[type='color'], input:not([type])"},_create:function(){var e=this.element,
b=this.options.theme||a.mobile.getInheritedTheme(this.element,"c"),d=" ui-body-"+b,f,c;a("label[for='"+e.attr("id")+"']").addClass("ui-input-text");f=e.addClass("ui-input-text ui-body-"+b);typeof e[0].autocorrect!=="undefined"&&!a.support.touchOverflow&&(e[0].setAttribute("autocorrect","off"),e[0].setAttribute("autocomplete","off"));e.is("[type='search'],:jqmData(type='search')")?(f=e.wrap("<div class='ui-input-search ui-shadow-inset ui-btn-corner-all ui-btn-shadow ui-icon-searchfield"+d+"'></div>").parent(),
c=a("<a href='#' class='ui-input-clear' title='clear text'>clear text</a>").tap(function(a){e.val("").focus();e.trigger("change");c.addClass("ui-input-clear-hidden");a.preventDefault()}).appendTo(f).buttonMarkup({icon:"delete",iconpos:"notext",corners:true,shadow:true}),b=function(){setTimeout(function(){c.toggleClass("ui-input-clear-hidden",!e.val())},0)},b(),e.bind("paste cut keyup focus change blur",b)):e.addClass("ui-corner-all ui-shadow-inset"+d);e.focus(function(){f.addClass("ui-focus")}).blur(function(){f.removeClass("ui-focus")});
if(e.is("textarea")){var h=function(){var a=e[0].scrollHeight;e[0].clientHeight<a&&e.height(a+15)},g;e.keyup(function(){clearTimeout(g);g=setTimeout(h,100)});a.trim(e.val())&&(a(window).load(h),a(document).one("pagechange",h))}},disable:function(){(this.element.attr("disabled",true).is("[type='search'],:jqmData(type='search')")?this.element.parent():this.element).addClass("ui-disabled")},enable:function(){(this.element.attr("disabled",false).is("[type='search'],:jqmData(type='search')")?this.element.parent():
this.element).removeClass("ui-disabled")}});a(document).bind("pagecreate create",function(e){a.mobile.textinput.prototype.enhanceWithin(e.target)})})(jQuery);
(function(a){var e=function(b){var d=b.selectID,f=b.label,c=b.select.closest(".ui-page"),e=a("<div>",{"class":"ui-selectmenu-screen ui-screen-hidden"}).appendTo(c),g=b._selectOptions(),i=b.isMultiple=b.select[0].multiple,k=d+"-button",l=d+"-menu",o=a("<div data-"+a.mobile.ns+"role='dialog' data-"+a.mobile.ns+"theme='"+b.options.theme+"' data-"+a.mobile.ns+"overlay-theme='"+b.options.overlayTheme+"'><div data-"+a.mobile.ns+"role='header'><div class='ui-title'>"+f.getEncodedText()+"</div></div><div data-"+
a.mobile.ns+"role='content'></div></div>").appendTo(a.mobile.pageContainer).page(),m=a("<div>",{"class":"ui-selectmenu ui-selectmenu-hidden ui-overlay-shadow ui-corner-all ui-body-"+b.options.overlayTheme+" "+a.mobile.defaultDialogTransition}).insertAfter(e),p=a("<ul>",{"class":"ui-selectmenu-list",id:l,role:"listbox","aria-labelledby":k}).attr("data-"+a.mobile.ns+"theme",b.options.theme).appendTo(m),j=a("<div>",{"class":"ui-header ui-bar-"+b.options.theme}).prependTo(m),q=a("<h1>",{"class":"ui-title"}).appendTo(j),
n=a("<a>",{text:b.options.closeText,href:"#","class":"ui-btn-left"}).attr("data-"+a.mobile.ns+"iconpos","notext").attr("data-"+a.mobile.ns+"icon","delete").appendTo(j).buttonMarkup(),A=o.find(".ui-content"),z=o.find(".ui-header a");a.extend(b,{select:b.select,selectID:d,buttonId:k,menuId:l,thisPage:c,menuPage:o,label:f,screen:e,selectOptions:g,isMultiple:i,theme:b.options.theme,listbox:m,list:p,header:j,headerTitle:q,headerClose:n,menuPageContent:A,menuPageClose:z,placeholder:"",build:function(){var b=
this;b.refresh();b.select.attr("tabindex","-1").focus(function(){a(this).blur();b.button.focus()});b.button.bind("vclick keydown",function(c){if(c.type=="vclick"||c.keyCode&&(c.keyCode===a.mobile.keyCode.ENTER||c.keyCode===a.mobile.keyCode.SPACE))b.open(),c.preventDefault()});b.list.attr("role","listbox").delegate(".ui-li>a","focusin",function(){a(this).attr("tabindex","0")}).delegate(".ui-li>a","focusout",function(){a(this).attr("tabindex","-1")}).delegate("li:not(.ui-disabled, .ui-li-divider)",
"click",function(c){var d=b.select[0].selectedIndex,f=b.list.find("li:not(.ui-li-divider)").index(this),e=b._selectOptions().eq(f)[0];e.selected=b.isMultiple?!e.selected:true;b.isMultiple&&a(this).find(".ui-icon").toggleClass("ui-icon-checkbox-on",e.selected).toggleClass("ui-icon-checkbox-off",!e.selected);(b.isMultiple||d!==f)&&b.select.trigger("change");b.isMultiple||b.close();c.preventDefault()}).keydown(function(b){var c=a(b.target),d=c.closest("li");switch(b.keyCode){case 38:return b=d.prev(),
b.length&&(c.blur().attr("tabindex","-1"),b.find("a").first().focus()),false;case 40:return b=d.next(),b.length&&(c.blur().attr("tabindex","-1"),b.find("a").first().focus()),false;case 13:case 32:return c.trigger("click"),false}});b.menuPage.bind("pagehide",function(){b.list.appendTo(b.listbox);b._focusButton();a.mobile._bindPageRemove.call(b.thisPage)});b.screen.bind("vclick",function(){b.close()});b.headerClose.click(function(){if(b.menuType=="overlay")return b.close(),false});b.thisPage.addDependents(this.menuPage)},
_isRebuildRequired:function(){var a=this.list.find("li");return this._selectOptions().text()!==a.text()},refresh:function(b){var c=this;this._selectOptions();this.selected();var d=this.selectedIndices();(b||this._isRebuildRequired())&&c._buildList();c.setButtonText();c.setButtonCount();c.list.find("li:not(.ui-li-divider)").removeClass(a.mobile.activeBtnClass).attr("aria-selected",false).each(function(b){a.inArray(b,d)>-1&&(b=a(this),b.attr("aria-selected",true),c.isMultiple?b.find(".ui-icon").removeClass("ui-icon-checkbox-off").addClass("ui-icon-checkbox-on"):
b.addClass(a.mobile.activeBtnClass))})},close:function(){if(!this.options.disabled&&this.isOpen)this.menuType=="page"?window.history.back():(this.screen.addClass("ui-screen-hidden"),this.listbox.addClass("ui-selectmenu-hidden").removeAttr("style").removeClass("in"),this.list.appendTo(this.listbox),this._focusButton()),this.isOpen=false},open:function(){if(!this.options.disabled){var b=this,c=b.list.parent().outerHeight(),d=b.list.parent().outerWidth(),f=a(".ui-page-active"),e=a.support.touchOverflow&&
a.mobile.touchOverflowEnabled,f=f.is(".ui-native-fixed")?f.find(".ui-content"):f;scrollTop=e?f.scrollTop():a(window).scrollTop();btnOffset=b.button.offset().top;screenHeight=window.innerHeight;screenWidth=window.innerWidth;b.button.addClass(a.mobile.activeBtnClass);setTimeout(function(){b.button.removeClass(a.mobile.activeBtnClass)},300);if(c>screenHeight-80||!a.support.scrollTop){b.thisPage.unbind("pagehide.remove");if(scrollTop==0&&btnOffset>screenHeight)b.thisPage.one("pagehide",function(){a(this).jqmData("lastScroll",
btnOffset)});b.menuPage.one("pageshow",function(){a(window).one("silentscroll",function(){b.list.find(a.mobile.activeBtnClass).focus()});b.isOpen=true});b.menuType="page";b.menuPageContent.append(b.list);b.menuPage.find("div .ui-title").text(b.label.text());a.mobile.changePage(b.menuPage,{transition:a.mobile.defaultDialogTransition})}else{b.menuType="overlay";b.screen.height(a(document).height()).removeClass("ui-screen-hidden");var f=btnOffset-scrollTop,h=scrollTop+screenHeight-btnOffset,g=c/2,e=
parseFloat(b.list.parent().css("max-width")),c=f>c/2&&h>c/2?btnOffset+b.button.outerHeight()/2-g:f>h?scrollTop+screenHeight-c-30:scrollTop+30;d<e?e=(screenWidth-d)/2:(e=b.button.offset().left+b.button.outerWidth()/2-d/2,e<30?e=30:e+d>screenWidth&&(e=screenWidth-d-30));b.listbox.append(b.list).removeClass("ui-selectmenu-hidden").css({top:c,left:e}).addClass("in");b.list.find(a.mobile.activeBtnClass).focus();b.isOpen=true}}},_buildList:function(){var b=this,c=this.options,d=this.placeholder,f=[],e=
[],h=b.isMultiple?"checkbox-off":"false";b.list.empty().filter(".ui-listview").listview("destroy");b.select.find("option").each(function(g){var j=a(this),i=j.parent(),m=j.getEncodedText(),p="<a href='#'>"+m+"</a>",k=[],n=[];i.is("optgroup")&&(i=i.attr("label"),a.inArray(i,f)===-1&&(e.push("<li data-"+a.mobile.ns+"role='list-divider'>"+i+"</li>"),f.push(i)));if(!this.getAttribute("value")||m.length==0||j.jqmData("placeholder"))c.hidePlaceholderMenuItems&&k.push("ui-selectmenu-placeholder"),d=b.placeholder=
m;this.disabled&&(k.push("ui-disabled"),n.push("aria-disabled='true'"));e.push("<li data-"+a.mobile.ns+"option-index='"+g+"' data-"+a.mobile.ns+"icon='"+h+"' class='"+k.join(" ")+"' "+n.join(" ")+">"+p+"</li>")});b.list.html(e.join(" "));b.list.find("li").attr({role:"option",tabindex:"-1"}).first().attr("tabindex","0");this.isMultiple||this.headerClose.hide();!this.isMultiple&&!d.length?this.header.hide():this.headerTitle.text(this.placeholder);b.list.listview()},_button:function(){return a("<a>",
{href:"#",role:"button",id:this.buttonId,"aria-haspopup":"true","aria-owns":this.menuId})}})};a("select").live("selectmenubeforecreate",function(){var b=a(this).data("selectmenu");b.options.nativeMenu||e(b)})})(jQuery);
(function(a){a.widget("mobile.selectmenu",a.mobile.widget,{options:{theme:null,disabled:false,icon:"arrow-d",iconpos:"right",inline:null,corners:true,shadow:true,iconshadow:true,menuPageTheme:"b",overlayTheme:"a",hidePlaceholderMenuItems:true,closeText:"Close",nativeMenu:true,initSelector:"select:not(:jqmData(role='slider'))"},_button:function(){return a("<div/>")},_setDisabled:function(a){this.element.attr("disabled",a);this.button.attr("aria-disabled",a);return this._setOption("disabled",a)},_focusButton:function(){var a=
this;setTimeout(function(){a.button.focus()},40)},_selectOptions:function(){return this.select.find("option")},_preExtension:function(){this.select=this.element.wrap("<div class='ui-select'>");this.selectID=this.select.attr("id");this.label=a("label[for='"+this.selectID+"']").addClass("ui-select");this.isMultiple=this.select[0].multiple;if(!this.options.theme)this.options.theme=a.mobile.getInheritedTheme(this.select,"c")},_create:function(){this._preExtension();this._trigger("beforeCreate");this.button=
this._button();var e=this,b=this.options,d=this.button.text(a(this.select[0].options.item(this.select[0].selectedIndex==-1?0:this.select[0].selectedIndex)).text()).insertBefore(this.select).buttonMarkup({theme:b.theme,icon:b.icon,iconpos:b.iconpos,inline:b.inline,corners:b.corners,shadow:b.shadow,iconshadow:b.iconshadow});b.nativeMenu&&window.opera&&window.opera.version&&this.select.addClass("ui-select-nativeonly");if(this.isMultiple)this.buttonCount=a("<span>").addClass("ui-li-count ui-btn-up-c ui-btn-corner-all").hide().appendTo(d.addClass("ui-li-has-count"));
(b.disabled||this.element.attr("disabled"))&&this.disable();this.select.change(function(){e.refresh()});this.build()},build:function(){var e=this;this.select.appendTo(e.button).bind("vmousedown",function(){e.button.addClass(a.mobile.activeBtnClass)}).bind("focus vmouseover",function(){e.button.trigger("vmouseover")}).bind("vmousemove",function(){e.button.removeClass(a.mobile.activeBtnClass)}).bind("change blur vmouseout",function(){e.button.trigger("vmouseout").removeClass(a.mobile.activeBtnClass)}).bind("change blur",
function(){e.button.removeClass("ui-btn-down-"+e.options.theme)})},selected:function(){return this._selectOptions().filter(":selected")},selectedIndices:function(){var a=this;return this.selected().map(function(){return a._selectOptions().index(this)}).get()},setButtonText:function(){var e=this,b=this.selected();this.button.find(".ui-btn-text").text(function(){return!e.isMultiple?b.text():b.length?b.map(function(){return a(this).text()}).get().join(", "):e.placeholder})},setButtonCount:function(){var a=
this.selected();this.isMultiple&&this.buttonCount[a.length>1?"show":"hide"]().text(a.length)},refresh:function(){this.setButtonText();this.setButtonCount()},open:a.noop,close:a.noop,disable:function(){this._setDisabled(true);this.button.addClass("ui-disabled")},enable:function(){this._setDisabled(false);this.button.removeClass("ui-disabled")}});a(document).bind("pagecreate create",function(e){a.mobile.selectmenu.prototype.enhanceWithin(e.target)})})(jQuery);
(function(a,e){function b(b){for(var c;b;){if((c=typeof b.className==="string"&&b.className.split(" "))&&a.inArray("ui-btn",c)>-1&&a.inArray("ui-disabled",c)<0)break;b=b.parentNode}return b}a.fn.buttonMarkup=function(b){for(var b=b||{},c=0;c<this.length;c++){var h=this.eq(c),g=h[0],i=a.extend({},a.fn.buttonMarkup.defaults,{icon:b.icon!==e?b.icon:h.jqmData("icon"),iconpos:b.iconpos!==e?b.iconpos:h.jqmData("iconpos"),theme:b.theme!==e?b.theme:h.jqmData("theme"),inline:b.inline!==e?b.inline:h.jqmData("inline"),
shadow:b.shadow!==e?b.shadow:h.jqmData("shadow"),corners:b.corners!==e?b.corners:h.jqmData("corners"),iconshadow:b.iconshadow!==e?b.iconshadow:h.jqmData("iconshadow")},b),k="ui-btn-inner",l,o,m=document.createElement(i.wrapperEls),p=document.createElement(i.wrapperEls),j=i.icon?document.createElement("span"):null;d&&d();if(!i.theme)i.theme=a.mobile.getInheritedTheme(h,"c");l="ui-btn ui-btn-up-"+i.theme;i.inline&&(l+=" ui-btn-inline");if(i.icon)i.icon="ui-icon-"+i.icon,i.iconpos=i.iconpos||"left",
o="ui-icon "+i.icon,i.iconshadow&&(o+=" ui-icon-shadow");i.iconpos&&(l+=" ui-btn-icon-"+i.iconpos,i.iconpos=="notext"&&!h.attr("title")&&h.attr("title",h.getEncodedText()));i.corners&&(l+=" ui-btn-corner-all",k+=" ui-btn-corner-all");i.shadow&&(l+=" ui-shadow");g.setAttribute("data-"+a.mobile.ns+"theme",i.theme);h.addClass(l);m.className=k;m.setAttribute("aria-hidden","true");p.className="ui-btn-text";m.appendChild(p);if(j)j.className=o,m.appendChild(j);for(;g.firstChild;)p.appendChild(g.firstChild);
g.appendChild(m);a.data(g,"textWrapper",a(p))}return this};a.fn.buttonMarkup.defaults={corners:true,shadow:true,iconshadow:true,inline:false,wrapperEls:"span"};var d=function(){a(document).bind({vmousedown:function(d){var d=b(d.target),c;d&&(d=a(d),c=d.attr("data-"+a.mobile.ns+"theme"),d.removeClass("ui-btn-up-"+c).addClass("ui-btn-down-"+c))},"vmousecancel vmouseup":function(d){var d=b(d.target),c;d&&(d=a(d),c=d.attr("data-"+a.mobile.ns+"theme"),d.removeClass("ui-btn-down-"+c).addClass("ui-btn-up-"+
c))},"vmouseover focus":function(d){var d=b(d.target),c;d&&(d=a(d),c=d.attr("data-"+a.mobile.ns+"theme"),d.removeClass("ui-btn-up-"+c).addClass("ui-btn-hover-"+c))},"vmouseout blur":function(d){var d=b(d.target),c;d&&(d=a(d),c=d.attr("data-"+a.mobile.ns+"theme"),d.removeClass("ui-btn-hover-"+c+" ui-btn-down-"+c).addClass("ui-btn-up-"+c))}});d=null};a(document).bind("pagecreate create",function(b){a(":jqmData(role='button'), .ui-bar > a, .ui-header > a, .ui-footer > a, .ui-bar > :jqmData(role='controlgroup') > a",
b.target).not(".ui-btn, :jqmData(role='none'), :jqmData(role='nojs')").buttonMarkup()})})(jQuery);
(function(a){a.fn.controlgroup=function(e){return this.each(function(){function b(a){a.removeClass("ui-btn-corner-all ui-shadow").eq(0).addClass(h[0]).end().last().addClass(h[1]).addClass("ui-controlgroup-last")}var d=a(this),f=a.extend({direction:d.jqmData("type")||"vertical",shadow:false,excludeInvisible:true},e),c=d.children("legend"),h=f.direction=="horizontal"?["ui-corner-left","ui-corner-right"]:["ui-corner-top","ui-corner-bottom"];d.find("input").first().attr("type");c.length&&(d.wrapInner("<div class='ui-controlgroup-controls'></div>"),
a("<div role='heading' class='ui-controlgroup-label'>"+c.html()+"</div>").insertBefore(d.children(0)),c.remove());d.addClass("ui-corner-all ui-controlgroup ui-controlgroup-"+f.direction);b(d.find(".ui-btn"+(f.excludeInvisible?":visible":"")));b(d.find(".ui-btn-inner"));f.shadow&&d.addClass("ui-shadow")})};a(document).bind("pagecreate create",function(e){a(":jqmData(role='controlgroup')",e.target).controlgroup({excludeInvisible:false})})})(jQuery);
(function(a){a(document).bind("pagecreate create",function(e){a(e.target).find("a").not(".ui-btn, .ui-link-inherit, :jqmData(role='none'), :jqmData(role='nojs')").addClass("ui-link")})})(jQuery);
(function(a,e){a.fn.fixHeaderFooter=function(){return!a.support.scrollTop||a.support.touchOverflow&&a.mobile.touchOverflowEnabled?this:this.each(function(){var b=a(this);b.jqmData("fullscreen")&&b.addClass("ui-page-fullscreen");b.find(".ui-header:jqmData(position='fixed')").addClass("ui-header-fixed ui-fixed-inline fade");b.find(".ui-footer:jqmData(position='fixed')").addClass("ui-footer-fixed ui-fixed-inline fade")})};a.mobile.fixedToolbars=function(){function b(){!i&&g==="overlay"&&(h||a.mobile.fixedToolbars.hide(true),
a.mobile.fixedToolbars.startShowTimer())}function d(a){var b=0,c,d;if(a){d=document.body;c=a.offsetParent;for(b=a.offsetTop;a&&a!=d;){b+=a.scrollTop||0;if(a==c)b+=c.offsetTop,c=a.offsetParent;a=a.parentNode}}return b}function f(b){var c=a(window).scrollTop(),e=d(b[0]),f=b.css("top")=="auto"?0:parseFloat(b.css("top")),h=window.innerHeight,g=b.outerHeight(),i=b.parents(".ui-page:not(.ui-page-fullscreen)").length;return b.is(".ui-header-fixed")?(f=c-e+f,f<e&&(f=0),b.css("top",i?f:c)):b.css("top",i?c+
h-g-(e-f):c+h-g)}if(a.support.scrollTop&&(!a.support.touchOverflow||!a.mobile.touchOverflowEnabled)){var c,h,g="inline",i=false,k=null,l=false,o=true;a(function(){var c=a(document),d=a(window);c.bind("vmousedown",function(){o&&(k=g)}).bind("vclick",function(b){o&&!a(b.target).closest("a,input,textarea,select,button,label,.ui-header-fixed,.ui-footer-fixed").length&&!l&&(a.mobile.fixedToolbars.toggle(k),k=null)}).bind("silentscroll",b);(c.scrollTop()===0?d:c).bind("scrollstart",function(){l=true;k===
null&&(k=g);var b=k=="overlay";if(i=b||!!h)a.mobile.fixedToolbars.clearShowTimer(),b&&a.mobile.fixedToolbars.hide(true)}).bind("scrollstop",function(b){a(b.target).closest("a,input,textarea,select,button,label,.ui-header-fixed,.ui-footer-fixed").length||(l=false,i&&(a.mobile.fixedToolbars.startShowTimer(),i=false),k=null)});d.bind("resize updatelayout",b)});a(".ui-page").live("pagebeforeshow",function(b,d){var e=a(b.target).find(":jqmData(role='footer')"),h=e.data("id"),g=d.prevPage,g=g&&g.find(":jqmData(role='footer')"),
g=g.length&&g.jqmData("id")===h;h&&g&&(c=e,f(c.removeClass("fade in out").appendTo(a.mobile.pageContainer)))}).live("pageshow",function(){var b=a(this);c&&c.length&&setTimeout(function(){f(c.appendTo(b).addClass("fade"));c=null},500);a.mobile.fixedToolbars.show(true,this)});a(".ui-collapsible-contain").live("collapse expand",b);return{show:function(b,c){a.mobile.fixedToolbars.clearShowTimer();g="overlay";return(c?a(c):a.mobile.activePage?a.mobile.activePage:a(".ui-page-active")).children(".ui-header-fixed:first, .ui-footer-fixed:not(.ui-footer-duplicate):last").each(function(){var c=
a(this),e=a(window).scrollTop(),h=d(c[0]),g=window.innerHeight,i=c.outerHeight(),e=c.is(".ui-header-fixed")&&e<=h+i||c.is(".ui-footer-fixed")&&h<=e+g;c.addClass("ui-fixed-overlay").removeClass("ui-fixed-inline");!e&&!b&&c.animationComplete(function(){c.removeClass("in")}).addClass("in");f(c)})},hide:function(b){g="inline";return(a.mobile.activePage?a.mobile.activePage:a(".ui-page-active")).children(".ui-header-fixed:first, .ui-footer-fixed:not(.ui-footer-duplicate):last").each(function(){var c=a(this),
d=c.css("top"),d=d=="auto"?0:parseFloat(d);c.addClass("ui-fixed-inline").removeClass("ui-fixed-overlay");if(d<0||c.is(".ui-header-fixed")&&d!==0)b?c.css("top",0):c.css("top")!=="auto"&&parseFloat(c.css("top"))!==0&&c.animationComplete(function(){c.removeClass("out reverse").css("top",0)}).addClass("out reverse")})},startShowTimer:function(){a.mobile.fixedToolbars.clearShowTimer();var b=[].slice.call(arguments);h=setTimeout(function(){h=e;a.mobile.fixedToolbars.show.apply(null,b)},100)},clearShowTimer:function(){h&&
clearTimeout(h);h=e},toggle:function(b){b&&(g=b);return g==="overlay"?a.mobile.fixedToolbars.hide():a.mobile.fixedToolbars.show()},setTouchToggleEnabled:function(a){o=a}}}}();a(document).bind("pagecreate create",function(b){a(":jqmData(position='fixed')",b.target).length&&a(b.target).each(function(){if(!a.support.scrollTop||a.support.touchOverflow&&a.mobile.touchOverflowEnabled)return this;var b=a(this);b.jqmData("fullscreen")&&b.addClass("ui-page-fullscreen");b.find(".ui-header:jqmData(position='fixed')").addClass("ui-header-fixed ui-fixed-inline fade");
b.find(".ui-footer:jqmData(position='fixed')").addClass("ui-footer-fixed ui-fixed-inline fade")})})})(jQuery);
(function(a){a.mobile.touchOverflowEnabled=false;a.mobile.touchOverflowZoomEnabled=false;a(document).bind("pagecreate",function(e){a.support.touchOverflow&&a.mobile.touchOverflowEnabled&&(e=a(e.target),e.is(":jqmData(role='page')")&&e.each(function(){var b=a(this),d=b.find(":jqmData(role='header'), :jqmData(role='footer')").filter(":jqmData(position='fixed')"),e=b.jqmData("fullscreen"),c=d.length?b.find(".ui-content"):b;b.addClass("ui-mobile-touch-overflow");c.bind("scrollstop",function(){c.scrollTop()>
0&&window.scrollTo(0,a.mobile.defaultHomeScroll)});d.length&&(b.addClass("ui-native-fixed"),e&&(b.addClass("ui-native-fullscreen"),d.addClass("fade in"),a(document).bind("vclick",function(){d.removeClass("ui-native-bars-hidden").toggleClass("in out").animationComplete(function(){a(this).not(".in").addClass("ui-native-bars-hidden")})})))}))})})(jQuery);
(function(a,e){function b(){var b=a("meta[name='viewport']");b.length?b.attr("content",b.attr("content")+", user-scalable=no"):a("head").prepend("<meta>",{name:"viewport",content:"user-scalable=no"})}var d=a("html");a("head");var f=a(e);a(e.document).trigger("mobileinit");if(a.mobile.gradeA()){if(a.mobile.ajaxBlacklist)a.mobile.ajaxEnabled=false;d.addClass("ui-mobile ui-mobile-rendering");var c=a("<div class='ui-loader ui-body-a ui-corner-all'><span class='ui-icon ui-icon-loading spin'></span><h1></h1></div>");
a.extend(a.mobile,{showPageLoadingMsg:function(){if(a.mobile.loadingMessage){var b=a("."+a.mobile.activeBtnClass).first();c.find("h1").text(a.mobile.loadingMessage).end().appendTo(a.mobile.pageContainer).css({top:a.support.scrollTop&&f.scrollTop()+f.height()/2||b.length&&b.offset().top||100})}d.addClass("ui-loading")},hidePageLoadingMsg:function(){d.removeClass("ui-loading")},initializePage:function(){var b=a(":jqmData(role='page')");b.length||(b=a("body").wrapInner("<div data-"+a.mobile.ns+"role='page'></div>").children(0));
b.add(":jqmData(role='dialog')").each(function(){var b=a(this);b.jqmData("url")||b.attr("data-"+a.mobile.ns+"url",b.attr("id")||location.pathname+location.search)});a.mobile.firstPage=b.first();a.mobile.pageContainer=b.first().parent().addClass("ui-mobile-viewport");f.trigger("pagecontainercreate");a.mobile.showPageLoadingMsg();!a.mobile.hashListeningEnabled||!a.mobile.path.stripHash(location.hash)?a.mobile.changePage(a.mobile.firstPage,{transition:"none",reverse:true,changeHash:false,fromHashChange:true}):
f.trigger("hashchange",[true])}});a.support.touchOverflow&&a.mobile.touchOverflowEnabled&&!a.mobile.touchOverflowZoomEnabled&&b();a.mobile._registerInternalEvents();a(function(){e.scrollTo(0,1);a.mobile.defaultHomeScroll=!a.support.scrollTop||a(e).scrollTop()===1?0:1;a.mobile.autoInitializePage&&a.mobile.initializePage();f.load(a.mobile.silentScroll)})}})(jQuery,this);
+24 -13
View File
@@ -2,7 +2,7 @@
<script><!--
jQuery(document).ready(function(){
jQuery("table.sortable tbody tr").mouseover( function() {
jQuery(this).addClass("highlight"); }).mouseout( function() {
jQuery(this).addClass("highlight"); }).mouseout( function() {
jQuery(this).removeClass("highlight"); });
jQuery('table.sortable tbody tr:odd').addClass('odd');
jQuery('table.sortable tbody tr:even').addClass('even');
@@ -63,11 +63,11 @@
<br/><br/>
<h4>{{=T("%s selected", nrows)}}</h4>
{{if start>0:}}{{=A(T('previous 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start-100)),_class="btn")}}{{pass}}
{{if stop<nrows:}}{{=A(T('next 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start+100)),_class="btn")}}{{pass}}
{{if stop<nrows:}}{{=A(T('next 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start+100)),_class="btn")}}{{pass}}
{{if rows:}}
<div style="overflow: auto;" width="80%">
{{linkto=URL('update',args=request.args[0])}}
{{upload=URL('download',args=request.args[0])}}
{{upload=URL('download',args=request.args[0])}}
{{=SQLTABLE(rows,linkto,upload,orderby=True,_class='sortable')}}
</div>
{{pass}}
@@ -75,7 +75,7 @@
<a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}" class="btn">{{=T("export as csv file")}}</a>
{{=formcsv or ''}}
{{elif request.function=='insert':}}
{{elif request.function=='insert':}}
<h2>{{=T("Database")}} {{=A(request.args[0],_href=URL('index'))}}
{{if hasattr(table,'_primarykey'):}}
{{fieldname=table._primarykey[0]}}
@@ -83,7 +83,7 @@
{{tablename=request.args[1]}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}}
{{else:}}
{{else:}}
{{=T("Table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}}
{{pass}}
</h2>
@@ -95,7 +95,7 @@
{{fieldname=request.vars.keys()[0]}}
{{dbname=request.args[0]}}
{{tablename=request.args[1]}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}}
{{=T("Record")}} {{=A('%s=%s'%request.vars.items()[0],_href=URL('update',args=request.args[:2],vars=request.vars))}}
{{else:}}
@@ -131,7 +131,7 @@
dict(ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
</p>
<p>
{{=T("Size of cache:")}}
{{=T("Size of cache:")}}
{{if object_stats:}}
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict(items=total['objects'], bytes=total['bytes']))}}
{{if total['bytes'] > 524287:}}
@@ -151,7 +151,7 @@
</div>
<br />
{{pass}}
<h4>{{=T("RAM")}}</h4>
<p>{{=T.M("Number of entries: **%s**", ram['entries'])}}</p>
{{if ram['entries'] > 0:}}
@@ -179,16 +179,16 @@
</div>
<br />
{{pass}}
<h4>{{=T("DISK")}}</h4>
<p>{{=T.M("Number of entries: **%s**", disk['entries'])}}</p>
{{if disk['entries'] > 0:}}
<p>
{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}}
dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}}
</p>
<p>
{{=T("Size of cache:")}}
{{=T("Size of cache:")}}
{{if object_stats:}}
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict( items=disk['objects'], bytes=disk['bytes']))}}
{{if disk['bytes'] > 524287:}}
@@ -209,11 +209,11 @@
<br />
{{pass}}
</div>
<div class="list-header">
<h3>{{=T("Manage Cache")}}</h3>
</div>
<div class="content">
<p>
{{=form}}
@@ -222,3 +222,14 @@
</div>
<div class="clear"></div>
{{pass}}
{{if request.function=='graph_model':}}
<h2>{{=T("Graph Model")}}</h2>
{{if not pgv:}}
{{=T('pygraphviz library not found')}}
{{elif not databases:}}
{{=T("No databases in this application")}}
{{else:}}
{{=IMG(_src=URL('appadmin', 'bg_graph_model'))}}
{{pass}}
{{pass}}
@@ -0,0 +1,137 @@
{{extend 'layout.html'}}
{{block sectionclass}}debug{{end}}
{{
frm_trs = form.elements('tr')
tbl_rows = []
for frm_tr in frm_trs:
if frm_tr['_id'] != 'submit_record__row':
fld_label = frm_tr.element('td.w2p_fl')
fld_widget = frm_tr.element('td.w2p_fw')[0]
fld_comment = frm_tr.element('td.w2p_fc')[0]
lbls = fld_label.elements('label')
lbl = ''
if len(lbls) > 0:
lbl = fld_label.elements('label')[0]
lbl['_class'] = 'control-label'
pass
if fld_widget['_type'] == 'checkbox':
fld_widget = LABEL(fld_widget, _class='checkbox')
else:
fld_widget = CAT(fld_widget, SPAN('', _class='help-inline'))
pass
if isinstance(fld_widget, SPAN):
fld_widget['_role'] = 'asinput'
pass
tbl_row = DIV(lbl, DIV(fld_widget,
TAG['SMALL'](fld_comment,
_class='help-block'),
_class='controls'), _class='control-group')
tbl_rows.append(tbl_row)
else:
smt_btn = frm_tr.element('td.w2p_fw')
btn = smt_btn.elements('input')[0]
btn['_class'] = 'btn btn-primary'
tbl_rows.append(DIV(btn, _class='controls'))
pass
pass
form.element('table', replace=CAT(*tbl_rows))
form['_class'] = 'form-horizontal well well-small'
import re
if form.errors:
for key, value in form.errors.iteritems():
inpt = form.element(_name=key)
inpt_wrapper = inpt.parent
if inpt_wrapper['_class'] == None or \
not "controls" in inpt_wrapper['_class']:
inpt_wrapper = inpt_wrapper.parent
pass
inpt_wrapper.parent['_class'] += ' error'
inpt_wrapper.element(_class=re.compile('help-inline'),
replace=lambda me:SPAN(value, _class=me['_class']))
pass
form.errors.clear()
pass
}}
<!-- begin "debug" block -->
<div class="row-fluid">
<div class="applist f60 span7" style="padding-bottom:20px;">
<div class="applist_inner">
<h2>{{=T("Breakpoints")}}</h2>
<div class="errorform">
<form name="myform" method="post">
<div class="tablebar">
<input value="{{=T('delete all checked')}}" type="submit" class="btn"/>
</div>
<div class="row-fluid">
<div class="span12 errors">
<table id="trck_breakpoints" class="sortable table table-hover table-condensed">
<thead>
<tr>
<th class="column1 cbcentered"><input type="checkbox" name="delete_all}" /></th>
<th class="column2">{{=T("Filename")}}</th>
<th class="column3">{{=T("Line Nr")}}</th>
<th>{{=T("Temporary")}}</th>
<th>{{=T("Condition")}}</th>
<th class="columnN">{{=T("Hits")}}</th>
</tr>
</thead>
<tbody>
{{for bp in breakpoints:}}
<tr class="breakpoint">
<td class="cbcentered"><input type="checkbox" name="delete_{{=bp['number']}}" /></td>
<td>{{=bp['filename']}}</td>
<td>{{=A(bp['lineno'],_href="#",_onclick="collapse('%s');" % bp['number'])}}</td>
<td>{{=bp['temporary']}}</td>
<td>{{=bp['condition']}}</td>
<td>{{=bp['hits']}}</td>
</tr>
<tr id="{{=bp['number']}}" class="sourcecode traceback">
<td colspan="6">
<div class="ticket_code">
{{=CODE(open(bp['path']).read(), language='python',
link=None, highlight_line=bp['lineno'], context_lines=10)}}
</div>
</td>
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
</form><!-- /errorform -->
</div>
</div>
</div><!-- /applist -->
<div class="sidebar fl60 span5">
<div class="sidebar_inner controls" style="margin:0;">
<div class="box">
<h3>{{=T("Add breakpoint")}}</h3>
{{=form}}
<div class="row-fluid">
<div class="help span12 alert alert-block alert-info">
<ul class="unstyled">
<li>{{=T("You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button")}}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('.sourcecode').hide();
jQuery("#trck_breakpoints thead tr th:first input[type=checkbox]").click(function() {
var checkedStatus = this.checked;
jQuery("#trck_breakpoints tbody tr td:first-child input[type=checkbox]").each(function() {
this.checked = checkedStatus;
});
});
jQuery("#trck_breakpoints tbody tr td:first-child input[type=checkbox]").change(function() {
var allchecked = jQuery("#trck_breakpoints tbody tr td:first-child input[type=checkbox]:checked").length == jQuery("#trck_breakpoints tbody tr td:first-child input[type=checkbox]").length;
jQuery("#trck_breakpoints thead tr th:first input[type=checkbox]").prop('checked', allchecked);
});
});
</script>
<!-- end "debug" block -->
@@ -0,0 +1,191 @@
{{extend 'layout.html'}}
{{block sectionclass}}debug{{end}}
<!-- begin "debug" block -->
<div class="row-fluid">
<div class="applist f60 span7" style="padding-bottom:20px;">
<div class="applist_inner">
<h2>{{=T("web2py online debugger")}}</h2>
{{if filename:}}
<h3 style="word-wrap:break-word;">{{=T("Interaction at %s line %s") % (filename, lineno)}}</h3>
{{if exception:}}
<h3 class="exception">{{=T("Exception %s", exception['title'])}}</h3>
{{pass}}
<h5>{{=T("Code listing")}}</h5>
{{if lines:}}<div class="inspect" style="width:100%;overflow:auto;background-color:whiteSmoke;margin-bottom:20px;">
<pre>{{=CODE('\n'.join([x[1] for x in sorted(lines.items(),key=lambda x: x[0])]),
language='python', link=None, counter=min(lines.keys()),
highlight_line=lineno, context_lines=10)}}</pre></div>
{{pass}}
<div class="row-fluid">
<div class="help span7 alert alert-block alert-info">
<ul class="unstyled">
<li>{{=T("Your application will be blocked until you click an action button (next, step, continue, etc.)")}}</li>
<li>{{=T("Your can inspect variables using the console below")}}</li>
</ul>
</div>
</div>
<h3>{{=T("Interactive console")}}</h3>
<div class="shell"><div id="wrapper">
<div class="row-fluid">
<div class="output-wrapper span11">
<textarea id="output" readonly="readonly">{{=data}}</textarea>
</div>
</div>
<div class="row-fluid">
<form id="form" action="{{=URL(r=request, f='callback', args=app)}}" method="get" class="span11">
<div id="shellwrapper">
<div class="prompt-wrapper">
<div class="prompt-container">
<textarea class="prompt" name="statement" id="statement"></textarea>
</div>
<a href="#" rel="tooltip" data-placement="right" data-original-title="{{=T('Type some Python code in here and hit Return (Enter) to execute it.')}}">
{{=helpicon()}}
<span>Type some Python code in here and hit Return (Enter) to execute it.</span>
</a>
</div>
<div id="caret"><span>&gt;&gt;&gt;</span></div>
<div id="autoscroll">autoscroll</div>
</div>
</form>
</div>
</div></div>
{{elif request.env.get('wsgi_multiprocess') or not request.env.get('wsgi_multithread'):}}
<h3 class="not_paused">{{=T("Unsupported webserver working mode: %s", request.env.get('server_software', ''))}}</h3>
<div class="help span7 alert alert-block alert-info">
<ul class="unstyled">
<li><b>{{=T("WARNING:")}} </b>{{=T("This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.")}}</li>
<li>{{=T("In development, use the default Rocket webserver that is currently supported by this debugger.")}}</li>
<li>{{=T("On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.")}}</li>
</ul>
</div>
{{#=BEAUTIFY(request.env)}}
{{else:}}
<h3 class="not_paused">{{=T("No Interaction yet")}}</h3>
<div class="help span7 alert alert-block alert-info">
<ul class="unstyled">
<li>{{=T("You need to set up and reach a")}} {{=A(T("breakpoint"), _href=URL('breakpoints'))}} {{=T('to use the debugger!')}}</li>
<li>{{=T('To emulate a breakpoint programatically, write:')}}
{{=CODE("from gluon.debug import dbg\n"
"dbg.set_trace() # stop here!\n",
counter=None)}}</li>
<li>{{=T('Please')}} {{=A(T("refresh"), _href=URL('interact'))}} {{=T('this page to see if a breakpoint was hit and debug interaction is required.')}}</li>
</ul>
</div>
{{pass}}
</div>
</div> <!-- /applist -->
<div class="sidebar fl60 span5">
<div class="sidebar_inner controls" style="margin:0;">
<span class="pwdchange pull-right">
{{if filename:}}
{{=sp_button(URL('step'), T("step"))}}
{{=sp_button(URL('next'), T("next"))}}
{{=sp_button(URL('ret'), T("return"))}}
{{=sp_button(URL('cont'), T("continue"))}}
{{=sp_button(URL('stop'), T("stop"))}}
{{pass}}
{{=button(URL('breakpoints'), T("breakpoints"))}}
</span>
{{if exception:}}
<div class="box">
<h3>{{=T('Exception %(extype)s: %(exvalue)s', dict(extype=exception['extype'], exvalue=exception['exvalue']))}}</h3>
<div class="formfield">
{{=CODE((exception['request']), counter=None)}}
</div>
</div>
{{pass}}
<div class="box">
<h3>{{=T('Locals##debug')}}</h3>
<div class="formfield">
{{=BEAUTIFY(f_locals)}}
</div>
</div>
<div class="box">
<h3>{{=T('Globals##debug')}}</h3>
<div class="formfield">
{{=BEAUTIFY(f_globals)}}
</div>
</div>
</div>
</div>
<script src="{{=URL('static', 'js/autoscroll.js')}}"></script>
<script type="text/javascript">
var bShellScrolling=0
jQuery(document).ready(function(){
jQuery('#statement').focus();
jQuery('#statement').keyup(function(event){
var t=jQuery(this),
s=t.val(),
o=jQuery('#output'),
RETURN = 38;
if(s=='\n') t.val('');
if(s.length>1 && s.substr(s.length-1,1)=='\n' && s.substr(s.length-2,1)!=':' &&
(s.indexOf(':\n ')<0 || s.substr(s.length-2,1)=='\n')) {
t.val('');
jQuery.post("{{=URL(r=request,f='execute',args=app)}}",
{statement:s},function(data){o.html(o.html()+data).attr('scrollTop',o.attr('scrollHeight'));});
} else { };
if(event.keyCode==RETURN){
var i=s.length
if(i==0){
var s=o.find('table:last pre:first').text();
bShellScrolling=o.find('table').length;
}else if(bShellScrolling){
var i=bShellScrolling
if(i<1){
return
}else{
i--
var s=o.find('table:nth-child('+(i)+') pre:first').text();
bShellScrolling=i
}
}else if(s.indexOf('\n')<0){
var oo=o.find('tr:first-child pre:contains("'+s+'")')
if(oo.length==0){
return
}else if(oo.length==1){
s=oo.text();
}else{
sVar=oo.text();
o.html(o.html()+'<dd>'+s+' ?</dd><dt>'+sVar+'</dt>').attr('scrollTop',o.attr('scrollHeight'))
return
}
}else{
//multistring expr
return;
}
// if(s.slice(s.length-1)=='\n'){
s=s.slice(0,s.length-1)
// }
t.val(s);
}
if(bShellScrolling && event.keyCode==40){
var i=bShellScrolling
i++
var s=o.find('table:nth-child('+i+') tr:first-child pre').text();
if(s){
s=s.slice(0,s.length-1)
t.val(s);
bShellScrolling=i
}else{
bShellScrolling=0
t.val('')
}
};
if(bShellScrolling && (event.keyCode==37 || event.keyCode==39)){
bShellScrolling=0;
};
if(event.keyCode==27){
bShellScrolling=0;
t.val('');
};
});
});
</script>
</div>
<!-- end "debug" block -->
+16 -14
View File
@@ -1,24 +1,26 @@
{{extend 'layout.html'}}
{{block sectionclass}}about{{end}}
<!-- begin "about" block -->
<h2>{{=T("About application")}} "{{=app}}"</h2>
<h3>{{=T("About")}} {{=app}}</h3>
<p class="controls">{{=button(URL('edit/%s/ABOUT' % (app)), T('Edit'))}}</p>
<div class="about_text legalese">{{=about}}</div>
<div class="about_text legalese well well-small">{{=about}}</div>
<h3>{{=T('License for')}} {{=app}}</h3>
<p class="controls">{{=button(URL('edit/%s/LICENSE' % (app)), T('Edit'))}}</p>
<div class="license_text legalese">{{=license}}</div>
</ul>
<script language="javascript" type="text/javascript" src="{{=URL('static','js/jquery.flot.js')}}"></script>
<div class="license_text legalese well well-small">{{=license}}</div>
<h3>{{=T('Project Progress')}}</h3>
<p>
<center>
<div id="placeholder" style="width:600px;height:300px;"></div>
</center>
<script language="javascript" type="text/javascript" src="{{=URL('static','js/jquery.flot.js')}}"></script>
<script language="javascript" type="text/javascript" src="{{=URL('static','js/jquery.flot.resize.js')}}"></script>
<div class="row-fluid">
<div class="span2"> </div>
<div class="span8 center">
<div id="placeholder"></div>
</div>
<div class="span2"> </div>
</div>
<script type="text/javascript">
jQuery(function () { jQuery.plot(jQuery("#placeholder"), [ {{=progress}} ]); });
jQuery(document).ready(function() {
jQuery.plot(jQuery("#placeholder"), [ {{=progress}} ]);
})
</script>
</p>
<!-- end "about" block -->
@@ -1,5 +1,20 @@
{{extend 'layout.html'}}
<h1>{{=T('Bulk Student Registration')}}</h1>
{{=form}}
{{
# add bootstrap class to form
form['_class']='span4 well well-small'
# change form.custom.begin
form.custom.begin=XML("<%s %s>" % (form.tag,form._xml()[0]))
# new form buttons
smt = form.element('input',_type='submit')
smt['_class']='btn'
form.element('input[type=submit]',replace=lambda button: DIV(button,_class="controls-inline"))
}}
<h2>{{=T('Bulk Student Registration').capitalize()}}</h2>
<div id="web2py_user_form">
{{=form.custom.begin}}
{{for e in form.components[0]:}}
{{= e[0][0]}}
{{= e[1][0]}}
{{pass}}
{{=form.custom.end}}
</div>
@@ -1,10 +1,22 @@
{{extend 'layout.html'}}
{{block sectionclass}}change_password{{end}}
<h2>Change Admin Password</h2>
<!-- begin "change_password" block -->
<h2>web2py&trade; {{=T('Web Framework')}}</h2>
<h3>{{=T('Change Admin Password')}}</h3>
<div class="pwform">
{{=form}}
{{=form.custom.begin}}
{{ for fieldname in form.table.fields: }}
{{if fieldname is not 'id':}}
<label>{{=form.custom.label[fieldname]}}</label>
{{=form.custom.widget[fieldname]}}
{{pass}}
{{pass}}
<div class="controls"><button type="submit" class="btn">{{=T('Submit')}}</button></div>
{{=form.custom.end}}
</div>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery(":input:visible:enabled:first").focus();
});
</script>
<!-- end "change_password" block -->
+10 -3
View File
@@ -1,9 +1,16 @@
{{extend 'layout.html'}}
{{
dlg = dialog
smt_button = dlg.element(_type="submit")
smt_button['_class'] = 'btn'
smt_button['_style'] = 'margin-right:4px;'
ccl_button = dlg.element(_type="button")
ccl_button['_class'] = 'btn'
}}
{{block sectionclass}}delete{{end}}
<!-- begin "delete" block -->
<h2>{{=T('Are you sure you want to delete file "%s"?', filename)}}</h2>
<div class="center">
{{=dialog}}
</div>
<!-- end "delete" block -->
@@ -1,9 +1,16 @@
{{extend 'layout.html'}}
{{
dlg = dialog
smt_button = dlg.element(_type="submit")
smt_button['_class'] = 'btn'
smt_button['_style'] = 'margin-right:4px;'
ccl_button = dlg.element(_type="button")
ccl_button['_class'] = 'btn'
}}
{{block sectionclass}}delete_plugin{{end}}
<!-- begin "delete_plugin" block -->
<h2>{{=T('Are you sure you want to delete plugin "%s"?', plugin)}}</h2>
<div class="center">
{{=dialog}}
</div>
<!-- end "delete_plugin" block -->
+382 -317
View File
@@ -1,58 +1,81 @@
{{extend 'layout.html'}}
{{
def all(items):
return reduce(lambda a,b:a and b,items,True)
return reduce(lambda a,b:a and b,items,True)
def peekfile(path,file,vars={},title=None):
args=(path,file) if 'app' in vars else (app,path,file)
return A(file.replace('\\\\','/'),_title=title,_href=URL('peek', args=args, vars=vars))
args=(path,file) if 'app' in vars else (app,path,file)
return A(file.replace('\\\\','/'),_title=title,_href=URL('peek', args=args, vars=vars))
def editfile(path,file,vars={}):
args=(path,file) if 'app' in vars else (app,path,file)
return A(SPAN(T('Edit')),_class='button editbutton',_href=URL('edit', args=args, vars=vars))
args=(path,file) if 'app' in vars else (app,path,file)
return A(SPAN(T('Edit')),_class='button editbutton btn',_href=URL('edit', args=args, vars=vars))
def testfile(path,file):
return A(TAG[''](IMG(_src=URL('static', 'images/test_icon.png'), _alt=T('test')), SPAN(T("Run tests in this file (to run all files, you may also use the button labelled 'test')"))), _class='icon test tooltip',_href=URL('test', args=(app, file)))
return A(TAG[''](IMG(_src=URL('static', 'images/test_icon.png'), _alt=T('test')),
SPAN(T("Run tests in this file (to run all files, you may also use the button labelled 'test')"))),
_class='icon test',
_href=URL('test', args=(app, file)),
_rel="tooltip",
**{'_data-placement':'right',
'_data-original-title':T("Run tests in this file (to run all files, you may also use the button labelled 'test')")})
def editlanguagefile(path,file,vars={}):
return A(SPAN(T('Edit')),_class='button editbutton',_href=URL('edit_language', args=(app, path, file), vars=vars))
return A(SPAN(T('Edit')),_class='button editbutton btn',_href=URL('edit_language', args=(app, path, file), vars=vars))
def editpluralsfile(path,file,vars={}):
return A(SPAN(T('Edit')),_class='button editbutton',_href=URL('edit_plurals', args=(app, path, file), vars=vars))
return A(SPAN(T('Edit')),_class='button editbutton btn',_href=URL('edit_plurals', args=(app, path, file), vars=vars))
def file_upload_form(location, anchor=None):
form=FORM(T("upload file:")," ",
INPUT(_type="file",_name="file")," ",T("and rename it:")," ",
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY),
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="token",_value=session.token),
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app, anchor=anchor)),
INPUT(_type="submit",_value=T("upload")),_action=URL('upload_file'))
return form
def file_create_form(location, anchor=None):
form=FORM(T("create file with filename:")," ",
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY),
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app)),
INPUT(_type="hidden",_name="token",_value=session.token),
INPUT(_type="hidden",_name="id",_value=anchor),
INPUT(_type="submit",_value=T("Create")),_action=URL('create_file'))
return form
form=FORM(
LABEL(T("upload file:")),
INPUT(_type="file",_name="file"),
LABEL(T("and rename it:")),
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY,_class=""),
DIV(TAG['BUTTON'](T("Upload"),_type="submit",_class="btn"),_class="controls"),
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="token",_value=session.token),
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app, anchor=anchor)),
_action=URL('upload_file'),
_class="generatedbyw2p well well-small")
return form
def file_create_form(location, anchor=None, helptext=""):
form=FORM(
LABEL(T("create file with filename:")),
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY,_class=''),
TAG['SMALL'](helptext,_class="help-block"),
DIV(TAG['BUTTON'](T("Create"),_type="submit",_class="btn"),_class="controls"),
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app)),
INPUT(_type="hidden",_name="token",_value=session.token),
INPUT(_type="hidden",_name="id",_value=anchor),
_action=URL('create_file'),
_class="generatedbyw2p well well-small")
return form
def upload_plugin_form(app, anchor=None):
form=FORM(T("upload plugin file:")," ",
INPUT(_type="file",_name="pluginfile"),
INPUT(_type="hidden",_name="id",_value=anchor),
INPUT(_type="hidden",_name="token",_value=session.token),
INPUT(_type="submit",_value=T("upload")))
return form
form=FORM(
LABEL(T("upload plugin file:")),
INPUT(_type="file",_name="pluginfile"),
INPUT(_type="hidden",_name="id",_value=anchor),
INPUT(_type="hidden",_name="token",_value=session.token),
DIV(TAG['BUTTON'](T("Upload"),_type="submit",_class="btn"),_class="controls"),
_class="generatedbyw2p well well-small")
return form
def deletefile(arglist, vars={}):
vars.update({'sender':request.function+'/'+app})
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')), SPAN(T('Delete this file (you will be asked to confirm deletion)'))), _class='icon delete tooltip', _href=URL('delete',args=arglist,vars=vars))
vars.update({'sender':request.function+'/'+app})
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')),
SPAN(T('Delete this file (you will be asked to confirm deletion)'))),
_href=URL('delete',args=arglist,vars=vars),
_class='icon delete',
_rel="tooltip",
**{'_data-placement':'right',
'_data-original-title':T('Delete this file (you will be asked to confirm deletion)')})
}}
{{block sectionclass}}design{{end}}
<!-- begin "design" block -->
<h2>{{=T("Edit application")}} "{{=A(app,_href=URL(app,'default','index'),_target="_blank")}}"</h2>
<!-- COLLAPSE/JUMP-TO BUTTONS -->
<div class="right-full controls">
<p>
<p class="buttons-row">
{{=searchbox('search')}}
<a class="button special" href="#" onclick="jQuery('h3').click();return false"><span>{{=T("collapse/expand all")}}</span></a>
<a class="button special btn btn-inverse" href="#" onclick="jQuery('h3>span').click();return false"><span>{{=T("collapse/expand all")}}</span></a>
<span class="buttongroup">
{{=button('#models', T("models"))}}
{{=button('#controllers', T("controllers"))}}
@@ -63,43 +86,49 @@ def deletefile(arglist, vars={}):
{{=button('#private', T("private files"))}}
{{=button('#plugins', T("plugins"))}}
</span>
</p>
</p>
</div>
<!-- MODELS -->
<h3 id="models" onclick="collapse('models_inner');" class="component">
{{=T("Models")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("The data representation, define database tables and sets")}}</span></span>
<h3 id="_models" rel="pagebookmark">
<span class="component" onclick="collapse('models_inner');">{{=T("Models")}}</span>
<a href="#models" rel="tooltip" data-placement="right" data-original-title="{{=T('The data representation, define database tables and sets')}}">
{{=helpicon()}}
<span>{{=T("The data representation, define database tables and sets")}}</span>
</a><span id="models" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="models_inner" class="component_contents">
{{if not models:}}<p><strong>{{=T("There are no models")}}</strong></p>{{else:}}
<div class="controls comptools">
{{=button(URL(a=app,c='appadmin',f='index'), T('database administration'))}}
{{if os.access(os.path.join(request.folder,'..',app,'databases','sql.log'),os.R_OK):}}
{{=button(URL('peek/%s/databases/sql.log'%app), 'sql.log')}}
{{pass}}
</div>
{{pass}}
<ul>
{{for m in models:}}
{{id="models__"+m.replace('.','__')}}
<li id="{{=id}}">
<span class="filetools controls">
{{=editfile('models',m, dict(id=id))}}
{{=deletefile([app, 'models', m], dict(id=id, id2='models'))}}
</span>
<span class="file">
{{=peekfile('models',m, dict(id=id))}}
</span>
<span class="extras">
{{if len(defines[m]):}}{{=T("defines tables")}} {{pass}}{{=XML(', '.join([B(table).xml() for table in defines[m]]))}}
</span>
</li>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/models/' % app, 'models')}}</div>
{{if not models:}}<p><strong>{{=T("There are no models")}}</strong></p>{{else:}}
<div class="controls comptools">
{{=button(URL(a=app,c='appadmin',f='index'), T('database administration'))}}
{{if os.access(os.path.join(request.folder,'..',app,'databases','sql.log'),os.R_OK):}}
{{=button(URL('peek/%s/databases/sql.log'%app), 'sql.log')}}
{{pass}}
{{=button(URL(a=app, c='appadmin',f='graph_model'), T('graph model'))}}
</div>
<ul class="unstyled act_edit">
{{for m in models:}}
{{id="models__"+m.replace('.','__')}}
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick">&nbsp;</span>
<span class="filetools controls">
{{=editfile('models',m, dict(id=id))}}
{{=deletefile([app, 'models', m], dict(id=id, id2='models'))}}
</span>
<span class="file">
{{=peekfile('models',m, dict(id=id))}}
</span>
<span class="extras">
{{if len(defines[m]):}}{{=T("defines tables")}} {{pass}}{{=XML(', '.join([B(table).xml() for table in defines[m]]))}}
</span>
</li>
{{pass}}
</ul>
{{pass}}
<div class="controls formfield">
<div class="row-fluid">
<div class="span3">{{=file_create_form('%s/models/' % app, 'models')}}</div>
</div>
</div>
</div>
<!-- FIND CONTROLLER FUNCTIONS -->
@@ -109,289 +138,325 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
}}
<!-- CONTROLLERS -->
<h3 id="controllers" onclick="collapse('controllers_inner');" class="component">
{{=T("Controllers")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("The application logic, each URL path is mapped in one exposed function in the controller")}}</span></span>
<h3 id="_controllers" rel="pagebookmark">
<span class="component" onclick="collapse('controllers_inner');">{{=T("Controllers")}}</span>
<a href="#controllers" rel="tooltip" data-placement="right" data-original-title="{{=T('The application logic, each URL path is mapped in one exposed function in the controller')}}">
{{=helpicon()}}
<span>{{=T("The application logic, each URL path is mapped in one exposed function in the controller")}}</span>
</a><span id="controllers" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="controllers_inner" class="component_contents">
{{if not controllers:}}<p><strong>{{=T("There are no controllers")}}</strong></p>{{else:}}
<div class="controls comptools">
{{=button(URL(r=request,c='shell',f='index',args=app), T("shell"))}}
{{=button(URL('test',args=app), T("test"))}}
{{=button(URL('edit',args=[app,'cron','crontab']), T("crontab"))}}
</div>
{{pass}}
<ul>
{{for c in controllers:}}
{{id="controllers__"+c.replace('.','__')}}
<li id="{{=id}}">
<span class="filetools controls">
{{=editfile('controllers',c, dict(id=id))}}
{{=deletefile([app, 'controllers', c], dict(id=id, id2='controllers'))}}
{{=testfile('controllers',c)}}
</span>
<span class="file">
{{=peekfile('controllers',c, dict(id=id))}}
</span>
<span class="extras">
{{if functions[c]:}}{{=T("exposes")}} {{pass}}{{=XML(', '.join([A(f,_href=URL(a=app,c=c[:-3],f=f)).xml() for f in functions[c]]))}}
</span>
</li>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/controllers/' % app, 'controllers')}}</div>
{{if not controllers:}}<p><strong>{{=T("There are no controllers")}}</strong></p>{{else:}}
<div class="controls comptools">
{{=button(URL(r=request,c='shell',f='index',args=app), T("shell"))}}
{{=button(URL('test',args=app), T("test"))}}
{{=button(URL('edit',args=[app,'cron','crontab']), T("crontab"))}}
</div>
<ul class="unstyled act_edit">
{{for c in controllers:}}
{{id="controllers__"+c.replace('.','__')}}
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick">&nbsp;</span>
<span class="filetools controls">
{{=editfile('controllers',c, dict(id=id))}}
{{=deletefile([app, 'controllers', c], dict(id=id, id2='controllers'))}}
{{=testfile('controllers',c)}}
</span>
<span class="file">
{{=peekfile('controllers',c, dict(id=id))}}
</span>
<span class="extras celled">
{{if functions[c]:}}{{=T("exposes")}}{{pass}} {{=XML(', '.join([A(f,_href=URL(a=app,c=c[:-3],f=f)).xml() for f in functions[c]]))}}
</span>
</li>
{{pass}}
</ul>
{{pass}}
<div class="controls formfield">
<div class="row-fluid">
<div class="span3">{{=file_create_form('%s/controllers/' % app, 'controllers')}}</div>
</div>
</div>
</div>
<!-- VIEWS -->
<h3 id="views" onclick="collapse('views_inner');" class="component">
{{=T("Views")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("The presentations layer, views are also known as templates")}}</span></span>
<h3 id="_views" rel="pagebookmark">
<span class="component" onclick="collapse('views_inner');">{{=T("Views")}}</span>
<a href="#views" rel="tooltip" data-placement="right" data-original-title="{{=T('The presentations layer, views are also known as templates')}}">
{{=helpicon()}}
<span>{{=T("The presentations layer, views are also known as templates")}}</span>
</a><span id="views" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="views_inner" class="component_contents">
<div class="controls comptools">
{{=button(LAYOUTS_APP, T("download layouts"))}}
</div>
{{if not views:}}<p><strong>{{=T("There are no views")}}</strong></p>{{pass}}
<ul>
{{for c in views:}}
{{id="views__"+c.replace('/','__').replace('.','__')}}
<li id="{{=id}}">
<span class="filetools controls">
{{=editfile('views',c, dict(id=id))}}
{{=deletefile([app, 'views', c], dict(id=id, id2='views'))}}
</span>
<span class="file">
{{=peekfile('views',c, dict(id=id))}}
</span>
<span class="extras">
{{if extend.has_key(c):}}{{=T("extends")}} <b>{{=extend[c]}}</b> {{pass}}
{{if include[c]:}}{{=T("includes")}} {{pass}}{{=XML(', '.join([B(f).xml() for f in include[c]]))}}
</span>
</li>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/views/' % app, 'views')}}</div>
{{if not views:}}<p><strong>{{=T("There are no views")}}</strong></p>{{else:}}
<div class="controls comptools">
{{=button(LAYOUTS_APP, T("download layouts"))}}
</div>
<ul class="unstyled act_edit">
{{for c in views:}}
{{id="views__"+c.replace('/','__').replace('.','__')}}
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick">&nbsp;</span>
<span class="filetools controls">
{{=editfile('views',c, dict(id=id))}}
{{=deletefile([app, 'views', c], dict(id=id, id2='views'))}}
</span>
<span class="file">
{{=peekfile('views',c, dict(id=id))}}
</span>
<span class="extras celled celled-one">
{{if extend.has_key(c):}}{{=T("extends")}} <b>{{=extend[c]}}</b> {{pass}}
{{if include[c]:}}{{=T("includes")}} {{pass}}{{=XML(', '.join([B(f).xml() for f in include[c]]))}}
</span>
</li>
{{pass}}
</ul>
{{pass}}
<div class="controls formfield">
<div class="row-fluid">
<div class="span3">{{=file_create_form('%s/views/' % app, 'views')}}</div>
</div>
</div>
</div>
<!-- LANGUAGES -->
<h3 id="languages" onclick="collapse('languages_inner');" class="component">
{{=T("Languages")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("Translation strings for the application")}}</span></span>
<h3 id="_languages" rel="pagebookmark">
<span class="component" onclick="collapse('languages_inner');">{{=T("Languages")}}</span>
<a href="#languages" rel="tooltip" data-placement="right" data-original-title="{{=T('Translation strings for the application')}}">
{{=helpicon()}}
<span>{{=T("Translation strings for the application")}}</span>
</a><span id="languages" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="languages_inner" class="component_contents">
<div class="controls comptools">
{{=button(URL('update_languages/'+app), T('update all languages'))}}
</div>
{{if not languages:}}<p><strong>{{=T("There are no translators, only default language is supported")}}</strong></p>{{pass}}
<table>
{{for lang in sorted(languages):
file = lang+'.py'
id = "languages__"+file.replace('.','__')}}
<tr id="{{=id}}">
<td>
<span class="filetools controls">
{{=editlanguagefile('languages',file)}}
{{=deletefile([app, 'languages', file], dict(id=id, id2='languages'))}}
</span>
<span class="file">
{{=peekfile('languages',file, dict(id=id))}}
</span>
</td>
<td>
&nbsp;
(
{{=T("Plural-Forms:")}}
{{p=languages[lang][3:7]}}
{{if p[2] == 'default':}}
<span class='error'>{{=T("rules are not defined")}}</span> {{=T.M("(file **gluon/contrib/plural_rules/%s.py** is not found)",lang[:2])}}
{{else:}}
{{if p[3] == 1:}}
{{=B(T("are not used"))}}
{{else:}}
{{pfile=p[0]}}
{{if p[1]!=0:}}
<span class="filetools controls">
{{=editpluralsfile('languages',pfile,dict(nplurals=p[3]))}}
</span>
<span class="file">
{{=peekfile('languages',pfile,dict(id=id))}}
</span>
{{else:}}
<b>{{=T("are not used yet")}}</b>
{{pass}}
{{pass}}
{{pass}}
)
</td>
</tr>
{{pass}}
</table>
{{pass}}
<div class="controls formfield">{{=file_create_form('%s/languages/' % app, 'languages')}}{{=T('(something like "it-it")')}}</div>
{{if not languages:}}<p><strong>{{=T("There are no translators, only default language is supported")}}</strong></p>{{else:}}
<div class="controls comptools">
{{=button(URL('update_languages/'+app), T('update all languages'))}}
</div>
<ul class="unstyled act_edit">
{{for lang in sorted(languages):
file = lang+'.py'
id = "languages__"+file.replace('.','__')}}
<li id="{{='_'+id}}" rel="pagebookmark" class="li-row"><span id="{{=id}}" class="hashstick">&nbsp;</span>
<span class="li-controls">
<span class="filetools controls">
{{=editlanguagefile('languages',file)}}
{{=deletefile([app, 'languages', file], dict(id=id, id2='languages'))}}
</span>
<span class="">
{{=peekfile('languages',file, dict(id=id))}}
</span>
</span> <!-- /li-row -->
<span class="extras celled">
(
{{=T("Plural-Forms:")}}
{{p=languages[lang][3:7]}}
{{if p[2] == 'default':}}
<span class='error text-error'>{{=T("rules are not defined")}}</span> {{=T.M("(file **gluon/contrib/plural_rules/%s.py** is not found)",lang[:2])}}
{{else:}}
{{if p[3] == 1:}}
{{=B(T("are not used"))}}
{{else:}}
{{pfile=p[0]}}
{{if p[1]!=0:}}<span style="display:inline-block;margin-top:-10px;">
<span class="filetools controls">
{{=editpluralsfile('languages',pfile,dict(nplurals=p[3]))}}
</span>
<span class="file">
{{=peekfile('languages',pfile,dict(id=id))}}
</span></span>
{{else:}}
<b>{{=T("are not used yet")}}</b>
{{pass}}
{{pass}}
{{pass}}
)
</span>
</li>
{{pass}}
</ul>
{{pass}}
<div class="controls formfield">
<div class="row-fluid">
<div class="span3">{{=file_create_form('%s/languages/' % app, 'languages', T('(something like "it-it")'))}}</div>
</div>
</div>
</div>
<!-- STATIC -->
<h3 id="static" onclick="collapse('static_inner');" class="component">
{{=T("Static files")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("These files are served without processing, your images go here")}}</span></span>
<h3 id="_static" rel="pagebookmark">
<span class="component" onclick="collapse('static_inner');">{{=T("Static")}}</span>
<a href="#static" rel="tooltip" data-placement="right" data-original-title="{{=T('These files are served without processing, your images go here')}}">
{{=helpicon()}}
<span>{{=T("These files are served without processing, your images go here")}}</span>
</a><span id="static" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="static_inner" class="component_contents">
<div class="controls comptools">
</div>
{{if not statics:}}<p><strong>{{=T("There are no static files")}}</strong></p>{{pass}}
<ul>
{{
path=[]
for file in statics+['']:
items=file.split('/')
file_path=items[:-1]
filename=items[-1]
while path!=file_path:
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
path.append(file_path[len(path)])
thispath='static__'+'__'.join(path)
}}
<li class="folder">
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
else:
path = path[:-1]
}}
</ul></li>
{{
pass
pass
if filename:
}}<li>
<span class="filetools controls">
{{=editfile('static',file, dict(id="static"))}} {{=deletefile([app,'static',file], dict(id="static",id2="static"))}}
</span>
<span class="file">
<a href="{{=URL(a=app,c='static',f=file)}}">{{=filename}}</a>
</span>
</li>{{
pass
pass
}}
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/static/' % app, 'static')}}
{{=file_upload_form('%s/static/' % app, 'static')}}</div>
{{if not statics:}}<p><strong>{{=T("There are no static files")}}</strong></p>{{else:}}
<ul class="unstyled act_edit">
{{
path=[]
for file in statics+['']:
items=file.split('/')
file_path=items[:-1]
filename=items[-1]
while path!=file_path:
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
path.append(file_path[len(path)])
thispath='static__'+'__'.join(path)
}}
<li class="folder"><i>&nbsp;</i>
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
else:
path = path[:-1]
}}
</ul></li>
{{
pass
pass
if filename:
}}
<li>
<span class="filetools controls">
{{=editfile('static',file, dict(id="static"))}} {{=deletefile([app,'static',file], dict(id="static",id2="static"))}}
</span>
<span class="file">
<a href="{{=URL(a=app,c='static',f=file)}}">{{=filename}}</a>
</span>
</li>{{
pass
pass
}}
</ul>
{{pass}}
<div class="controls formfield">
<div class="row-fluid">
<div class="span3">{{=file_create_form('%s/static/' % app, 'static')}}<em>{{=T('or alternatively')}}</em></div>
<div class="span3">{{=file_upload_form('%s/static/' % app, 'static')}}</div>
</div>
</div>
</div>
<!-- MODULES -->
<h3 id="modules" onclick="collapse('modules_inner');" class="component">
{{=T("Modules")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("Additional code for your application")}}</span></span>
<h3 id="_modules" rel="pagebookmark">
<span class="component" onclick="collapse('modules_inner');">{{=T("Modules")}}</span>
<a href="#modules" rel="tooltip" data-placement="right" data-original-title="{{=T('Additional code for your application')}}">
{{=helpicon()}}
<span>{{=T("Additional code for your application")}}</span>
</a><span id="modules" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="modules_inner" class="component_contents">
<div class="controls comptools">
</div>
{{if not modules:}}<p><strong>{{=T("There are no modules")}}</strong></p>{{pass}}
<ul>
{{for m in modules:}}
{{id="modules__"+m.replace('/','__').replace('.','__')}}
<li id="{{=id}}">
<span class="filetols controls">
{{=editfile('modules',m,dict(id=id))}}
{{if m!='__init__.py':}}
{{=deletefile([app, 'modules', m], dict(id=id, id2='modules'))}}
{{pass}}
</span>
<span class="file">
{{=peekfile('modules',m, dict(id=id))}}
</span>
</li>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/modules/' % app, 'modules')}}
{{=file_upload_form('%s/modules/' % app, 'modules')}}</div>
{{if not modules:}}<p><strong>{{=T("There are no modules")}}</strong></p>{{else:}}
<ul class="unstyled act_edit">
{{for m in modules:}}
{{id="modules__"+m.replace('/','__').replace('.','__')}}
<li id="{{='_'+id}}" rel="pagebookmark"><span id="{{=id}}" class="hashstick">&nbsp;</span>
<span class="filetols controls">
{{=editfile('modules',m,dict(id=id))}}
{{if m!='__init__.py':}}
{{=deletefile([app, 'modules', m], dict(id=id, id2='modules'))}}
{{pass}}
</span>
<span class="file">
{{=peekfile('modules',m, dict(id=id))}}
</span>
</li>
{{pass}}
</ul>
{{pass}}
<div class="controls formfield">
<div class="row-fluid">
<div class="span3">{{=file_create_form('%s/modules/' % app, 'modules')}}<em>{{=T('or alternatively')}}</em></div>
<div class="span3">{{=file_upload_form('%s/modules/' % app, 'modules')}}</div>
</div>
</div>
</div>
<!-- PRIVATE -->
<h3 id="private" onclick="collapse('private_inner');" class="component">
{{=T("Private files")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("These files are not served, they are only available from within your app")}}</span></span>
<h3 id="_private" rel="pagebookmark">
<span class="component" onclick="collapse('private_inner');">{{=T("Private files")}}</span>
<a href="#private" rel="tooltip" data-placement="right" data-original-title="{{=T('These files are not served, they are only available from within your app')}}">
{{=helpicon()}}
<span>{{=T("These files are not served, they are only available from within your app")}}</span>
</a><span id="private" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="private_inner" class="component_contents">
<div class="controls comptools">
</div>
{{if not privates:}}<p><strong>{{=T("There are no private files")}}</strong></p>{{pass}}
<ul>
{{
path=[]
for file in privates+['']:
items=file.split('/')
file_path=items[:-1]
filename=items[-1]
while path!=file_path:
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
path.append(file_path[len(path)])
thispath='private__'+'__'.join(path)
}}
<li class="folder">
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
else:
path = path[:-1]
}}
</ul></li>
{{
pass
pass
if filename:
}}<li>
<span class="filetools controls">
{{=editfile('private',file, dict(id="private"))}} {{=deletefile([app,'private',file], dict(id="private",id2="private"))}}
</span>
<span class="file">
{{=peekfile('private',file, dict(id="private"))}}
</span>
</li>{{
pass
pass
}}
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/private/' % app, 'private')}}
{{=file_upload_form('%s/private/' % app, 'private')}}</div>
{{if not privates:}}<p><strong>{{=T("There are no private files")}}</strong></p>{{else:}}
<ul class="unstyled act_edit">
{{
path=[]
for file in privates+['']:
items=file.split('/')
file_path=items[:-1]
filename=items[-1]
while path!=file_path:
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
path.append(file_path[len(path)])
thispath='private__'+'__'.join(path)
}}
<li class="folder">
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
else:
path = path[:-1]
}}
</ul>
</li>
{{
pass
pass
if filename:
}}
<li>
<span class="filetools controls">
{{=editfile('private',file, dict(id="private"))}} {{=deletefile([app,'private',file], dict(id="private",id2="private"))}}
</span>
<span class="file">
{{=peekfile('private',file, dict(id="private"))}}
</span>
</li>{{
pass
pass
}}
{{pass}}
</ul>
<div class="controls formfield">
<div class="row-fluid">
<div class="span3">{{=file_create_form('%s/private/' % app, 'private')}}<em>{{=T('or alternatively')}}</em></div>
<div class="span3">{{=file_upload_form('%s/private/' % app, 'private')}}</div>
</div>
</div>
</div>
<!-- PLUGINS -->
<h3 id="plugins" onclick="collapse('plugins_inner');" class="component">
{{=T("Plugins")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("To create a plugin, name a file/folder plugin_[name]")}}</span></span>
<h3 id="_plugins" rel="pagebookmark">
<span class="component" onclick="collapse('plugins_inner');">{{=T("Plugins")}}</span>
<a href="#plugins" rel="tooltip" data-placement="right" data-original-title="{{=T('To create a plugin, name a file/folder plugin_[name]')}}">
{{=helpicon()}}
<span>{{=T("To create a plugin, name a file/folder plugin_[name]")}}</span>
</a><span id="plugins" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="plugins_inner" class="component_contents">
<div class="controls comptools">
{{=button(PLUGINS_APP, T('download plugins'))}}
</div>
<div class="controls">
</div>
{{if plugins:}}
<ul>
{{for plugin in plugins:}}
{{id="plugins__"+plugin.replace('/','__').replace('.','__')}}
<li id="{{=id}}">
{{=A('plugin_%s' % plugin, _class='file', _href=URL('plugin', args=[app, plugin], vars=dict(id=id, id2='plugins')))}}
</li>
{{pass}}
</ul>
{{else:}}
<p><strong>{{=T('There are no plugins')}}</strong></p>
{{pass}}
<div class="controls formfield">{{=upload_plugin_form(app, 'plugins')}}</div>
<div class="controls comptools">
{{=button(PLUGINS_APP, T('download plugins'))}}
</div>
{{if plugins:}}
<ul class="unstyled act_edit">
{{for plugin in plugins:}}
{{id="plugins__"+plugin.replace('/','__').replace('.','__')}}
<li id="{{=id}}">
{{=A('plugin_%s' % plugin, _class='file', _href=URL('plugin', args=[app, plugin], vars=dict(id=id, id2='plugins')))}}
</li>
{{pass}}
</ul>
{{else:}}
<p><strong>{{=T('There are no plugins')}}</strong></p>
{{pass}}
<div class="controls formfield">
<div class="row-fluid">
<div class="span3">{{=upload_plugin_form(app, 'plugins')}}</div>
</div>
</div>
</div>
<script>
function filter_files() {
if(jQuery('#search').val()){
@@ -416,4 +481,4 @@ jQuery(document).ready(function(){
jQuery('#search_start').click(function(e){ filter_files(); });
});
</script>
<!-- end "design" block -->
+78 -60
View File
@@ -1,8 +1,8 @@
{{extend 'layout.html'}}
<!-- begin "edit" block -->
{{
def shortcut(combo, description):
return XML('<li><tt>%s</tt> %s</li>' % (combo, description))
return XML('<li><span class="teletype-text">%s</span><span>%s</span></li>' % (combo, description))
}}
{{if TEXT_EDITOR == 'amy':}}
{{include 'default/amy_ajax.html'}}
@@ -88,7 +88,7 @@ jQuery(document).ready(function(){
<h2>{{=T('Editing file "%s"',filename)}}</h2>
{{if functions:}}
<p class="formfield">
<p class="formfield well well-small">
<span style="text-align:left;" id="exposed">
{{=B(T('exposes:'))}} {{=XML(', '.join([A(f,_href=URL(a=app,c=controller,f=f)).xml() for f in functions]))}}
</span>
@@ -98,15 +98,15 @@ jQuery(document).ready(function(){
{{pass}}
</p>
{{pass}}
<p class="right controls">
<div class='row-fluid'>
<p class="right controls pull-right">
{{if filetype=='python':}}
{{=A(SPAN(T('toggle breakpoint')),
_value="breakpoint", _name="breakpoint",
_onclick="return doToggleBreakpoint('%s','%s://%s%s');" % (filename,
request.env['wsgi_url_scheme'], request.env['http_host'],
URL(c='debug', f='toggle_breakpoint')),
_class="button special")}}
_class="button special btn btn-inverse")}}
{{pass}}
{{=button(URL('design',args=request.vars.app if request.vars.app else request.args[0], anchor=request.vars.id), T('back'))}}
{{if edit_controller:}}
@@ -116,20 +116,31 @@ jQuery(document).ready(function(){
{{=button(view_link, T('try view'))}}
{{pass}}
{{if request.args[1]=='models':}}
<a class="button" href="http://www.web2py.com/sqldesigner" target="_blank"><span>{{=T('online designer')}}</span></a>
<a class="button btn" href="http://www.web2py.com/sqldesigner" target="_blank"><span>{{=T('online designer')}}</span></a>
{{pass}}
<a class="button" href="http://www.web2py.com/examples/static/epydoc/index.html" target="_blank"><span>{{=T('docs')}}</span></a>
<a class="button btn" href="http://www.web2py.com/examples/static/epydoc/index.html" target="_blank"><span>{{=T('docs')}}</span></a>
</p>
</div>
<div id="editor_area">
<form action="{{=URL('edit',args=filename)}}" method="post" name="editform" id="editform">
<a value="save" name="save" onclick="return doClickSave();" class="icon saveicon">
{{=IMG(_src=URL('static', 'images/save_icon.png'), _alt=T('Save'))}}
</a>
{{=T('Saved file hash:')}}
<input type="input" name="file_hash" value="{{=file_hash}}" readonly="readonly"/>
{{=T('Last saved on:')}} <input type="input" name="saved_on" value="{{=saved_on}}" readonly="readonly"/>
<br><hr>
<div class="editor-bar-column">
<label>{{=T('Save file:')}}</label>
<a value="save" name="save" onclick="return doClickSave();" class="icon saveicon btn btn-mini" style="background-image: -webkit-linear-gradient(top,white,#E6E6E6);">
{{=IMG(_src=URL('static', 'images/save_icon.png'), _alt=T('Save'))}}
</a>
</div>
<div class="editor-bar-column">
<div class="row-fluid">
<div class="span7">
<label>{{=T('Saved file hash:')}}</label>
<input type="input" name="file_hash" value="{{=file_hash}}" class="input-long uneditable-input" readonly="readonly"/>
</div>
<div class="span5">
<label>{{=T('Last saved on:')}}</label>
<input type="input" name="saved_on" value="{{=saved_on}}" class="input-normal uneditable-input" readonly="readonly"/>
</div>
</div>
</div>
{{if TEXT_EDITOR == 'amy':}}
<textarea style="width: auto; height:400px;direction:ltr;" rows="58" cols="100" -amy-enabled="true" id="body" name="data">{{=data}}</textarea>
<script>window.eamy = eamy;</script>
@@ -227,52 +238,59 @@ window.onload = function() {
<textarea cols="80" rows="25" id="body" style="direction:ltr;" name="data">{{=data}}</textarea>
<script>window.textarea = area.textarea;</script>
{{pass}}
<button class="editbutton" onclick="window.location.reload(); return false">{{=T('restore')}}</button> {{=T('currently saved or')}} <button class="editbutton" type="submit" name="revert">{{=T('revert')}}</button>
{{=T('to previous version.')}}
<div class="editor-bar-bottom" style="margin-top:9px;">
<button class="editbutton btn" onclick="window.location.reload(); return false">{{=T('restore')}}</button>
{{=T('currently saved or')}}
<button class="editbutton btn" type="submit" name="revert">{{=T('revert')}}</button>
{{=T('to previous version.')}}
</div>
<br/>
</form>
</div>
<div class="help">
{{if TEXT_EDITOR=='edit_area' and filetype=='html':}}
<h3>{{=T('Key bindings for ZenCoding Plugin')}}</h3>
<ul>
{{=shortcut('Ctrl+S', T('Save via Ajax'))}}
{{=shortcut('Ctrl+,', T('Expand Abbreviation'))}}
{{=shortcut('Ctrl+M', T('Match Pair'))}}
{{=shortcut('Ctrl+H', T('Wrap with Abbreviation'))}}
{{=shortcut('Shift+Ctrl+M', T('Merge Lines'))}}
{{=shortcut('Ctrl+Shift+←', T('Previous Edit Point'))}}
{{=shortcut('Ctrl+Shift+', T('Next Edit Point'))}}
{{=shortcut('Ctrl+Shift+', T('Go to Matching Pair'))}}
</ul>
{{elif TEXT_EDITOR == 'codemirror' and filetype=='html':}}
<h3>{{=T('Key bindings for ZenCoding Plugin')}}</h3>
<ul>
{{=shortcut('Ctrl+S', T('Save via Ajax'))}}
{{=shortcut('Ctrl+F11', T('Toggle Fullscreen'))}}
{{=shortcut('Ctrl-F / Cmd-F', T('Start searching'))}}
{{=shortcut('Ctrl-G / Cmd-G', T('Find Next'))}}
{{=shortcut('Shift-Ctrl-G / Shift-Cmd-G', T('Find Previous'))}}
{{=shortcut('Shift-Ctrl-F / Cmd-Option-F', T('Replace'))}}
{{=shortcut('Shift-Ctrl-R / Shift-Cmd-Option-F', T('Replace All'))}}
{{=shortcut('Tab', T('Expand Abbreviation'))}}
</ul>
{{elif TEXT_EDITOR == 'codemirror':}}
<h3>{{=T("Key bindings")}}</h3>
<ul>
{{=shortcut('Ctrl+S', T('Save via Ajax'))}}
{{=shortcut('Ctrl+F11', T('Toggle Fullscreen'))}}
{{=shortcut('Ctrl-F / Cmd-F', T('Start searching'))}}
{{=shortcut('Ctrl-G / Cmd-G', T('Find Next'))}}
{{=shortcut('Shift-Ctrl-G / Shift-Cmd-G', T('Find Previous'))}}
{{=shortcut('Shift-Ctrl-F / Cmd-Option-F', T('Replace'))}}
{{=shortcut('Shift-Ctrl-R / Shift-Cmd-Option-F', T('Replace All'))}}
</ul>
{{else:}}
<h3>{{=T("Key bindings")}}</h3>
<ul>
{{=shortcut('Ctrl+S', T('Save via Ajax'))}}
</ul>
{{pass}}
<div class="row-fluid">
<div class="help span4 alert alert-block alert-info">
{{if TEXT_EDITOR=='edit_area' and filetype=='html':}}
<h3>{{=T('Key bindings for ZenCoding Plugin')}}</h3>
<ul class="keybindings unstyled">
{{=shortcut('Ctrl+S', T('Save via Ajax'))}}
{{=shortcut('Ctrl+,', T('Expand Abbreviation'))}}
{{=shortcut('Ctrl+M', T('Match Pair'))}}
{{=shortcut('Ctrl+H', T('Wrap with Abbreviation'))}}
{{=shortcut('Shift+Ctrl+M', T('Merge Lines'))}}
{{=shortcut('Ctrl+Shift+', T('Previous Edit Point'))}}
{{=shortcut('Ctrl+Shift+', T('Next Edit Point'))}}
{{=shortcut('Ctrl+Shift+↑', T('Go to Matching Pair'))}}
</ul>
{{elif TEXT_EDITOR == 'codemirror' and filetype=='html':}}
<h3>{{=T('Key bindings for ZenCoding Plugin')}}</h3>
<ul class="keybindings unstyled">
{{=shortcut('Ctrl+S', T('Save via Ajax'))}}
{{=shortcut('Ctrl+F11', T('Toggle Fullscreen'))}}
{{=shortcut('Ctrl-F / Cmd-F', T('Start searching'))}}
{{=shortcut('Ctrl-G / Cmd-G', T('Find Next'))}}
{{=shortcut('Shift-Ctrl-G / Shift-Cmd-G', T('Find Previous'))}}
{{=shortcut('Shift-Ctrl-F / Cmd-Option-F', T('Replace'))}}
{{=shortcut('Shift-Ctrl-R / Shift-Cmd-Option-F', T('Replace All'))}}
{{=shortcut('Tab', T('Expand Abbreviation'))}}
</ul>
{{elif TEXT_EDITOR == 'codemirror':}}
<h3>{{=T("Key bindings")}}</h3>
<ul class="keybindings unstyled">
{{=shortcut('Ctrl+S', T('Save via Ajax'))}}
{{=shortcut('Ctrl+F11', T('Toggle Fullscreen'))}}
{{=shortcut('Ctrl-F / Cmd-F', T('Start searching'))}}
{{=shortcut('Ctrl-G / Cmd-G', T('Find Next'))}}
{{=shortcut('Shift-Ctrl-G / Shift-Cmd-G', T('Find Previous'))}}
{{=shortcut('Shift-Ctrl-F / Cmd-Option-F', T('Replace'))}}
{{=shortcut('Shift-Ctrl-R / Shift-Cmd-Option-F', T('Replace All'))}}
</ul>
{{else:}}
<h3>{{=T("Key bindings")}}</h3>
<ul class="keybindings unstyled">
{{=shortcut('Ctrl+S', T('Save via Ajax'))}}
</ul>
{{pass}}
</div>
</div>
<!-- end "edit" block -->
@@ -7,18 +7,19 @@ function delkey(id) {
return false;
}
function hideShowTranslated(){
jQuery(".translated").closest("p").toggle();
jQuery(".translated").closest("div.row-fluid").toggle();
}
</script>
{{block sectionclass}}edit_language{{end}}
<!-- begin "edit_language" block -->
<h2>{{=T('Editing Language file')}} "{{=filename}}"</h2>
<a class="button" href="#" onclick="hideShowTranslated(this);">
<div class="controls">
<a class="button btn" href="#" onclick="hideShowTranslated(this);">
<span>{{=T('Hide/Show Translated strings')}}</span>
</a>
</div>
<div class="languageform">
{{=form}}
</div>
<!-- end "edit_language" block -->
@@ -6,11 +6,10 @@ function delkey(id) {
return false;
}
</script>
{{block sectionclass}}edit_language{{end}}
<!-- begin "edit_language(plurals)" block -->
<h2>{{=T("Editing Plural Forms File")}} "{{=filename}}"</h2>
<div class="pluralsform">
{{=form}}
</div>
<!-- end "edit_language(plurals)" block -->
+115 -133
View File
@@ -1,142 +1,124 @@
{{extend 'layout.html'}}
{{import os, stat, time}}
{{block sectionclass}}errors{{end}}
<style>
table.sortable {
border-spacing:0px;
}
table.sortable td, table.sortable th {
padding: 2px 5px 2px 5px;
}
table.sortable thead {
background-color:#eee;
color:#666666;
font-weight: bold;
cursor: default;
}
tr.error_ticket:hover {
background-color: #eee;
}
.controls a.button.unavailable {
color: #ff0000;
}
</style>
<script language="JavaScript">
function check(){
for (var i = 0; i < document.myform.elements.length; i++) {
var e = document.myform.elements[i];
if (e.type == 'checkbox') e.checked = true;
}
}
function uncheck(){
for (var i = 0; i < document.myform.elements.length; i++) {
var e = document.myform.elements[i];
if (e.type == 'checkbox') e.checked = false;
}
}
jQuery(document).ready(function() { jQuery('.traceback').hide(); });
</script>
<!-- begin "errors" block -->
{{if db_ready['status'] == False:
switchbutton = A(SPAN("switch to : db"), _href=db_ready['errlink'], _class="button unavailable", _title="%s" % (db_ready['errmessage']))
switchbutton = A(SPAN("switch to : db"), _href=db_ready['errlink'], _class="button unavailable btn btn-danger", _title="%s" % (db_ready['errmessage']))
else:
switchbutton = A(SPAN("switch to : db"), _href=URL(args=[app, 'dbnew']), _class="button")
switchbutton = A(SPAN("switch to : db"), _href=URL(args=[app, 'dbnew']), _class="button btn")
pass}}
<h2>{{=T('Error logs for "%(app)s"',dict(app=app))}}</h2>
<div class="errorform">
<form name="myform" method="post">
<input name="CheckAll" value="{{=T('check all')}}"
onclick="check()" type="button">
<input name="CheckAll" value="{{=T('uncheck all')}}"
onclick="uncheck()" type="button">
<input value="{{=T('delete all checked')}}" type="submit"><br><br>
{{ if 'new' in method: }}
{{base_url = 'db' in method and 'ticketdb' or 'ticket' }}
<h3>{{=T('Click row to expand traceback')}}</h3>
<p class="controls">
{{if 'db' in method:}}
source : db
<a class="button" href="{{=URL(args=[app, 'new'])}}"><span>switch to : filesystem</span></a>
<a class="button" href="{{=URL(args=[app, 'dbold'])}}"><span>lists by ticket</span></a>
{{else:}}
source : filesystem
{{=switchbutton}}
<a class="button" href="{{=URL(args=[app, 'old'])}}"><span>lists by ticket</span></a>
{{pass}}
</p>
<table id="trck_errors" class="sortable">
<thead>
<tr>
<th>{{=T("Delete")}}</th>
<th>{{=T("Count")}}</th>
<th>{{=T("File")}}</th>
<th>{{=T("Error")}}</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{{for e in errors:}}
<tr class="error_ticket">
<td><input type="checkbox" name="delete_{{=e['hash']}}" /></td>
<td>{{=e['count']}}</td>
<td>{{=e['causer']}}</td>
<td>{{=A(e['last_line'],_href="#",_onclick="collapse('%s');"%e['hash'])}}</td>
<td>+</td>
<td>{{=A(T('details'),_href=URL(base_url,args=[app,e['ticket']]))}}</td>
</tr>
<tr id="{{=e['hash']}}" class="traceback">
<td colspan="6">
<div>
{{=CODE(e['pickel']['traceback'])}}
</div>
</td>
</tr>
{{pass}}
</tbody>
</table>
{{ else: }}
<h3>{{=T('Click row to view a ticket')}}</h3>
<p class="controls">
{{if 'db' in method:}}
source : db
<a class="button" href="{{=URL(args=[app, 'old'])}}"><span>switch to : filesystem</span></a>
<a class="button" href="{{=URL(args=[app, 'dbnew'])}}"><span>lists by exception</span></a>
{{else:}}
source : filesystem
{{=switchbutton}}
<a class="button" href="{{=URL(args=[app, 'new'])}}"><span>lists by exception</span></a>
{{pass}}
</p>
<table class="sortable">
<thead>
<tr>
<th>{{=T("Delete")}}</th>
<th>{{=T("Ticket")}}</th>
<th>{{=T("Date and Time")}}</th>
</tr>
</thead>
<tbody>
{{for ticket in tickets:}}
<tr>
<td><input type="checkbox" name="delete_{{=ticket}}"/></td>
{{if 'db' in method:}}
<td><a href="{{=URL('ticketdb',args=[app,ticket])}}">{{=ticket}}</a></td>
<td>{{=time.strftime('%Y-%m-%d %H:%M:%S',times[ticket].timetuple())}}</td>
{{else:}}
<td><a href="{{=URL('ticket',args=[app,ticket])}}">{{=ticket}}</a></td>
<td>{{=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(os.stat(os.path.join(request.folder,'../%s/errors/%s' % (app,ticket)))[stat.ST_CTIME]))}}</td>
{{pass}}
</tr>
{{pass}}
</tbody>
</table>
{{ pass }}
</form>
<form name="myform" method="post">
{{ if 'new' in method: }}
{{base_url = 'db' in method and 'ticketdb' or 'ticket' }}
<p class="controls row-fluid">
<div class="controls controls-row">
{{if 'db' in method:}}
<span class="uneditable-input">source : db</span>
<a class="button btn" href="{{=URL(args=[app, 'new'])}}"><span>switch to : filesystem</span></a>
<a class="button btn" href="{{=URL(args=[app, 'dbold'])}}"><span>lists by ticket</span></a>
{{else:}}
<span class="uneditable-input">source : filesystem</span>
{{=switchbutton}}
<a class="button btn" href="{{=URL(args=[app, 'old'])}}"><span>lists by ticket</span></a>
{{pass}}
</div>
</p>
<div class="tablebar">
<input value="{{=T('delete all checked')}}" type="submit" class="btn"/>
<span class="help label label-info">{{=T('Click row to expand traceback')}}</span>
</div>
<div class="row-fluid">
<div class="span6">
<table id="trck_errors" class="sortable table table-hover table-condensed">
<thead>
<tr>
<th class="column1 cbcentered"><input type="checkbox" name="delete_all}" /></th>
<th class="column2">{{=T("Count")}}</th>
<th class="column3">{{=T("File")}}</th>
<th>{{=T("Error")}}</th>
<th class="columnN"></th>
</tr>
</thead>
<tbody>
{{for e in errors:}}
<tr class="error_ticket">
<td class="cbcentered"><input type="checkbox" name="delete_{{=e['hash']}}" /></td>
<td>{{=e['count']}}</td>
<td>{{=e['causer']}}</td>
<td>{{=A(e['last_line'],_href="#",_onclick="collapse('%s');return false;"%e['hash'])}}</td>
<td>+&nbsp;{{=A(T('details'),_href=URL(base_url,args=[app,e['ticket']]))}}</td>
</tr>
<tr id="{{=e['hash']}}" class="traceback">
<td colspan="5">
<div class="ticket_code">
{{=CODE(e['pickel']['traceback'])}}
</div>
</td>
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
{{ else: }}
<p class="controls row-fluid">
<div class="controls controls-row">
{{if 'db' in method:}}
<span class="uneditable-input">source : db</span>
<a class="button btn" href="{{=URL(args=[app, 'old'])}}"><span>switch to : filesystem</span></a>
<a class="button btn" href="{{=URL(args=[app, 'dbnew'])}}"><span>lists by exception</span></a>
{{else:}}
<span class="uneditable-input">source : filesystem</span>
{{=switchbutton}}
<a class="button btn" href="{{=URL(args=[app, 'new'])}}"><span>lists by exception</span></a>
{{pass}}
</div>
</p>
<div class="tablebar">
<input value="{{=T('delete all checked')}}" type="submit" class="btn"/>
<span class="help label label-info">{{=T('Click row to expand traceback')}}</span>
</div>
<div class="row-fluid">
<div class="span6">
<table id="trck_errors" class="sortable table table-hover table-condensed">
<thead>
<tr>
<th class="column1 cbcentered"><input type="checkbox" name="delete_all}" /></th>
<th>{{=T("Ticket")}}</th>
<th class="columnN1">{{=T("Date and Time")}}</th>
</tr>
</thead>
<tbody>
{{for ticket in tickets:}}
<tr>
<td class="cbcentered"><input type="checkbox" name="delete_{{=ticket}}"/></td>
{{if 'db' in method:}}
<td><a href="{{=URL('ticketdb',args=[app,ticket])}}">{{=ticket}}</a></td>
<td>{{=time.strftime('%Y-%m-%d %H:%M:%S',times[ticket].timetuple())}}</td>
{{else:}}
<td><a href="{{=URL('ticket',args=[app,ticket])}}">{{=ticket}}</a></td>
<td>{{=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(os.stat(os.path.join(request.folder,'../%s/errors/%s' % (app,ticket)))[stat.ST_CTIME]))}}</td>
{{pass}}
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
{{ pass }}
</form><!-- /errorform -->
</div>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('.traceback').hide();
jQuery("#trck_errors thead tr th:first input[type=checkbox]").click(function() {
var checkedStatus = this.checked;
jQuery("#trck_errors tbody tr td:first-child input[type=checkbox]").each(function() {
this.checked = checkedStatus;
});
});
});
</script>
<!-- end "errors" block -->
+11 -1
View File
@@ -1,5 +1,15 @@
{{extend 'layout.html'}}
{{
dlg = dialog
smt_button = dlg.element(_type="submit")
smt_button['_class'] = 'btn'
smt_button['_style'] = 'margin-right:4px;'
ccl_button = dlg.element(_type="button")
ccl_button['_class'] = 'btn'
}}
<!-- begin "git_pull" block -->
<div class="center">
<h2>{{=T('This will pull changes from the remote repo for application "%s"?', app)}}</h2>
{{=dialog}}
</div>
<!-- end "git_pull" block -->
+10 -1
View File
@@ -1,6 +1,15 @@
{{extend 'layout.html'}}
{{
frm = form
smt_button = frm.element(_type="submit")
smt_button['_class'] = 'btn'
smt_button['_style'] = 'margin-right:4px;'
ccl_button = frm.element(_type="button")
ccl_button['_class'] = 'btn'
}}
<!-- begin "git_push" block -->
<h2>{{=T('This will push changes to the remote repo for application "%s".', app)}}</h2>
<center>
{{=form}}
</center>
<!-- end "git_push" block -->
+16 -19
View File
@@ -1,26 +1,23 @@
{{extend 'layout.html'}}
<script type="text/javascript">
jQuery(function() {
jQuery("#password").focus();
});
</script>
{{block sectionclass}}login{{end}}
<!-- begin "index" block -->
<h2>web2py&trade; {{=T('Web Framework')}}</h2>
<h3>{{=T('Login to the Administrative Interface')}}</h3>
<div class="form row-fluid">
{{if request.is_https or request.is_local:}}
<div class="form">
<form action="{{=URL(r=request)}}" method="post">
<div><input type="hidden" name="send" value="{{=send}}"/></div>
<table>
<tr><td>{{=T('Administrator Password:')}}</td><td><input type="password" name="password" id="password"/></td></tr>
<tr><td></td><td><input type="submit" name="login" value="{{=T('Login')}}"/></td></tr>
</table>
</form>
</div>
<form action="{{=URL(r=request)}}" method="post" class="span4 well">
<label for="password">{{=T('Administrator Password:')}}</label>
<input type="password" name="password" id="password"/>
<input type="hidden" name="send" value="{{=send}}"/>
<div class="controls"><button type="submit" name="login" class="btn">{{=T('Login')}}</button></div>
</form>
{{else:}}
<p class="help">{{=T('ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.')}}</p>
<p class="help span7 alert alert-block alert-warning">{{=T('ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.')}}</p>
{{pass}}
</div>
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#password").focus();
});
</script>
<!-- end "index" block -->
@@ -1,5 +1,163 @@
{{extend 'layout.html'}}
{{
#grid['_class'] = 'web2py_grid'
if not request.args:
add_btn = grid.elements('div.web2py_console a.w2p_trap',replace=None)[0]
add_btn['_id'] = 'w2p_grid_addbtn'
add_btn['_class'] = 'w2p_trap btn'
qry_pnl_rows = grid.elements('div',_class="w2p_query_row hidden")
for qry_pnl_row in qry_pnl_rows:
qry_pnl_btn1 = qry_pnl_row.elements('input',_value="New",replace=None)[0]
qry_pnl_btn2 = qry_pnl_row.elements('input',_value="And",replace=None)[0]
qry_pnl_btn3 = qry_pnl_row.elements('input',_value="Or",replace=None)[0]
qry_pnl_btngrp = qry_pnl_row.elements('input',_value="Close",replace=lambda me:DIV(qry_pnl_btn1,qry_pnl_btn2,qry_pnl_btn3,me,_class="qry_pnl_btns"))
pass
qry_pnl = grid.elements('div#w2p_query_panel',replace=None)
csl_frm = grid.elements('div.web2py_console form')[0]
csl_frm['_class'] = 'form-inline'
csl_frm_search = grid.elements('#web2py_keywords',replace=lambda me:DIV(me,TAG['button'](T('Search'),_class='btn',_type='submit'),TAG['button'](T('Clear'),_class='btn',_type='button',_onclick='jQuery("#web2py_keywords").val("");'),_class="input-append"))
csl_frm_search_btn1 = grid.elements('input',_value="Search",replace=None)
csl_frm_search_btn2 = grid.elements('input',_value="Clear",replace=None)
new_console = grid.elements('div.web2py_console form',replace=lambda frm_csl:DIV(SPAN(add_btn,_class='span1'),SPAN(DIV(frm_csl,qry_pnl[0],_id='w2p_search-form'),_class='span5'),_class='row-fluid'))
w2p_grid_tbl = grid.element('table')
if w2p_grid_tbl:
w2p_grid_tbl['_class'] = 'table table-condensed table-hover table-bordered'
tbl_button_rows = grid.elements('td',_class="row_buttons")
for tbl_button_row in tbl_button_rows:
buttons = tbl_button_row.elements('a.w2p_trap')
for button in buttons:
button['_class'] = 'w2p_trap btn'
pass
pass
export_menu = grid.element('div.w2p_export_menu')
export_menu_links = export_menu.elements('a')
export_menu_items = []
for link in export_menu_links:
item = LI(link)
export_menu_items.append(item)
pass
new_export_menu = DIV(A(T('Exports:'),SPAN(_class='caret'),_href='#',_class='btn dropdown-toggle',**{'_data-toggle':"dropdown"}),UL(*export_menu_items,_class='dropdown-menu'),_class='w2p_export_menu btn-group pull-left')
grid_pagination = grid.element('div.web2py_paginator')
if grid_pagination:
export_menu = grid.element('div.w2p_export_menu',replace=None)
new_grid_pagination = grid.element('div.web2py_paginator',replace=lambda me:DIV(new_export_menu,me,_class='w2p_grid_bottom_bar'))
grid_pagination['_class'] = 'web2py_paginator pagination pagination-right'
grid_page_active = grid.element('li.current')
grid_page_active['_class'] = 'current active'
else:
new_grid_pagination = grid.element('div.w2p_export_menu',replace=DIV(new_export_menu))
pass
records_counter = grid.element('div.web2py_counter')
records_found = int(records_counter[0].partition('records')[0].strip())
paginate = 5 # TODO: get it from the controller
pages = records_found/paginate
tot_pages = pages if records_found%paginate == 0 else pages+1
current_page = int(request.vars.page) if request.vars.page else 1
end_record = paginate*current_page if current_page < tot_pages else records_found
begin_record = 1 if current_page == 1 else (paginate*(current_page-1))+1
rec = "records" if records_found>1 else "record"
record_shown_in_the_page = T("Showing %s to %s of %s %s found")%(begin_record,end_record,records_found,rec)
new_record_counter = grid.element('div.web2py_counter',replace=DIV(record_shown_in_the_page,_class="web2py_counter span6 pull-right"))
pass
elif request.args(0)=='new':
bck_btn = grid.element('div.web2py_grid span.leftarrow').parent
bck_btn['_id'] = 'w2p_grid_bckbtn'
bck_btn['_class'] = 'w2p_trap btn'
frm = grid.element('div.web2py_grid form')
frm['_class'] = 'web2py_form span4 well well-small'
checkbox_lbl = frm.element('label',_for='auth_user_is_manager')
checkbox_inp = frm.element(_name='is_manager',replace=CAT())
checkbox_lbl[0] = checkbox_inp
checkbox_lbl[1] = 'Is Manager'
checkbox_lbl['_class'] = "checkbox"
inp_smt = frm.element('input',_type='submit',replace=TAG['button'](T('Submit'),_type='submit',_class='btn'))
new_form_flds = []
frm_trs = frm.elements('tr')
for tr in frm_trs:
label = tr[0][0]
input = tr[1][0]
help = tr[2][0]
new_form_flds.append(label)
new_form_flds.append(input)
new_form_flds.append(help)
pass
new_frm_content = frm.element('table',replace=CAT(*new_form_flds))
new_frm = grid.element('div.web2py_grid form',replace=lambda me:DIV(me,_class='row-fluid'))
elif request.args(0)=='view':
bck_btn = grid.element('div.web2py_grid span.leftarrow').parent
bck_btn['_id'] = 'w2p_grid_bckbtn'
bck_btn['_class'] = 'w2p_trap btn'
pen_btn = grid.element('div.web2py_grid span.pen').parent
pen_btn['_id'] = 'w2p_grid_penbtn'
pen_btn['_class'] = 'w2p_trap btn'
frm = grid.element('div.web2py_grid form')
frm['_class'] = 'web2py_form span4 well well-small'
checkbox_lbl = frm.element('label',_for='auth_user_is_manager')
checkbox_inp = frm.element(_name='is_manager',replace=CAT())
checkbox_lbl[0] = checkbox_inp
checkbox_lbl[1] = 'Is Manager'
checkbox_lbl['_class'] = "checkbox"
new_form_flds = []
frm_trs = frm.elements('tr')
for tr in frm_trs:
label = tr[0][0]
input = tr[1][0]
help = tr[2][0]
new_form_flds.append(label)
if len(input) > 0 :
new_form_flds.append(SPAN(input,_class='uneditable-input'))
pass
new_form_flds.append(help)
pass
new_frm_content = frm.element('table',replace=CAT(*new_form_flds))
new_frm = grid.element('div.web2py_grid form',replace=lambda me:DIV(me,_class='row-fluid'))
elif request.args(0)=='edit':
bck_btn = grid.element('div.web2py_grid span.leftarrow').parent
bck_btn['_id'] = 'w2p_grid_bckbtn'
bck_btn['_class'] = 'w2p_trap btn'
viw_btn = grid.element('div.web2py_grid span.magnifier').parent
viw_btn['_id'] = 'w2p_grid_viwbtn'
viw_btn['_class'] = 'w2p_trap btn'
frm = grid.element('div.web2py_grid form')
frm['_class'] = 'web2py_form span4 well well-small'
checkbox_lbl = frm.element('label',_for='auth_user_is_manager')
checkbox_inp = frm.element(_name='is_manager',replace=CAT())
checkbox_lbl[0] = checkbox_inp
checkbox_lbl[1] = 'Is Manager'
checkbox_lbl['_class'] = "checkbox"
checkbox1_lbl = frm.element('label',_for='delete_record')
checkbox1_inp = frm.element(_id='delete_record',replace=CAT())
checkbox1_lbl[0] = checkbox1_inp
checkbox1_lbl[1] = T('Check to delete')
checkbox1_lbl['_class'] = "checkbox"
inp_smt = frm.element('input',_type='submit',replace=TAG['button'](T('Submit'),_type='submit',_class='btn'))
id_input = frm.element(_id='auth_user_id')
id_input['_class'] = 'uneditable-input'
new_form_flds = []
frm_trs = frm.elements('tr')
for tr in frm_trs:
label = tr[0][0]
input = tr[1][0]
help = tr[2][0]
new_form_flds.append(label)
print label
new_form_flds.append(input)
new_form_flds.append(help)
pass
new_frm_content = frm.element('table',replace=CAT(*new_form_flds))
new_frm = grid.element('div.web2py_grid form',replace=lambda me:DIV(me,_class='row-fluid'))
pass
}}
<h1>{{=T('Manage Admin Users/Students')}}</h1>
{{=grid}}
<h2>{{=T('Manage Admin Users/Students')}}</h2>
{{=grid}}
+4 -5
View File
@@ -1,17 +1,16 @@
{{extend 'layout.html'}}
{{block sectionclass}}peek{{end}}
<!-- begin "peek" block -->
<h2>{{=T("Peeking at file")}} "{{=filename}}"</h2>
<p class="controls">
{{=button(URL('design',args=request.vars.app if request.vars.app else request.args[0], anchor=request.vars.id), T('back'))}}
{{=button(URL('edit',args=request.args, vars=request.vars), T('Edit'))}}
</p>
<div class="code-wrapper">
{{
if filename[-3:]=='.py': language='python'
else: language='html'
}}
{{=CODE(data,language=language,link='/examples/global/vars/')}}
</div>
<!-- end "peek" block -->
+157 -153
View File
@@ -6,9 +6,15 @@ def all(items):
def peekfile(path,file):
return A(file.replace('\\\\','/'),_href=URL('peek', args=(app, path, file)))
def editfile(path,file):
return A(SPAN(T('Edit')),_class='button editbutton',_href=URL('edit', args=(app, path, file)))
return A(SPAN(T('Edit')),_class='button editbutton btn',_href=URL('edit', args=(app, path, file)))
def testfile(path,file):
return A(TAG[''](IMG(_src=URL('static', 'images/test_icon.png'), _alt=T('test')), SPAN(T("Run tests in this file"))), _class='icon test tooltip',_href=URL('test', args=(app, file)))
return A(TAG[''](IMG(_src=URL('static', 'images/test_icon.png'), _alt=T('test')),
SPAN(T("Run tests in this file"))),
_class='icon test',
_href=URL('test', args=(app, file)),
_rel="tooltip",
**{'_data-placement':'right',
'_data-original-title':T("Run tests in this file")})
def editlanguagefile(path,file):
return A(SPAN(T('Edit')),_class='button editbutton',_href=URL('edit_language', args=(app, path, file)))
def file_upload_form(location):
@@ -29,57 +35,62 @@ def file_create_form(location):
INPUT(_type="submit",_value=T("submit")),_action=URL('create_file'))
return form
def deletefile(arglist):
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')), SPAN(T('Delete this file (you will be asked to confirm deletion)'))), _class='icon delete tooltip', _href=URL('delete',args=arglist,vars=dict(sender=request.function+'/'+app+'/'+request.args[1])))
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')),
SPAN(T('Delete this file (you will be asked to confirm deletion)'))),
_href=URL('delete',args=arglist,vars=dict(sender=request.function+'/'+app+'/'+request.args[1])),
_class='icon delete',
_rel="tooltip",
**{'_data-placement':'right',
'_data-original-title':T('Delete this file (you will be asked to confirm deletion)')})
}}
{{block sectionclass}}plugin{{end}}
<!-- begin "plugin" block -->
<h2>{{=T('Plugin "%s" in application', request.args(1))}} "{{=app}}"</h2>
<h2>
{{=T('Plugin "%s" in application', request.args(1))}} "{{=app}}"
</h2>
<!-- COLLAPSE/JUMP-TO BUTTONS -->
<div class="right-full controls">
<a class="button special" href="#" onclick="jQuery('h3').click();return false"><span>{{=T("collapse/expand all")}}</span></a>
<span class="buttongroup">
{{=button("#models", T("models"))}}
{{=button("#controllers", T("controllers"))}}
{{=button("#views", T("views"))}}
{{=button("#static", T("static"))}}
{{=button("#modules", T("modules"))}}
</span>
<span class="buttongroup">
{{=sp_button(URL('design',args=request.args, anchor=request.vars.id), T("back"))}}
{{=sp_button(URL('delete_plugin',args=request.args, vars=request.vars), T("delete plugin"))}}
{{=sp_button(URL('pack_plugin',args=request.args), T("pack plugin"))}}
</span>
<p class="buttons-row">
<a class="button special btn btn-inverse" href="#" onclick="jQuery('h3>span').click();return false"><span>{{=T("collapse/expand all")}}</span></a>
<span class="buttongroup">
{{=button('#models', T("models"))}}
{{=button('#controllers', T("controllers"))}}
{{=button('#views', T("views"))}}
{{=button('#static', T("static"))}}
{{=button('#modules', T("modules"))}}
</span>
<span class="buttongroup">
{{=sp_button(URL('design',args=request.args, anchor=request.vars.id), T("back"))}}
{{=sp_button(URL('delete_plugin',args=request.args, vars=request.vars), T("delete plugin"))}}
{{=sp_button(URL('pack_plugin',args=request.args), T("pack plugin"))}}
</span>
</p>
</div>
<!-- MODELS -->
<h3 id="models" onclick="collapse('models_inner');" class="component">
{{=T("Models")}}
<h3 id="_models" rel="pagebookmark">
<span class="component" onclick="collapse('models_inner');">{{=T("Models")}}</span>
<span id="models" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="models_inner" class="component_contents">
{{if not models:}}
<p><strong>{{=T("There are no models")}}</strong></p>
{{pass}}
<div class="controls comptools">
</div>
<ul>
{{for m in models:}}
<li>
<span class="filetools controls">
{{=editfile('models',m)}}
{{=deletefile([app, 'models', m])}}
</span>
<span class="file">
{{=peekfile('models',m)}}
</span>
<span class="extras">
{{if len(defines[m]):}}{{=T("defines tables")}} {{pass}}{{=XML(', '.join([B(table).xml() for table in defines[m]]))}}
</span>
</li>
{{pass}}
</ul>
{{if not models:}}<p><strong>{{=T("There are no models")}}</strong></p>{{else:}}
<ul class="unstyled act-edit">
{{for m in models:}}
<li>
<span class="filetools controls">
{{=editfile('models',m)}}
{{=deletefile([app, 'models', m])}}
</span>
<span class="file">
{{=peekfile('models',m)}}
</span>
<span class="extras">
{{if len(defines[m]):}}{{=T("defines tables")}} {{pass}}{{=XML(', '.join([B(table).xml() for table in defines[m]]))}}
</span>
</li>
{{pass}}
</ul>
{{pass}}
</div>
<!-- FIND CONTROLLER FUNCTIONS -->
@@ -89,131 +100,124 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
}}
<!-- CONTROLLERS -->
<h3 id="controllers" onclick="collapse('controllers_inner');" class="component">
{{=T("Controllers")}}
<h3 id="_controllers" rel="pagebookmark">
<span class="component" onclick="collapse('controllers_inner');">{{=T("Controllers")}}</span>
<span id="controllers" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="controllers_inner" class="component_contents">
{{if not controllers:}}
<p><strong>{{=T("There are no controllers")}}</strong></p>
{{pass}}
<div class="controls comptools">
</div>
<ul>
{{for c in controllers:}}
<li>
<span class="filetools controls">
{{=editfile('controllers',c)}}
{{=deletefile([app,'controllers',c])}}
{{=testfile('controllers',c)}}
</span>
<span class="file">
{{=peekfile('controllers',c)}}
</span>
<span class="extras">
{{if functions[c]:}}{{=T("exposes")}} {{pass}}{{=XML(', '.join([A(f,_href=URL(a=app,c=c[:-3],f=f)).xml() for f in functions[c]]))}}
</span>
</li>
{{pass}}
</ul>
{{if not controllers:}}<p><strong>{{=T("There are no controllers")}}</strong></p>{{else:}}
<ul class="unstyled act_edit">
{{for c in controllers:}}
<li>
<span class="filetools controls">
{{=editfile('controllers',c)}}
{{=deletefile([app,'controllers',c])}}
{{=testfile('controllers',c)}}
</span>
<span class="file">
{{=peekfile('controllers',c)}}
</span>
<span class="extras celled">
{{if functions[c]:}}{{=T("exposes")}} {{pass}}{{=XML(', '.join([A(f,_href=URL(a=app,c=c[:-3],f=f)).xml() for f in functions[c]]))}}
</span>
</li>
{{pass}}
</ul>
{{pass}}
</div>
<!-- VIEWS -->
<h3 id="views" onclick="collapse('views_inner');" class="component">
{{=T("Views")}}
<h3 id="_views" rel="pagebookmark">
<span class="component" onclick="collapse('views_inner');">{{=T("Views")}}</span>
<span id="views" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="views_inner" class="component_contents">
{{if not views:}}
<p><strong>{{=T("There are no views")}}</strong></p>
{{pass}}
<div class="controls comptools">
</div>
<ul>
{{for c in views:}}
<li>
<span class="filetools controls">
{{=editfile('views',c)}}
{{=deletefile([app,'views',c])}}
</span>
<span class="file">
{{=peekfile('views',c)}}
</span>
<span class="extras">
{{if extend.has_key(c):}}{{=T("extends")}} <b>{{=extend[c]}}</b> {{pass}}
{{if include[c]:}}{{=T("includes")}} {{pass}}{{=XML(', '.join([B(f).xml() for f in include[c]]))}}
</span>
</li>
{{pass}}
</ul>
{{if not views:}}<p><strong>{{=T("There are no views")}}</strong></p>{{else:}}
<ul class="unstyled act_edit">
{{for c in views:}}
<li>
<span class="filetools controls">
{{=editfile('views',c)}}
{{=deletefile([app, 'views', c])}}
</span>
<span class="file">
{{=peekfile('views',c)}}
</span>
<span class="extras celled">
{{if extend.has_key(c):}}{{=T("extends")}} <b>{{=extend[c]}}</b> {{pass}}
{{if include[c]:}}{{=T("includes")}} {{pass}}{{=XML(', '.join([B(f).xml() for f in include[c]]))}}
</span>
</li>
{{pass}}
</ul>
{{pass}}
</div>
<!-- STATIC -->
<h3 id="static" onclick="collapse('static_inner');" class="component">
{{=T("Static files")}}
<h3 id="_static" rel="pagebookmark">
<span class="component" onclick="collapse('static_inner');">{{=T("Static files")}}</span>
<span id="static" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="static_inner" class="component_contents">
{{if not statics:}}<p><strong>{{=T("There are no static files")}}</strong></p>{{pass}}
<ul>
{{
path=[]
for file in statics+['']:
items=file.split('/')
file_path=items[:-1]
filename=items[-1]
while path!=file_path:
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
path.append(file_path[len(path)])
thispath='static__'+'__'.join(path)
}}
<li class="folder">
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
else:
path = path[:-1]
}}
</ul></li>
{{
pass
pass
if filename:
}}<li>
<span class="filetools controls">
{{=editfile('static',file)}} {{=deletefile([app,'static',file])}}
</span>
<span class="file">
<a href="{{=URL(a=app,c='static',f=file)}}">{{=filename}}</a>
</span>
</li>{{
pass
pass
}}
{{pass}}
</ul>
{{if not statics:}}<p><strong>{{=T("There are no static files")}}</strong></p>{{else:}}
<ul class="unstyled act_edit">
{{
path=[]
for file in statics+['']:
items=file.split('/')
file_path=items[:-1]
filename=items[-1]
while path!=file_path:
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
path.append(file_path[len(path)])
thispath='static__'+'__'.join(path)
}}
<li class="folder"><i>&nbsp;</i>
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
<ul id="{{=thispath}}" style="display: none;" class="sublist">
{{
else:
path = path[:-1]
}}
</ul>
</li>
{{
pass
pass
if filename:
}}
<li>
<span class="filetools controls">
{{=editfile('static',file)}} {{=deletefile([app,'static',file])}}
</span>
<span class="file">
<a href="{{=URL(a=app,c='static',f=file)}}">{{=filename}}</a>
</span>
</li>
{{
pass
pass
}}
</ul>
{{pass}}
</div>
<!-- MODULES -->
<h3 id="modules" onclick="collapse('modules_inner');" class="component">
{{=T("Modules")}}
<h3 id="_modules" rel="pagebookmark">
<span class="component" onclick="collapse('modules_inner');">{{=T("Modules")}}</span>
<span id="modules" class="hashstick">&nbsp;</span><a href="#" class="tophashlink btn btn-mini btn-warning"><span>top</span></a>
</h3>
<div id="modules_inner" class="component_contents">
{{if not modules:}}
<p><strong>{{=T("There are no modules")}}</strong></p>
{{pass}}
<div class="controls comptools">
</div>
<ul>
{{for m in modules:}}
<li>
{{=editfile('modules',m)}}
{{if m!='__init__.py':}}<a class="button" href="{{=URL('delete',args=[app,'modules',m],vars=dict(sender=request.function+'/'+app))}}">{{=T("delete")}}</a>{{pass}}
{{=peekfile('modules',m)}}
</li>
{{pass}}
</ul>
{{if not modules:}}<p><strong>{{=T("There are no modules")}}</strong></p>{{else:}}
<ul class="unstyled act_edit">
{{for m in modules:}}
<li>
{{=editfile('modules',m)}}
{{if m!='__init__.py':}}<a class="button btn" href="{{=URL('delete',args=[app,'modules',m],vars=dict(sender=request.function+'/'+app))}}">{{=T("delete")}}</a>{{pass}}
{{=peekfile('modules',m)}}
</li>
{{pass}}
</ul>
{{pass}}
</div>
<!-- end "plugin" block -->
+6 -10
View File
@@ -1,25 +1,21 @@
{{extend 'layout.html'}}
{{block sectionclass}}resolve{{end}}
<!-- begin "resolve" block -->
<h2>{{=T('Resolve Conflict file')}} "{{=filename}}"</h2>
<script>
function plus() {jQuery('.plus').show(); jQuery('.minus').hide(); }
function minus() {jQuery('.plus').hide(); jQuery('.minus').show(); }
function all() {jQuery('.plus').show(); jQuery('.minus').show(); }
</script>
<div class="controls">
<button onclick="plus()">new</button>
<button onclick="minus()">old</button>
<button onclick="all()">all</button>
<button class="btn" onclick="plus()">new</button>
<button class="btn" onclick="minus()">old</button>
<button class="btn" onclick="all()">all</button>
</div>
<div class="form">
<form action="{{=URL(r=request,args=request.args)}}" method="post">
{{=diff}}
<input type="submit" name="merge" value="{{=T('merge')}}" /><br/>
<input class="btn" type="submit" name="merge" value="{{=T('merge')}}" /><br/>
</form>
</div>
<!-- end "resolve" block -->
+142 -155
View File
@@ -1,158 +1,145 @@
{{extend 'layout.html'}}
{{import os, glob}}
{{block sectionclass}}site{{end}}
<div class="applist f60">
<div class="applist_inner">
<h2>{{=T("Installed applications")}}</h2>
<ul>
{{for a in apps:}}
<li class="application"> <!-- onmouseover="jQuery(this).children('p').show()" onmouseout="jQuery(this).children('p').hide()"-->
{{if a==request.application:}}
<h3 class="currentapp">{{=a}} ({{=T('currently running')}})</h3>
<p class="controls">
{{else:}}
<h3 class="editableapp">{{=A(a,_href=URL(a,'default','index'))}}</h3>
{{if MULTI_USER_MODE and db.app(name=a):}}(created by {{="%(first_name)s %(last_name)s" % db.auth_user[db.app(name=a).owner]}}){{pass}}
<p class="controls">
{{if not os.path.exists('applications/%s/compiled' % a):}}
{{=sp_button(URL('design',args=a), T("Edit"))}}
{{else:}}
{{=button(URL(a,'appadmin','index'), T("appadmin"))}}
{{pass}}
{{=button(URL('about',args=a), T("About"))}}
{{pass}}
{{=button(URL('errors',args=a), T("Errors"))}}
{{=button(URL('cleanup',args=a), T("Clean"))}}
{{=button(URL('pack',args=a), T("Pack all"))}}
{{if not os.path.exists('applications/%s/compiled' % a):}}
{{=button(URL('compile_app',args=a), T("Compile"))}}
{{else:}}
{{=button(URL('pack',args=(a, 'compiled')), T("Pack compiled"))}}
{{if glob.glob('applications/%s/controllers/*.py' % a):}}
{{=button(URL('remove_compiled_app',args=a), T("Remove compiled"))}}
{{pass}}
{{pass}}
{{if os.path.exists(os.path.join(apath(r=request),a,'.git')): }}
{{=button(URL('git_pull',args=a), T("Git Pull"))}}
{{=button(URL('git_push',args=a), T("Git Push"))}}
{{pass}}
{{if a!=request.application:}}
{{=button(URL('uninstall',args=a), T("Uninstall"))}}
{{=button_enable(URL('enable',args=a), a)}}
{{pass}}
</p>
</li>
{{pass}}
</ul>
</div>
</div>
<div class="sidebar fl60">
<div class="sidebar_inner controls">
<div class="pwdchange">
<!-- CHANGE ADMIN PWD -->
{{if MULTI_USER_MODE:}}
{{=auth.navbar()}}
{{else:}}
{{=sp_button(URL('change_password'), T('Change admin password'))}}
{{pass}}
</div>
<!-- VERSION -->
{{if is_manager():}}
<div class="box">
<h3>{{=T("Version %s.%s.%s (%s) %s", myversion)}}</h3>
{{if session.check_version:}}
<p id="check_version">
{{=T('Checking for upgrades...')}}
<script>ajax('{{=URL('check_version')}}',[],'check_version');</script>{{session.check_version=False}}
{{else:}}
<p id="check_version">
{{=button("javascript:ajax('"+URL('check_version')+"',[],'check_version')", T('Check for upgrades'))}}
{{=button(URL('default','reload_routes'), T('Reload routes'))}}
</p>
{{pass}}
<p>
{{=T("Running on %s", request.env.server_software)}}
</p>
{{if session.is_mobile=='auto':}}<p>
{{=A(T('Try the mobile interface'),_href=URL('plugin_jqmobile','about'))}}</p>
{{pass}}
</div>
{{pass}}
<!-- MULTI_USER_INTERFACE -->
{{if MULTI_USER_MODE and is_manager():}}
<div class="box">
<h3>{{=T("Multi User Mode")}}</h3>
<p>
{{=button(URL('bulk_register'),T('Bulk Register'))}}
{{=button(URL('manage_students'),T('Manage Students'))}}
</p>
</div>
{{pass}}
<!-- APP WIZARD -->
<div class="box">
<h3>{{=T("New application wizard")}}</h3>
<p>{{=button(URL('wizard','index'), T('Start wizard'))}}
{{=T("(requires internet access)")}}</p>
</div>
<!-- SCAFFOLD APP -->
<div class="box">
<h3>{{=T("New simple application")}}</h3>
{{=form_create.custom.begin}}
<table><tr><td>
{{=LABEL(T("Application name:"))}}
</td><td>
{{=form_create.custom.widget.name}}
</td><td>
<button type="submit">{{=T('Create')}}</button>
</td></tr></table>
{{=form_create.custom.end}}
</div>
<!-- UPLOAD PACKAGE -->
<div class="box">
<h3>{{=T("Upload and install packed application")}}</h3>
{{=form_update.custom.begin}}
<table><tr><td>
{{=LABEL(T("Application name:"))}}
</td><td>
{{=form_update.custom.widget.name}}
</td></tr><tr><td>
{{=LABEL(T("Upload a package:"))}}
</td><td>
{{=form_update.custom.widget.file}}
</td></tr><tr><td>
{{=LABEL('Or ',T("Get from URL:"))}}
</td><td>
{{=form_update.custom.widget.url}}
</td></tr><tr><td>
({{=T('can be a git repo')}})
</td><td>
{{=form_update.custom.widget.overwrite}}
{{=LABEL(T("Overwrite installed app"))}}
</td></tr><tr><td>
</td><td>
<button type="submit">{{=T('Install')}}</button>
</td></tr></table>
{{=form_update.custom.end}}
</div>
<!-- DEPLOY ON GAE -->
<div class="box">
<h3>{{=T("Deploy")}}</h3>
<p>
{{=button(URL('gae','deploy'), T('Deploy on Google App Engine'))}}
{{=button(URL('openshift','deploy'),T('Deploy to OpenShift'))}}
</p>
</div><br/>
{{if TWITTER_HASH:}}
<div class="box">
<h3>{{=T("%s Recent Tweets"%TWITTER_HASH)}}</h3>
<div id="tweets">{{=T('loading...')}}</div>
<script>
jQuery(document).ready(function(){jQuery('#tweets').load('{{=URL('twitter.load')}}');});
</script>
</div>
{{pass}}
</div>
</div>
<!-- begin "site" block -->
<div class="row-fluid">
<div class="applist f60 span7">
<div class="applist_inner">
<h2>{{=T("Installed applications")}}</h2>
<ul class="unstyled">
{{for a in apps:}}
<li class="application"> <!-- onmouseover="jQuery(this).children('p').show()" onmouseout="jQuery(this).children('p').hide()"-->
{{if a==request.application:}}
<h3 class="currentapp muted">{{=a}} ({{=T('currently running')}})</h3>
<p class="controls row-buttons">
{{else:}}
<h3 class="editableapp muted">{{=A(a,_href=URL(a,'default','index'))}}</h3>
{{if MULTI_USER_MODE and db.app(name=a):}}(created by {{="%(first_name)s %(last_name)s" % db.auth_user[db.app(name=a).owner]}}){{pass}}
<p class="controls row-buttons">
{{if not os.path.exists('applications/%s/compiled' % a):}}
{{=sp_button(URL('design',args=a), T("Edit"))}}
{{else:}}
{{=button(URL(a,'appadmin','index'), T("appadmin"))}}
{{pass}}
{{=button(URL('about',args=a), T("About"))}}
{{pass}}
{{=button(URL('errors',args=a), T("Errors"))}}
{{=button(URL('cleanup',args=a), T("Clean"))}}
{{=button(URL('pack',args=a), T("Pack all"))}}
{{if not os.path.exists('applications/%s/compiled' % a):}}
{{=button(URL('compile_app',args=a), T("Compile"))}}
{{else:}}
{{=button(URL('pack',args=(a, 'compiled')), T("Pack compiled"))}}
{{if glob.glob('applications/%s/controllers/*.py' % a):}}
{{=button(URL('remove_compiled_app',args=a), T("Remove compiled"))}}
{{pass}}
{{pass}}
{{if os.path.exists(os.path.join(apath(r=request),a,'.git')): }}
{{=button(URL('git_pull',args=a), T("Git Pull"))}}
{{=button(URL('git_push',args=a), T("Git Push"))}}
{{pass}}
{{if a!=request.application:}}
{{=button(URL('uninstall',args=a), T("Uninstall"))}}
{{=button_enable(URL('enable',args=a), a)}}
{{pass}}
</p>
</li>
{{pass}}
</ul>
</div>
</div> <!-- /applist -->
<div class="sidebar fl60 span5">
<div class="sidebar_inner controls well well-small">
<!-- CHANGE ADMIN PWD -->
<div class="pwdchange pull-right">
{{if MULTI_USER_MODE:}}
{{=auth.navbar()}}
{{else:}}
{{=sp_button(URL('change_password'), T('Change admin password'))}}
{{pass}}
</div> <!-- /CHANGE ADMIN PWD -->
{{if is_manager():}}
<!-- VERSION -->
<div class="box">
<h3>{{=T("Version %s.%s.%s %s (%s)", myversion)}}</h3>
<p id="check_version" class="row-buttons">
{{if session.check_version:}}
{{=T('Checking for upgrades...')}}
</p>
<script>ajax('{{=URL('check_version')}}',[],'check_version');</script>
{{session.check_version=False}}
{{else:}}
{{=button("javascript:ajax('"+URL('check_version')+"',[],'check_version')", T('Check for upgrades'))}}
{{=button(URL('default','reload_routes'), T('Reload routes'))}}
</p>
{{pass}}
<p>{{=T("Running on %s", request.env.server_software)}}</p>
{{if session.is_mobile=='auto':}}
<p>{{=A(T('Try the mobile interface'),_href=URL('plugin_jqmobile','about'))}}</p>
{{pass}}
</div> <!-- /VERSION -->
{{pass}}
{{if MULTI_USER_MODE and is_manager():}}
<!-- MULTI_USER_INTERFACE -->
<div class="box">
<h3>{{=T("Multi User Mode")}}</h3>
<p class="row-buttons">
{{=button(URL('bulk_register'),T('Bulk Register'))}}
{{=button(URL('manage_students',vars={'order':'auth_user.id'}),T('Manage Students'))}}
</p>
</div> <!-- /MULTI_USER_INTERFACE -->
{{pass}}
<!-- APP WIZARD -->
<div class="box">
<h3>{{=T("New application wizard")}}</h3>
<p>{{=button(URL('wizard','index'), T('Start wizard'))}}
{{=T("(requires internet access)")}}</p>
</div> <!-- /APP WIZARD -->
<!-- SCAFFOLD APP -->
<div class="box">
<h3>{{=T("New simple application")}}</h3>
{{=form_create.custom.begin}}
{{=LABEL(T("Application name:"))}}
{{=form_create.custom.widget.name}}
<div class="controls"><button type="submit" class="btn">{{=T('Create')}}</button></div>
{{=form_create.custom.end}}
</div> <!-- /SCAFFOLD APP -->
<!-- UPLOAD PACKAGE -->
<div class="box">
<h3>{{=T("Upload and install packed application")}}</h3>
{{=form_update.custom.begin}}
<label for="appupdate_name">{{=T("Application name:")}}</label>
{{=form_update.custom.widget.name}}
<label for="appupdate_file">{{=T("Upload a package:")}}</label>
{{=form_update.custom.widget.file}}
<label for="appupdate_url">{{=T("Or Get from URL:")}}</label>
{{=form_update.custom.widget.url}}<small class="help-block">({{=T('can be a git repo')}})</small>
<div class="controls">
<label class="checkbox">
{{=form_update.custom.widget.overwrite}} {{=T("Overwrite installed app")}}
</label>
<button type="submit" class='btn'>{{=T('Install')}}</button>
</div>
{{=form_update.custom.end}}
</div> <!-- /UPLOAD PACKAGE -->
<!-- DEPLOY ON GAE -->
<div class="box">
<h3>{{=T("Deploy")}}</h3>
<p class="row-buttons">
{{=button(URL('gae','deploy'), T('Deploy on Google App Engine'))}}
{{=button(URL('openshift','deploy'),T('Deploy to OpenShift'))}}
</p>
</div> <!-- /DEPLOY ON GAE -->
<br/>
{{if TWITTER_HASH:}}
<!-- TWITTER -->
<div class="box">
<h3>{{=T("%s Recent Tweets"%TWITTER_HASH)}}</h3>
<div id="tweets">{{=T('loading...')}}</div>
<script>jQuery(document).ready(function(){jQuery('#tweets').load('{{=URL('twitter.load')}}');});</script>
</div> <!-- /TWITTER -->
{{pass}}
</div>
</div> <!-- /sidebar -->
</div> <!-- /row-fluid
<!-- end "site" block -->
+12 -6
View File
@@ -1,7 +1,7 @@
{{extend 'layout.html'}}
{{block sectionclass}}test{{end}}
<!-- begin "test" block -->
<h2>{{=T('Testing application')}} "{{=app}}"</h2>
{{for controller in sorted(controllers):}}
@@ -14,8 +14,14 @@ ajax('{{=URL(a=app,c=controller[:-3],f='_TEST')}}',[],'output_{{=controller[:-3]
//--></script>
{{pass}}
<p class="help">{{=T("""If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.
A green title indicates that all tests (if defined) passed. In this case test results are not shown.""")}}</p>
<p class="help">{{=T('Functions with no doctests will result in [passed] tests.')}}</p>
<p class="help">{{=T('ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.')}}</p>
<div class="row-fluid">
<p class="help alert alert-info span6">{{=T("""If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.
A green title indicates that all tests (if defined) passed. In this case test results are not shown.""")}}</p>
</div>
<div class="row-fluid">
<p class="help alert alert-info span6">{{=T('Functions with no doctests will result in [passed] tests.')}}</p>
</div>
<div class="row-fluid">
<p class="help alert alert-info span6">{{=T('ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.')}}</p>
</div>
<!--end "test" block -->
+142 -127
View File
@@ -1,139 +1,154 @@
{{extend 'layout.html'}}
{{block sectionclass}}ticket{{end}}
<!-- begin "ticket" block -->
<h2>{{=T('Error ticket')}} for "{{=app}}"</h2>
<h3>{{=T('Ticket ID')}}</h3>
<p>{{=ticket}}</p>
{{if output:}}<h4>{{=output}}</h4>{{pass}}
<h3>{{=T('Version')}}</h3>
<table class="versions">
<tbody>
<tr>
<th>web2py&trade;</th>
<td>{{=myversion}}</td>
</tr>
{{if snapshot:}}
<tr>
<th>Python</th>
<td>{{=snapshot.get('pyver','')}}</td>
</tr>
{{pass}}
</tbody>
<tbody>
<tr>
<th>web2py&trade;</th>
<td>{{=myversion}}</td>
</tr>
{{if snapshot:}}
<tr>
<th>Python</th>
<td>{{=snapshot.get('pyver','')}}</td>
</tr>
{{pass}}
</tbody>
</table>
{{if traceback or code or layer:}}
<h3>{{=T('Traceback')}}</h3>
<div class="inspect">
{{=traceback}}
</div>
{{if snapshot:}}
{{try:}}
<!-- ERROR SNAPSHOT -->
<h3>
{{=T('Error snapshot')}}
<span class="tooltip">{{=helpicon()}} <span>{{=T('Detailed traceback description')}}</span></span>
</h3>
<!-- SNAPSHOT LIST -->
<div id="snapshot">
<!-- Exception details -->
<p class="exception_object inspect">
<code>{{=snapshot['etype']}}({{=snapshot['evalue']}})</code>
</p>
<p class="controls">
<a class="button" onclick="collapse('exception_inner');"><span>{{=T('inspect attributes')}}</span></a>
</p>
<div id="exception_inner" class="hide">
<div class="inspect">
<h5>{{=T("Exception instance attributes")}}</h5>
<table>
<tbody>
{{for k,v in snapshot['exception'].items():}}
<tr>
<th>{{=k}}</th>
<td>{{=v}}</td>
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
</div>
<!-- FRAMES -->
<div id="frames">
<h4>{{=T('Frames')}}</h4>
<ul>
{{for i, frame in enumerate(snapshot['frames']):}}
<li>
{{is_hidden = (i != len(snapshot['frames'])-1 and 'hide' or 'inspect')}}
<div class="framefile inspect controls">
<p>
<strong>File {{="%s in %s at line %s" % (frame['file'], frame['func'], frame['lnum'])}}</strong>
<a class="button tbbutton" onclick="collapse('{{="%s_code_inner" % i}}');"><span>{{=T("code")}}</span></a>
<a class="button tbbutton" onclick="collapse('{{="%s_args_inner" % i}}');"><span>{{=T("arguments")}}</span></a>
<a class="button tbbutton" onclick="collapse('{{="%s_vars_inner" % i}}');"><span>{{=T("variables")}}</span></a>
</p>
<div id="{{="%s_args_inner" % i}}" class="{{=is_hidden}}">
<h5>Function argument list</h5>
<p>{{=frame['call']}}</p>
</div>
<div id="{{="%s_code_inner" % i}}" class="{{=is_hidden}}">
<h5>Code listing</h5>
{{if frame['lines']:}}
<pre>{{=CODE('\n'.join([x[1] for x in sorted(frame['lines'].items(),key=lambda x: x[0])]),
language='python', link=None, counter=min(frame['lines'].keys()), highlight_line=frame['lnum'])}}</pre>
{{pass}}
</div>
<div id="{{="%s_vars_inner" % i}}" class="{{=is_hidden}}">
<h5>Variables</h5>
<table>
<tbody>
{{for k,v in frame['dump'].items():}}
<tr>
<th>{{=k}}</th>
<td>{{=v}}</td>
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
</li>
{{pass}}
</ul>
</div>
<!-- VIEW ENVIRONMENT -->
<div class="viewenv">
<h4>Context</h4>
<p class="controls">
<a class="button" onclick="jQuery('#locals').slideToggle()"><span>{{=T('locals')}}</span></a>
<a class="button" onclick="jQuery('#request').slideToggle()"><span>{{=T('request')}}</span></a>
<a class="button" onclick="jQuery('#session').slideToggle()"><span>{{=T('session')}}</span></a>
<a class="button" onclick="jQuery('#response').slideToggle()"><span>{{=T('response')}}</span></a>
</p>
<div class="hide inspect" id="locals"><h6>locals</h6>{{=BEAUTIFY(snapshot['locals'])}}</div>
<div class="hide inspect" id="request"><h6>request</h6>{{=BEAUTIFY(snapshot['request'])}}</div>
<div class="hide inspect" id="session"><h6>session</h6>{{=BEAUTIFY(snapshot['session'])}}</div>
<div class="hide inspect" id="response"><h6>response</h6>{{=BEAUTIFY(snapshot['response'])}}</div>
</div>
{{except Exception, e:}}
<!-- this should not happen, just in case... (cannot output normal hmtl as we don't know current open tags) -->
{{import traceback;tb=traceback.format_exc().replace("\n","\\n") }}
<script language='javascript'>alert("Exception during snapshot rendering: {{=tb}} ");</script>
{{pass}}
{{pass}}
<div class="errorsource">
<h3>In file: {{=layer}}</h3>
{{=CODE(code.replace('\r',''),language='python',link='/examples/global/vars/')}}
</div>
<h3>{{=T('Traceback')}}</h3>
<div class="inspect resp1">{{=traceback}}</div>
{{if snapshot:}}
{{try:}}
<!-- ERROR SNAPSHOT -->
<h3>{{=T('Error snapshot')}}
<a href="#" rel="tooltip" data-placement="right" data-original-title="{{=T('Detailed traceback description')}}">
{{=helpicon()}}
<span>{{=T("Detailed traceback description")}}</span>
</a>
</h3>
<!-- SNAPSHOT LIST -->
<div id="snapshot">
<!-- Exception details -->
<p class="exception_object inspect">
<code>{{=snapshot['etype']}}({{=snapshot['evalue']}})</code>
</p>
<p class="controls">
<a class="button btn" onclick="collapse('exception_inner');"><span>{{=T('inspect attributes')}}</span></a>
</p>
<div id="exception_inner" class="hide">
<div class="inspect">
<h5>{{=T("Exception instance attributes")}}</h5>
<table>
<tbody>
{{for k,v in snapshot['exception'].items():}}
<tr>
<th>{{=k}}</th>
<td>{{=v}}</td>
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
</div>
<!-- FRAMES -->
<div id="frames">
<h4>{{=T('Frames')}}</h4>
<ul class="unstyled">
{{for i, frame in enumerate(snapshot['frames']):}}
<li>
{{is_hidden = (i != len(snapshot['frames'])-1 and 'hide' or 'inspect')}}
<div class="framefile inspect controls">
<p>
<strong>File {{="%s in %s at line %s" % (frame['file'], frame['func'], frame['lnum'])}}</strong>
<a class="button tbbutton btn" onclick="collapse('{{='%s_code_inner' % i}}');"><span>{{=T("code")}}</span></a>
<a class="button tbbutton btn" onclick="collapse('{{='%s_args_inner' % i}}');"><span>{{=T("arguments")}}</span></a>
<a class="button tbbutton btn" onclick="collapse('{{='%s_vars_inner' % i}}');"><span>{{=T("variables")}}</span></a>
</p>
<div id="{{='%s_args_inner' % i}}" class="{{=is_hidden}}" style="width:100%;overflow:auto">
<h5>Function argument list</h5>
<p>{{=frame['call']}}</p>
</div>
<div id="{{='%s_code_inner' % i}}" class="{{=is_hidden}}" style="width:100%;overflow:auto">
<h5>Code listing</h5>
{{if frame['lines']:}}
<pre>{{=CODE('\n'.join([x[1] for x in sorted(frame['lines'].items(),key=lambda x: x[0])]),
language='python', link=None, counter=min(frame['lines'].keys()), highlight_line=frame['lnum'])}}</pre>
{{pass}}
</div>
<div id="{{='%s_vars_inner' % i}}" class="{{=is_hidden}}" style="width:100%;overflow:auto">
<h5>Variables</h5>
<table>
<tbody>
{{for k,v in frame['dump'].items():}}
<tr>
<th>{{=k}}</th>
<td>{{=v}}</td>
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
</li>
{{pass}}
</ul>
</div>
<!-- VIEW ENVIRONMENT -->
<div class="viewenv">
<h4><span>Context</span></h4>
<p class="controls">
<a class="button btn" onclick="jQuery('#locals').slideToggle()"><span>{{=T('locals')}}</span></a>
<a class="button btn" onclick="jQuery('#request').slideToggle()"><span>{{=T('request')}}</span></a>
<a class="button btn" onclick="jQuery('#session').slideToggle()"><span>{{=T('session')}}</span></a>
<a class="button btn" onclick="jQuery('#response').slideToggle()"><span>{{=T('response')}}</span></a>
</p>
<div class="hide inspect resp1" id="locals"><h6>locals</h6>
{{try:}}
{{=BEAUTIFY(snapshot['locals'])}}
{{except:}}
{{=BEAUTIFY('no locals available in snapshot')}}
{{pass}}
</div>
<div class="hide inspect" id="request"><h6>request</h6>
{{try:}}
{{=BEAUTIFY(snapshot['request'])}}
{{except:}}
{{=BEAUTIFY('no request available in snapshot')}}
{{pass}}
</div>
<div class="hide inspect" id="session"><h6>session</h6>
{{try:}}
{{=BEAUTIFY(snapshot['session'])}}
{{except:}}
{{=BEAUTIFY('no session available in snapshot')}}
{{pass}}
</div>
<div class="hide inspect" id="response"><h6>response</h6>
{{try:}}
{{=BEAUTIFY(snapshot['response'])}}
{{except:}}
{{=BEAUTIFY('no response available in snapshot')}}
{{pass}}
</div>
</div>
{{except Exception, e:}}
<!-- this should not happen, just in case... (cannot output normal hmtl as we don't know current open tags) -->
{{import traceback;tb=traceback.format_exc().replace("\n","\\n") }}
<script language='javascript'>alert("Exception during snapshot rendering: {{=tb}} ");</script>
{{pass}}
{{pass}}
<div class="errorsource">
<h3>In file: {{=layer}}</h3>
{{=CODE(code.replace('\r',''),language='python',link='/examples/global/vars/')}}
</div>
{{else:}}
<h3>{{=T('Ticket Missing')}}</h3>
<h3>{{=T('Ticket Missing')}}</h3>
{{pass}}
<!-- end "ticket" block -->
@@ -1,7 +1,7 @@
{{extend 'layout.html'}}
<!-- begin "uninstall" block -->
<h2>{{=T('Are you sure you want to uninstall application "%s"?', app)}}</h2>
<div class="center">
{{=dialog}}
</div>
<!-- end "uninstall" block -->
@@ -1,13 +1,17 @@
{{extend 'layout.html'}}
{{
dlg = dialog
smt_button = dlg.element(_type="submit")
smt_button['_class'] = 'btn'
smt_button['_style'] = 'margin-right:4px;'
ccl_button = dlg.element(_type="button")
ccl_button['_class'] = 'btn'
}}
{{block sectionclass}}upgrade{{end}}
<!-- begin "shell" block -->
<h2>{{=T('web2py upgrade')}}</h2>
<p class="center"><strong class="att">{{=T('ATTENTION:')}}</strong> {{=T('This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk')}}<br />
{{=T('If start the upgrade, be patient, it may take a while to download')}}</p>
<p class="center"><div class="alert"><strong class="att">{{=T('ATTENTION:')}}</strong> {{=T('This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk')}}<br />
{{=T('If start the upgrade, be patient, it may take a while to download')}}</p></div>
<div class="center">
{{=dialog}}
</div>
</div>
+57 -10
View File
@@ -1,20 +1,67 @@
{{extend 'layout.html'}}
<!-- begin "user" block -->
<h2>{{=T( request.args(0).replace('_',' ').capitalize() )}}</h2>
<div id="web2py_user_form">
{{if 'auth' in globals():}}
{{
# add bootstrap class to form
form['_class']='span4 well well-small'
# change form.custom.begin
form.custom.begin=XML("<%s %s>" % (form.tag,form._xml()[0]))
if request.args(0)=='login':
# delete empty label
d = form.elements("tr#auth_user_remember__row")
d[0][0] = " "
# remake remember checkbox
cbx_inp=form.element(_name='remember')
cbx_inp['_class']=""
cbx_lbl=form.element(_for='auth_user_remember')[0]
form.element('div',replace=LABEL(cbx_inp,cbx_lbl,_class="checkbox"))
# new form buttons
smt = form.element('input',_type='submit')
smt['_class']='btn'
btns = [smt]
if not 'register' in auth.settings.actions_disabled:
btns.append(A(T('register'),_href=URL(r=request,args='register'),_class='btn btn-lnk'))
pass
if not 'request_reset_password' in auth.settings.actions_disabled:
btns.append(A(T('lost password'),_href=URL(r=request,args='request_reset_password'),_class='btn btn-lnk'))
pass
form.element('input[type=submit]',replace=DIV(*btns,_class="controls-inline"))
pass
if request.args(0)in['register','profile']:
# remake is_manager checkbox
cbx_inp=form.element(_name='is_manager')
cbx_lbl=form.element(_for='auth_user_is_manager')[0]
form.element(_name='is_manager',replace=lambda cbx_inp : LABEL(cbx_inp,cbx_lbl,_class="checkbox"))
# delete is manager label
d = form.elements("tr#auth_user_is_manager__row")
d[0][0][0] = " "
# new form buttons
smt = form.element('input',_type='submit')
smt['_class']='btn'
form.element('input[type=submit]',replace=lambda button: DIV(button,_class="controls-inline"))
pass
if request.args(0)in ['request_reset_password','change_password']:
# new form buttons
smt = form.element('input',_type='submit')
smt['_class']='btn'
form.element('input[type=submit]',replace=lambda button: DIV(button,_class="controls-inline"))
pass
}}
{{=form.custom.begin}}
{{for e in form.components[0]:}}
{{= e[0][0]}}
{{= e[1][0]}}
{{pass}}
{{=form.custom.end}}
{{else:}}
{{=form}}
{{if request.args(0)=='login':}}
{{if not 'register' in auth.settings.actions_disabled:}}
<br/><a href="{{=URL(r=request,args='register')}}">register</a>
{{pass}}
{{if not 'request_reset_password' in auth.settings.actions_disabled:}}
<br/><a href="{{=URL(r=request,args='request_reset_password')}}">lost password</a>
{{pass}}
{{pass}}
</div>
<script language="javascript">
<!--
//<!--
jQuery("#web2py_user_form input:visible:enabled:first").focus();
//-->
</script>
<!-- end "user" block -->
+74 -33
View File
@@ -1,44 +1,85 @@
<!doctype html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="P3P" content="CP=\"IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA\"" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{=response.title or URL()}}</title>
{{response.files.append(URL('static','css/styles.css'))}}
{{
response.files.append(URL('static','css/bootstrap.min.css'))
response.files.append(URL('static','css/styles.css'))
response.files.append(URL('static','css/bootstrap_essentials.css'))
response.files.append(URL('static','css/bootstrap_adapters.css'))
response.files.append(URL('static','css/bootstrap-responsive.min.css'))
}}
{{include 'web2py_ajax.html'}}
<script>jQuery.noConflict();</script>
</head>
<body class="{{=T('direction: ltr') == 'direction: rtl' and 'RTLbody' or ''}} {{block sectionclass}}home{{end}}">
<div id="header">
<h1 id="start">
<a href="{{=URL('default', 'index')}}" class="button"><span>web2py&trade; {{=T('administrative interface')}}</span></a>
</h1>
{{if response.menu is not None:}}
<ul id="menu">
{{for _name,_active,_link in response.menu:}}
<li>{{=A(SPAN(_name), _href=_link, _class=_active and 'button select' or 'button')}}</li>
{{pass}}
</ul>
{{pass}}
</div>
<div id="main">
<div id="main_inner">
<div class="flash">{{=response.flash or ''}}</div>
{{include}}
</div>
</div>
<div id="footer" class="fixed">
{{=T('Powered by')}} {{=A('web2py', _href='http://www.web2py.com')}}&trade; {{=T('created by')}} Massimo Di Pierro &copy;2007-{{=request.now.year}} -
{{if hasattr(T,'get_possible_languages_info'):}}
<span>
{{=T('Admin language')}}
<select name="adminlanguage" onchange="var date = new Date();cookieDate=date.setTime(date.getTime()+(100*24*60*60*1000));document.cookie='adminLanguage='+this.options[this.selectedIndex].id+'; expires='+cookieDate+'; path=/';window.location.reload()">
{{for langinfo in sorted([(code,info[1]) for code,info in T.get_possible_languages_info().iteritems() if code != 'default']):}}
<option {{=T.accepted_language==langinfo[0] and 'selected' or ''}} {{='id='+langinfo[0]}} >{{=langinfo[1]}}</option>
{{pass}}
</select>
</span>
{{pass}}
</div>
<!-- NAVBAR
============== -->
<div id="header" class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<div id="start" class="brand_wrapper">
<a href="{{=URL('default', 'index')}}" class="button brand" ><span>web2py&trade; {{=T('administrative interface')}}</span></a>
</div>
<div class="nav-collapse">
{{if response.menu is not None:}}
<ul id="menu" class="nav pull-right">
{{for _name,_active,_link in response.menu:}}
<li>{{=A(SPAN(_name), _href=_link, _class=_active and 'button select' or 'button')}}</li>
{{pass}}
</ul>
{{pass}}
</div><!--/.nav-collapse -->
</div><!-- /container-fluid -->
</div><!-- /navbar-inner -->
</div><!-- /#header -->
<!-- MAIN
=========== -->
<div id="main" class="container-fluid">
<div id="main_inner" class="row-fluid">
<div class="span12">
<div class="flash alert">{{=response.flash or ''}}</div>
{{include}}
</div><!-- /main span12 -->
</div><!-- /main row-fluid -->
</div><!-- /#main -->
<!-- FOOTER
============== -->
<footer id="footer" class="fixed">
<p><span>{{=T('Powered by')}} {{=A('web2py', _href='http://www.web2py.com')}}&trade; {{=T('created by')}} Massimo Di Pierro &copy;2007-{{=request.now.year}}
{{if hasattr(T,'get_possible_languages_info'):}}
- {{=T('Admin language')}}</span>
<select name="adminlanguage" onchange="var date = new Date();cookieDate=date.setTime(date.getTime()+(100*24*60*60*1000));document.cookie='adminLanguage='+this.options[this.selectedIndex].id+'; expires='+cookieDate+'; path=/';window.location.reload()">
{{for langinfo in sorted([(code,info[1]) for code,info in T.get_possible_languages_info().iteritems() if code != 'default']):}}
<option {{=T.accepted_language==langinfo[0] and 'selected' or ''}} {{='id='+langinfo[0]}} >{{=langinfo[1]}}</option>
{{pass}}
</select>
{{else:}}
</span>{{pass}}
</p>
</footer><!-- /#footer -->
<!-- BS JAVASCRIPT
====================== -->
<script src="{{=URL('static','js/bootstrap.min.js')}}"></script>
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("[rel=tooltip]").tooltip();
});
</script>
</body>
</html>
+35 -85
View File
@@ -1,92 +1,42 @@
{{extend 'layout.html'}}
{{block sectionclass}}shell{{end}}
<!--style type="text/css">
.prompt, #output {
width: 45em;
border: 1px solid #CCCCCC;
font-size: 10pt;
margin: 0.5em;
padding: 0.5em;
padding-right: 0em;
overflow: auto;
wrap: hard;
}
#output {
height:250px;overflow:auto;
}
#toolbar {
margin-left: 0.5em;
padding-left: 0.5em;
}
#caret {
width: 2.5em;
margin-right: 0px;
padding-right: 0px;
border-right: 0px;
}
#statement {
width: 43em;
margin-left: -1em;
padding-left: 0px;
border-left: 0px;
background-position: top right;
background-repeat: no-repeat;
}
.processing {
background-image: url("{{=URL('static','images/spinner.gif')}}");
}
#ajax-status {
font-weight: bold;
}
.message {
color: #8AD;
font-weight: bold;
font-style: italic;
}
.error {
color: #F44;
}
.username {
font-weight: bold;
}
</style-->
<!-- begin "shell" block -->
<div id="wrapper">
<textarea id="output" readonly="readonly">web2py Shell {{=request.env.web2py_version}}</textarea>
<div class="row-fluid">
<div class="output-wrapper span8">
<textarea id="output" readonly="readonly">web2py Shell {{=request.env.web2py_version}}</textarea>
</div>
</div>
<form id="form" action="{{=URL(r=request,f='callback',args=app)}}" method="get">
<div id="shellwrapper">
<div id="caret">&gt;&gt;&gt;</div>
<div class="tooltip">
<textarea class="prompt" name="statement" id="statement"></textarea>
<span>Type some Python code in here and hit Return (Enter) to execute it.</span>
</div>
<div id="autoscroll" style="cursor:pointer;float:right;">autoscroll</div>
</div>
</form>
<div class="row-fluid">
<form id="form" action="{{=URL(r=request,f='callback',args=app)}}" method="get" class="span8">
<div id="shellwrapper">
<div class="prompt-wrapper">
<div class="prompt-container">
<textarea class="prompt" name="statement" id="statement"></textarea>
</div>
<a href="#" rel="tooltip" data-placement="right" data-original-title="{{=T('Type some Python code in here and hit Return (Enter) to execute it.')}}">
{{=helpicon()}}
<span>Type some Python code in here and hit Return (Enter) to execute it.</span>
</a>
</div>
<div id="caret"><span>&gt;&gt;&gt;</span></div>
<div id="autoscroll">autoscroll</div>
</div>
</form>
</div>
<div class="row-fluid clearfix">
<div class="help alert alert-info span6">
<ul>
<li>Using the shell may lock the database to other users of this app.</li>
<li>Each db statement is automatically committed.</li>
<li>Creating new tables dynamically is not allowed.</li>
<li>Models are automatically imported in the shell.</li>
</ul>
</div>
</div>
</div>
<div class="help">
<ul>
<li>Using the shell may lock the database to other users of this app.</li>
<li>Each db statement is automatically committed.</li>
<li>Creating new tables dynamically is not allowed.</li>
<li>Models are automatically imported in the shell.</li>
</ul>
</div>
<script type="text/javascript" src="{{=URL('static', 'js/autoscroll.js')}}"></script>
<script type="text/javascript">
@@ -163,4 +113,4 @@ jQuery(document).ready(function(){
});
});
</script>
<!-- end "shell" block -->
@@ -3,6 +3,7 @@
var w2p_ajax_confirm_message = "{{=T('Are you sure you want to delete this object?')}}";
var w2p_ajax_date_format = "{{=T('%Y-%m-%d')}}";
var w2p_ajax_datetime_format = "{{=T('%Y-%m-%d %H:%M:%S')}}";
var ajax_error_500 = '{{=XML(T('An error occured, please %s the page') % A(T('reload'), _href=URL(args=request.args, vars=request.vars))) }}'
//--></script>
{{
response.files.insert(0,URL('static','js/jquery.js'))
+11 -10
View File
@@ -1,14 +1,15 @@
{{extend 'layout.html'}}
{{block sectionclass}}generated{{end}}
<a class="button" href="{{=URL(app,'default','index')}}">Open new app in new window</a>
<a class="button" href="{{=URL('step1')}}">Back to wizard</a>
<a class="button" href="{{=URL('default','design',args=app)}}">Admin design page</a>
{{if have_mercurial:}}
<a class="button" href="{{=URL('mercurial','commit',args=app)}}">Admin versioning page</a>
{{pass}}
<a class="button" href="{{=URL(app,'appadmin','index')}}">Database administration</a>
<!-- begin "generated" block -->
<div class="controls row-buttons">
{{=button(URL(app,'default','index'), T('Open new app in new window'))}}
{{=button(URL('step1'), T('Back to wizard'))}}
{{=button(URL('default','design',args=app), T('Admin design page'))}}
{{if have_mercurial:}}
{{=button(URL('mercurial','commit',args=app), T('Admin versioning page'))}}
{{pass}}
{{=button(URL(app,'appadmin','index'), T('Database administration'))}}
</div>
<br/><br/>
<iframe style="width: 100%; height: 100%; min-height:600px" src="{{=URL(app,'default','index')}}"></iframe>
<!-- end "generated" block -->
+179 -137
View File
@@ -1,141 +1,183 @@
{{extend 'layout.html'}}
{{block sectionclass}}step{{end}}
<!-- begin "step" block -->
<h2>{{=T('New Application Wizard')}}</h2>
<div id="wizard_nav" class="f20 controls">
{{if request.function=='index':}}
<h3>{{=T('Start a new app')}}</h3>
{{else:}}
<div class="box">
<h3>{{=T('Basics')}}</h3>
<p>{{=button(URL('index'), T('restart'))}}</p>
<p><strong>App Name:</strong> {{=session.app['name']}}</p>
</div>
<div class="box">
<h3>Current settings</h3>
<p>{{=button(URL('step1'), T('Edit'))}}</p>
<ul id="current_settings">
{{for key,value in session.app['params']:}}
<li><b>{{=key}}:</b> {{=value}}</li>
{{pass}}
</ul>
</div>
<div class="box">
<h3>Tables</h3>
<p>{{=button(URL('step2'), T('edit all'))}}</p>
<ul>
{{for i,table in enumerate(session.app['tables']):}}
<li>{{=button(URL('step3',args=i), T('Edit'))}} <strong>{{=table}}</strong></li>
{{pass}}
</ul>
</div>
<div class="box">
<h3>Pages</h3>
<p>{{=button(URL('step4'), T('edit all'))}}</p>
<ul>
{{for i,page in enumerate(session.app['pages']):}}
<li>{{=button(URL('step5',args=i), T('Edit'))}} <strong>{{=page}}</strong></li>
{{pass}}
</ul>
</div>
<div class="box">
<h3>{{=T('Generate')}}</h3>
<p>{{=button(URL('step6'), T('go!'))}}</p>
</div>
{{pass}}
<div class='row-fluid'>
<div id="wizard_nav" class="f20 controls span3">
{{if request.function=='index':}}
<h3>{{=T('Start a new app')}}</h3>
{{else:}}
<div class="box first-box">
<h3>{{=T('Basics')}}</h3>
<p>{{=button(URL('index'), T('restart'))}}</p>
<p><strong>App Name:</strong> {{=session.app['name']}}</p>
</div>
<div class="box">
<h3>Current settings</h3>
<p>{{=button(URL('step1')+'/#xwizard_form', T('Edit'))}}</p>
<ul id="current_settings" class="unstyled">
{{for key,value in session.app['params']:}}
<li><b>{{=key}}:</b> {{=value}}</li>
{{pass}}
</ul>
</div>
<div class="box">
<h3>Tables</h3>
<p>{{=button(URL('step2')+'/#xwizard_form', T('edit all'))}}</p>
<ul class="unstyled">
{{for i,table in enumerate(session.app['tables']):}}
<li>{{=button(URL('step3',args=[i])+'/#xwizard_form', T('Edit'))}} <strong>{{=table}}</strong></li>
{{pass}}
</ul>
</div>
<div class="box">
<h3>Pages</h3>
<p>{{=button(URL('step4')+'/#xwizard_form', T('edit all'))}}</p>
<ul class="unstyled">
{{for i,page in enumerate(session.app['pages']):}}
<li>{{=button(URL('step5',args=i)+'/#xwizard_form', T('Edit'))}} <strong>{{=page}}</strong></li>
{{pass}}
</ul>
</div>
<div class="box">
<h3>{{=T('Generate')}}</h3>
<p>{{=button(URL('step6')+'/#xwizard_form', T('go!'))}}</p>
</div>
{{pass}}
</div> <!-- /wizard nav -->
<div id="wizard_form" class="fl20 controls span9" rel="pagebookmark"><span id="xwizard_form" class="hashstick">&nbsp;</span>
<!-- FORM -->
{{if 'step' in request.function:}}
<h3>{{=T('Step')}} {{=step}}</h3>
{{if request.function!='step1':}}
{{=button(URL('step' + str(int(request.function[-1])-1)) + '/#xwizard_form', T('back'))}}
{{pass}}
{{else:}}
<h3>{{=T('Begin')}}</h3>
{{pass}}
{{if request.function in ('step1','step2','step3','step4','step5'):}}
{{=button(URL('step6') + '/#xwizard_form', T('skip to generate'))}}
{{pass}}
<br /><br />
{{if request.function in ('step1','step6'):}}
{{pass}}
{{if request.function!='step6':}}
<div class="form row-fluid">
{{=form.custom.begin}}
{{ for fieldname in form.table.fields: }}
{{if fieldname is not 'id':}}
<label>{{=form.custom.label[fieldname]}}:</label>
{{=form.custom.widget[fieldname]}}
{{if fieldname=='layout_theme':}}
<span class="help-inline">
<img src="{{=LAYOUTS_APP}}/static/plugin_layouts/layouts/{{=dict(session.app['params'])['layout_theme']}}/preview.png" alt="" align="right" id="preview" class="img-polaroid"/>
</span>
{{pass}}
{{pass}}
{{pass}}
<div class="controls"><button type="submit" class="btn">{{=T('Submit')}}</button></div>
{{=form.custom.end}}
</div>
<script>
jQuery(function(){
var t=jQuery('#no_table_layout_theme');
t.change(function(){
jQuery('#preview').attr('src','{{=LAYOUTS_APP}}/static/plugin_layouts/layouts/'+t.val()+'/preview.png');
});
jQuery("#preview").error(function (){
jQuery('#preview').attr('src','http://placehold.it/190x141&text=no+preview+available');
});
jQuery('ul[id$="_grow_input"] li').addClass('input-append');
jQuery('ul[id$="_grow_input"] li a').addClass('btn');
});
</script>
{{else:}}
<div class="form row-fluid">
{{=form.custom.begin}}
{{ for fieldname in form.table.fields: }}
{{if fieldname is not 'id':}}
<div class="control-group">
<label class="control-label">{{=form.custom.label[fieldname]}}:</label>
<div class="controls">
<label class="checkbox">{{=form.custom.widget[fieldname]}}</label>
</div>
</div>
{{pass}}
{{pass}}
<div class="control-group">
<label class="control-label empty">&nbsp;</label>
<div class="controls">
<button type="submit" class="btn">{{=T('Submit')}}</button>
</div>
</div>
{{=form.custom.end}}
</div>
{{pass}}
<!-- INSTRUCTIONS -->
<div class="box">
<h4>Instructions</h4>
<div class="row-fluid">
<div class="help span7 alert alert-block alert-info">
{{if request.function=='index':}}
<ul class="unstyled">
<li>Insert the name of a new app.</li>
<li>If the app exists and was created with the wizard, you will be able to edit it, but any manual editing to the app <b>will be lost</b>.</li>
</ul>
{{elif request.function=='step1':}}
<ul class="unstyled">
<li>This Wizard will help you build a new web2py app.</li>
<li>You can create an app with a name that already exists.</li>
<li>If you do not have an email server set email server to "logging".</li>
<li>If you want to use Janrain Engage for login: 1) Sign up for a <a href="http://www.janrain.com/products/engage">Janrain Engage</a> account; 2) Register you hostname, domain, and obtain an api key; 3) Set Login Config above to "domain:api_key".</li>
<li>ATTENTION: you can use the wizard to download plugins BUT we cannot guarantee the stability or backward compatibility of plugins. Moreover plugins may conflict with each other. Anyway, we do recommend installing plugin "wiki" with adds CMS like capabilities to your app.</li>
</ul>
{{elif request.function=='step2':}}
<ul class="unstyled">
<li>List the names of table that you need.</li>
<li>If you do not need authentication remove the table "auth_user".</li>
<li>Press enter to create a new input row.</li>
<li>Empty rows are ignored.</li>
<li>Other tables for role based access control will be created automatically, and do not need to be listed.</li>
<li>You will be able to add fields later.</li>
</ul>
{{elif request.function=='step3':}}
<ul class="unstyled">
<li>List the fields for this table (do not include an id field, it is automatic), for example "name unique" or "birthday date" or "image upload" or "comments multiple" or "description wiki required"</li>
<li>The first keyword(s) for each entry will be used to generate a name for the table field and its label. You can use spaces an other unicode characters.</li>
<li>Keywords "string" (default), "text", "integer", "boolean", "float", "double", "file", "date", "time", "datetime", "file", "upload" will be used to determine the field type and they will not be made part of the field name.</ li>
<li>For a reference field use a field name, followed by the name of the referenced table.</li>
<li>Other special keywords are "required", "notnull" or "notempty", "unique". They map into equivalent validators but (at this time) should only be used with string and text types.</li>
<li>The keywords "html" and "wiki" force a text type and set a representation for the field value as sanitized HTML and MARKMIN resepectively.</li>
<li>string, integer and reference fields can be "multiple", i.e. multiple values will be allowed</li>
<li>For the "auth_user" table do not add attributes to the default fields (username, first_name, last_name, password and email). They are handled automatically.</li>
<li>Some fields will be added automatically upon creation and handled automatically: "created_by", "created_on", "modified_by", "modified_on", "active" (only active fields can be selected).</li>
<li>For every table "table" another table "table_archive" is created and it contains the previous versions of each record. This is only accessible via appadmin or programmatically.</li>
</ul>
{{elif request.function=='step4':}}
<ul class="unstyled">
<li>List the names of the pages you want to create.</li>
<li>Some pages are listed automatically because they expose Create/Read/Update/Delete for each tables you have created.</li>
<li>All pages, except "error" and those with name starting in underscore willbe listed in the menu. You will be able to edit the menu later.</li>
<li>You should have page "index", the starting point of your app, and page "error", where web2py will redirect to in case of error.</li>
</ul>
{{elif request.function=='step5':}}
<ul class="unstyled">
<li>Use the markmin syntax to add text to your pages.</li>
</ul>
{{elif request.function=='step6':}}
<ul class="unstyled">
<li>Almost done. Click on the button above to create your new app.</li>
<li>Once done you will be able to edit it as any normal web2py app.</li>
</ul>
{{pass}}
</div>
</div>
</div>
</div> <!-- /wizard form -->
</div>
<div id="wizard_form" class="fl20 controls">
<!-- FORM -->
{{if 'step' in request.function:}}
<h3>{{=T('Step')}} {{=step}}</h3>
{{if request.function!='step1':}}
{{=button(URL('step' + str(int(request.function[-1])-1)), T('back'))}}
{{pass}}
{{else:}}
<h3>{{=T('Begin')}}</h3>
{{pass}}
{{if request.function in ('step1','step2','step3','step4','step5'):}}
{{=button(URL('step6'), T('skip to generate'))}}
{{pass}}
<br /><br />
{{if request.function in ('step1','step6'):}}
<img src="{{=LAYOUTS_APP}}/static/plugin_layouts/layouts/{{=dict(session.app['params'])['layout_theme']}}/preview.png" alt="" align="right" id="preview"/>
{{pass}}
<div class="form">
{{=form}}
</div>
<script>
jQuery(function(){
var t=jQuery('#no_table_layout_theme');
t.change(function(){
jQuery('#preview').attr('src','{{=LAYOUTS_APP}}/static/plugin_layouts/layouts/'+t.val()+'/preview.png');
});
});
</script>
<!-- INSTRUCTIONS -->
<div class="box">
<h4>Instructions</h4>
<div class="help">
{{if request.function=='index':}}
<ul>
<li>Insert the name of a new app.</li>
<li>If the app exists and was created with the wizard, you will be able to edit it, but any manual editing to the app <b>will be lost</b>.</li>
</ul>
{{elif request.function=='step1':}}
<ul>
<li>This Wizard will help you build a new web2py app.</li>
<li>You can create an app with a name that already exists.</li>
<li>If you do not have an email server set email server to "logging".</li>
<li>If you want to use Janrain Engage for login: 1) Sign up for a <a href="http://www.janrain.com/products/engage">Janrain Engage</a> account; 2) Register you hostname, domain, and obtain an api key; 3) Set Login Config above to "domain:api_key".</li>
<li>ATTENTION: you can use the wizard to download plugins BUT we cannot guarantee the stability or backward compatibility of plugins. Moreover plugins may conflict with each other. Anyway, we do recommend installing plugin "wiki" with adds CMS like capabilities to your app.</li>
</ul>
{{elif request.function=='step2':}}
<ul>
<li>List the names of table that you need.</li>
<li>If you do not need authentication remove the table "auth_user".</li>
<li>Press enter to create a new input row.</li>
<li>Empty rows are ignored.</li>
<li>Other tables for role based access control will be created automatically, and do not need to be listed.</li>
<li>You will be able to add fields later.</li>
</ul>
{{elif request.function=='step3':}}
<ul>
<li>List the fields for this table (do not include an id field, it is automatic), for example "name unique" or "birthday date" or "image upload" or "comments multiple" or "description wiki required"</li>
<li>The first keyword(s) for each entry will be used to generate a name for the table field and its label. You can use spaces an other unicode characters.</li>
<li>Keywords "string" (default), "text", "integer", "boolean", "float", "double", "file", "date", "time", "datetime", "file", "upload" will be used to determine the field type and they will not be made part of the field name.</ li>
<li>For a reference field use a field name, followed by the name of the referenced table.</li>
<li>Other special keywords are "required", "notnull" or "notempty", "unique". They map into equivalent validators but (at this time) should only be used with string and text types.</li>
<li>The keywords "html" and "wiki" force a text type and set a representation for the field value as sanitized HTML and MARKMIN resepectively.</li>
<li>string, integer and reference fields can be "multiple", i.e. multiple values will be allowed</li>
<li>For the "auth_user" table do not add attributes to the default fields (username, first_name, last_name, password and email). They are handled automatically.</li>
<li>Some fields will be added automatically upon creation and handled automatically: "created_by", "created_on", "modified_by", "modified_on", "active" (only active fields can be selected).</li>
<li>For every table "table" another table "table_archive" is created and it contains the previous versions of each record. This is only accessible via appadmin or programmatically.</li>
</ul>
{{elif request.function=='step4':}}
<ul>
<li>List the names of the pages you want to create.</li>
<li>Some pages are listed automatically because they expose Create/Read/Update/Delete for each tables you have created.</li>
<li>All pages, except "error" and those with name starting in underscore willbe listed in the menu. You will be able to edit the menu later.</li>
<li>You should have page "index", the starting point of your app, and page "error", where web2py will redirect to in case of error.</li>
</ul>
{{elif request.function=='step5':}}
<ul>
<li>Use the markmin syntax to add text to your pages.</li>
</ul>
{{elif request.function=='step6':}}
<ul>
<li>Almost done. Click on the button above to create your new app.</li>
<li>Once done you will be able to edit it as any normal web2py app.</li>
</ul>
{{pass}}
</div>
</div>
</div>
<script type="text/javascript">
//jQuery(document).ready(function() {
//jQuery(":input:visible:enabled:first").focus();
//});
</script>
<!-- end "step" block -->
+81 -4
View File
@@ -11,6 +11,11 @@ import copy
import gluon.contenttype
import gluon.fileutils
try:
import pygraphviz as pgv
except ImportError:
pgv = None
response.subtitle = 'Database Administration (appadmin)'
# ## critical --- make a copy of the environment
@@ -396,12 +401,13 @@ def ccache():
if value[0] < ram['oldest']:
ram['oldest'] = value[0]
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
locker = open(os.path.join(request.folder,
'cache/cache.lock'), 'a')
folder = os.path.join(request.folder,'cache')
if not os.path.exists(folder):
os.mkdir(folder)
locker = open(os.path.join(folder, 'cache.lock'), 'a')
portalocker.lock(locker, portalocker.LOCK_EX)
disk_storage = shelve.open(
os.path.join(request.folder, 'cache/cache.shelve'))
os.path.join(folder, 'cache.shelve'))
try:
for key, value in disk_storage.items():
if isinstance(value, dict):
@@ -459,3 +465,74 @@ def ccache():
return dict(form=form, total=total,
ram=ram, disk=disk, object_stats=hp != False)
def table_template(table):
from gluon.html import TR, TD, TABLE, TAG
def FONT(*args, **kwargs):
return TAG.font(*args, **kwargs)
def types(field):
f_type = field.type
if not isinstance(f_type,str):
return ' '
elif f_type == 'string':
return field.length
elif f_type == 'id':
return B('pk')
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
return B('fk')
else:
return ' '
# This is horribe HTML but the only one graphiz understands
rows = []
cellpadding = 4
color = "#000000"
bgcolor = "#FFFFFF"
face = "Helvetica"
face_bold = "Helvetica Bold"
border = 0
rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor),
_colspan=3, _cellpadding=cellpadding,
_align="center", _bgcolor=color)))
for row in db[table]:
rows.append(TR(TD(FONT(row.name, _color=color, _face=face_bold),
_align="left", _cellpadding=cellpadding,
_border=border),
TD(FONT(row.type, _color=color, _face=face),
_align="left", _cellpadding=cellpadding,
_border=border),
TD(FONT(types(row), _color=color, _face=face),
_align="center", _cellpadding=cellpadding,
_border=border)))
return "< %s >" % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1,
_cellborder=0, _cellspacing=0)
).xml()
def bg_graph_model():
graph = pgv.AGraph(layout='dot', directed=True, strict=False, rankdir='LR')
for tablename in db.tables:
graph.add_node(tablename, name=tablename, shape='plaintext',
label=table_template(tablename))
for tablename in db.tables:
for field in db[tablename]:
f_type = field.type
if isinstance(f_type,str) and (
f_type.startswith('reference') or
f_type.startswith('list:reference')):
referenced_table = f_type.split()[1].split('.')[0]
n1 = graph.get_node(tablename)
n2 = graph.get_node(referenced_table)
graph.add_edge(n1, n2, color="#4C4C4C", label='')
graph.layout()
return graph.draw(format='png', prog='dot')
def graph_model():
return dict(databases=databases, pgv=pgv)
@@ -1,3 +1,4 @@
def hello1():
""" simple page without template """
@@ -99,7 +100,7 @@ def rss_aggregator():
pubDate=datetime.datetime.now()) for entry in
d.entries])
response.headers['Content-Type'] = 'application/rss+xml'
return rss2.dumps(rss)
return rss.to_xml(encoding='utf-8')
def ajaxwiki():
@@ -7,6 +7,7 @@
- [[User Voice http://web2py.uservoice.com/ popup]]
#### Learning and Demos
- [[Intro video http://www.youtube.com/watch?v=BXzqmHx6edY]] and [[code examples https://github.com/mjhea0/web2py]]
- [[Killer Web Development Tutorial http://killer-web-development.com/]]
- [[Admin Demo http://www.web2py.com/demo_admin popup]] (web-based IDE)
- [[Welcome App Demo http://www.web2py.com/welcome]] (scaffolding application)
+6 -2
View File
@@ -61,7 +61,7 @@ input[type=text],input[type=password],select{width:300px; margin-right:5px}
border-top:1px #DEDEDE solid;
}
.header {
// background:<fill here for header image>;
/* background:<fill here for header image>; */
}
@@ -115,6 +115,10 @@ div.flash {
z-index:2000;
}
div.flash #closeflash{color:inherit; float:right; margin-left:15px;}
.ie-lte7 div.flash #closeflash
{color:expression(this.parentNode.currentStyle['color']);float:none;position:absolute;right:4px;}
div.flash:hover { opacity:0.25; }
div.error_wrapper {display:block}
@@ -182,7 +186,7 @@ div.error {
* will look better with the declarations below
* if needed to remove base.css consider keeping these following lines in some css file.
*/
// .web2py_table {border:1px solid #ccc}
/* .web2py_table {border:1px solid #ccc} */
.web2py_paginator {}
.web2py_grid {width:100%}
.web2py_grid table {width:100%}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+17 -4
View File
@@ -50,12 +50,19 @@ function web2py_event_handlers() {
window.location = redirect;
};
});
doc.ajaxError(function(e, xhr, settings, exception) {
doc.off('click', '.flash')
switch(xhr.status){
case 500:
$('.flash').html(ajax_error_500).slideDown();
}
});
};
jQuery(function() {
var flash = jQuery('.flash');
flash.hide();
if(flash.html()) flash.append('<span style="float:right;">&times;</span>').slideDown();
if(flash.html()) flash.append('<span id="closeflash">&times;</span>').slideDown();
web2py_ajax_init(document);
web2py_event_handlers();
});
@@ -102,15 +109,20 @@ function web2py_ajax_page(method, action, data, target) {
web2py_ajax_init('#'+target);
if(command)
eval(decodeURIComponent(command));
if(flash)
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
if(flash) {
jQuery('.flash')
.html(decodeURIComponent(flash))
.append('<span id="closeflash">&times;</span>')
.slideDown();
}
}
});
}
function web2py_component(action, target, timeout, times){
jQuery(function(){
var element = jQuery("#" + target).get(0);
var jelement = jQuery("#" + target);
var element = jelement.get(0);
var statement = "jQuery('#" + target + "').get(0).reload();";
element.reload = function (){
// Continue if times is Infinity or
@@ -119,6 +131,7 @@ function web2py_component(action, target, timeout, times){
web2py_ajax_page('get', action, null, target);} }; // reload
// Method to check timing limit
element.reload_check = function (){
if (jelement.hasClass('w2p_component_stop')) {return false;}
if (this.reload_counter == Infinity){return true;}
else {
if (!isNaN(this.reload_counter)){
+24 -13
View File
@@ -2,7 +2,7 @@
<script><!--
jQuery(document).ready(function(){
jQuery("table.sortable tbody tr").mouseover( function() {
jQuery(this).addClass("highlight"); }).mouseout( function() {
jQuery(this).addClass("highlight"); }).mouseout( function() {
jQuery(this).removeClass("highlight"); });
jQuery('table.sortable tbody tr:odd').addClass('odd');
jQuery('table.sortable tbody tr:even').addClass('even');
@@ -63,11 +63,11 @@
<br/><br/>
<h4>{{=T("%s selected", nrows)}}</h4>
{{if start>0:}}{{=A(T('previous 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start-100)),_class="btn")}}{{pass}}
{{if stop<nrows:}}{{=A(T('next 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start+100)),_class="btn")}}{{pass}}
{{if stop<nrows:}}{{=A(T('next 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start+100)),_class="btn")}}{{pass}}
{{if rows:}}
<div style="overflow: auto;" width="80%">
{{linkto=URL('update',args=request.args[0])}}
{{upload=URL('download',args=request.args[0])}}
{{upload=URL('download',args=request.args[0])}}
{{=SQLTABLE(rows,linkto,upload,orderby=True,_class='sortable')}}
</div>
{{pass}}
@@ -75,7 +75,7 @@
<a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}" class="btn">{{=T("export as csv file")}}</a>
{{=formcsv or ''}}
{{elif request.function=='insert':}}
{{elif request.function=='insert':}}
<h2>{{=T("Database")}} {{=A(request.args[0],_href=URL('index'))}}
{{if hasattr(table,'_primarykey'):}}
{{fieldname=table._primarykey[0]}}
@@ -83,7 +83,7 @@
{{tablename=request.args[1]}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}}
{{else:}}
{{else:}}
{{=T("Table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}}
{{pass}}
</h2>
@@ -95,7 +95,7 @@
{{fieldname=request.vars.keys()[0]}}
{{dbname=request.args[0]}}
{{tablename=request.args[1]}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}}
{{=T("Record")}} {{=A('%s=%s'%request.vars.items()[0],_href=URL('update',args=request.args[:2],vars=request.vars))}}
{{else:}}
@@ -131,7 +131,7 @@
dict(ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
</p>
<p>
{{=T("Size of cache:")}}
{{=T("Size of cache:")}}
{{if object_stats:}}
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict(items=total['objects'], bytes=total['bytes']))}}
{{if total['bytes'] > 524287:}}
@@ -151,7 +151,7 @@
</div>
<br />
{{pass}}
<h4>{{=T("RAM")}}</h4>
<p>{{=T.M("Number of entries: **%s**", ram['entries'])}}</p>
{{if ram['entries'] > 0:}}
@@ -179,16 +179,16 @@
</div>
<br />
{{pass}}
<h4>{{=T("DISK")}}</h4>
<p>{{=T.M("Number of entries: **%s**", disk['entries'])}}</p>
{{if disk['entries'] > 0:}}
<p>
{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}}
dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}}
</p>
<p>
{{=T("Size of cache:")}}
{{=T("Size of cache:")}}
{{if object_stats:}}
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict( items=disk['objects'], bytes=disk['bytes']))}}
{{if disk['bytes'] > 524287:}}
@@ -209,11 +209,11 @@
<br />
{{pass}}
</div>
<div class="list-header">
<h3>{{=T("Manage Cache")}}</h3>
</div>
<div class="content">
<p>
{{=form}}
@@ -222,3 +222,14 @@
</div>
<div class="clear"></div>
{{pass}}
{{if request.function=='graph_model':}}
<h2>{{=T("Graph Model")}}</h2>
{{if not pgv:}}
{{=T('pygraphviz library not found')}}
{{elif not databases:}}
{{=T("No databases in this application")}}
{{else:}}
{{=IMG(_src=URL('appadmin', 'bg_graph_model'))}}
{{pass}}
{{pass}}
@@ -368,7 +368,7 @@ db.define_table(
db.define_table(
'product',
Field('seller_id',db_person),
Field('seller_id',db.person),
Field('name'),
Field('description', 'text'),
Field('picture', 'upload', default=''),
@@ -383,9 +383,7 @@ db.define_table(
Field('quantity', 'integer'),
format = '%(quantity)s %(product_id)s -> %(buyer_id)s')
purchased = \
(db.person.id==db.purchase.buyer_id)&\
(db.product.id==db.purchase.product_id)
purchased = (db.person.id==db.purchase.buyer_id)&(db.product.id==db.purchase.product_id)
db.person.name.requires = IS_NOT_EMPTY()
db.person.email.requires = [IS_EMAIL(), IS_NOT_IN_DB(db, 'person.email')]
+2 -2
View File
@@ -21,7 +21,7 @@
Please also send us a signed copy by fax or, scanned, by email.
<p/>
<h3>
Main Contributors
Main Contributors/Developers
</h3>
<ul>
<li>Alexey Nezhdanov (GAE and database performance)
@@ -106,7 +106,7 @@
</li><li>Olaf Ferger (Informix support)
</li><li>Omi Chiba (DB2, MSSQL support and Japanese translation)
</li><li>Ondrej Such (MSSQL support)
</li><li>Ovidio Marinho Falcao Neto (tests and plugins)
</li><li>Ovidio Marinho Falcao Neto (tests and plugin developer)
</li><li>Pai (internationalization)
</li><li>Paolo Caruccio (SQLFORM.grid query)
</li><li>Patrick Breitenbach
@@ -0,0 +1,9 @@
{{extend 'layout.html'}}
<h2>form.vars</h2>
<pre>{{=vars}}</pre>
<h2>form</h2>
{{=form}}
@@ -3,6 +3,7 @@
var w2p_ajax_confirm_message = "{{=T('Are you sure you want to delete this object?')}}";
var w2p_ajax_date_format = "{{=T('%Y-%m-%d')}}";
var w2p_ajax_datetime_format = "{{=T('%Y-%m-%d %H:%M:%S')}}";
var ajax_error_500 = '{{=XML(T('An error occured, please %s the page') % A(T('reload'), _href=URL(args=request.args, vars=request.vars))) }}'
//--></script>
{{
response.files.insert(0,URL('static','js/jquery.js'))
+81 -4
View File
@@ -11,6 +11,11 @@ import copy
import gluon.contenttype
import gluon.fileutils
try:
import pygraphviz as pgv
except ImportError:
pgv = None
response.subtitle = 'Database Administration (appadmin)'
# ## critical --- make a copy of the environment
@@ -396,12 +401,13 @@ def ccache():
if value[0] < ram['oldest']:
ram['oldest'] = value[0]
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
locker = open(os.path.join(request.folder,
'cache/cache.lock'), 'a')
folder = os.path.join(request.folder,'cache')
if not os.path.exists(folder):
os.mkdir(folder)
locker = open(os.path.join(folder, 'cache.lock'), 'a')
portalocker.lock(locker, portalocker.LOCK_EX)
disk_storage = shelve.open(
os.path.join(request.folder, 'cache/cache.shelve'))
os.path.join(folder, 'cache.shelve'))
try:
for key, value in disk_storage.items():
if isinstance(value, dict):
@@ -459,3 +465,74 @@ def ccache():
return dict(form=form, total=total,
ram=ram, disk=disk, object_stats=hp != False)
def table_template(table):
from gluon.html import TR, TD, TABLE, TAG
def FONT(*args, **kwargs):
return TAG.font(*args, **kwargs)
def types(field):
f_type = field.type
if not isinstance(f_type,str):
return ' '
elif f_type == 'string':
return field.length
elif f_type == 'id':
return B('pk')
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
return B('fk')
else:
return ' '
# This is horribe HTML but the only one graphiz understands
rows = []
cellpadding = 4
color = "#000000"
bgcolor = "#FFFFFF"
face = "Helvetica"
face_bold = "Helvetica Bold"
border = 0
rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor),
_colspan=3, _cellpadding=cellpadding,
_align="center", _bgcolor=color)))
for row in db[table]:
rows.append(TR(TD(FONT(row.name, _color=color, _face=face_bold),
_align="left", _cellpadding=cellpadding,
_border=border),
TD(FONT(row.type, _color=color, _face=face),
_align="left", _cellpadding=cellpadding,
_border=border),
TD(FONT(types(row), _color=color, _face=face),
_align="center", _cellpadding=cellpadding,
_border=border)))
return "< %s >" % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1,
_cellborder=0, _cellspacing=0)
).xml()
def bg_graph_model():
graph = pgv.AGraph(layout='dot', directed=True, strict=False, rankdir='LR')
for tablename in db.tables:
graph.add_node(tablename, name=tablename, shape='plaintext',
label=table_template(tablename))
for tablename in db.tables:
for field in db[tablename]:
f_type = field.type
if isinstance(f_type,str) and (
f_type.startswith('reference') or
f_type.startswith('list:reference')):
referenced_table = f_type.split()[1].split('.')[0]
n1 = graph.get_node(tablename)
n2 = graph.get_node(referenced_table)
graph.add_edge(n1, n2, color="#4C4C4C", label='')
graph.layout()
return graph.draw(format='png', prog='dot')
def graph_model():
return dict(databases=databases, pgv=pgv)
+1
View File
@@ -0,0 +1 @@
#crontab
+1 -1
View File
@@ -11,7 +11,7 @@
if not request.env.web2py_runtime_gae:
## if NOT running on Google App Engine use SQLite or other DB
db = DAL('sqlite://storage.sqlite')
db = DAL('sqlite://storage.sqlite',pool_size=1,check_reserved=['all'])
else:
## connect to Google BigTable (optional 'google:datastore://namespace')
db = DAL('google:datastore')
+5 -2
View File
@@ -5,6 +5,8 @@
## Customize your APP title, subtitle and menus here
#########################################################################
response.logo = A(B('web',SPAN(2),'py'),XML('&trade;&nbsp;'),
_class="brand",_href="http://www.web2py.com/")
response.title = ' '.join(
word.capitalize() for word in request.application.split('_'))
response.subtitle = T('customize me!')
@@ -26,11 +28,12 @@ response.menu = [
(T('Home'), False, URL('default', 'index'), [])
]
DEVELOPMENT_MENU = True
#########################################################################
## provide shortcuts for development. remove in production
#########################################################################
def _():
# shortcuts
app = request.application
@@ -133,4 +136,4 @@ def _():
])
]
)]
_()
if DEVELOPMENT_MENU: _()
+1
View File
@@ -0,0 +1 @@
403
+1
View File
@@ -0,0 +1 @@
404
+1
View File
@@ -0,0 +1 @@
500
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -115,6 +115,10 @@ div.flash {
z-index:2000;
}
div.flash #closeflash{color:inherit; float:right; margin-left:15px;}
.ie-lte7 div.flash #closeflash
{color:expression(this.parentNode.currentStyle['color']);float:none;position:absolute;right:4px;}
div.flash:hover { opacity:0.25; }
div.error_wrapper {display:block}
@@ -1,5 +1,5 @@
/*=============================================================
CUSTOM RULES
CUSTOM RULES
==============================================================*/
body{height:auto;} /* to avoid vertical scroll bar */
@@ -39,7 +39,7 @@ div.flash.flash-top,div.flash.flash-top:hover{
/* auth navbar - primitive style */
.auth_navbar,.auth_navbar a{color:inherit;}
.ie-lte7 .auth_navbar,.auth_navbar a{color:expression(this.parentNode.currentStyle['color']); /* ie7 doesn't support inherit */}
.auth_navbar a{white-space:nowrap;} /* to avoid the nav split on more lines */
.auth_navbar a{white-space:nowrap;} /* to avoid the nav split on more lines */
.auth_navbar a:hover{color:white;text-decoration:none;}
ul#navbar>.auth_navbar{
display:inline-block;
@@ -51,7 +51,7 @@ div.error_wrapper .error{
border-radius: 4px;
-o-border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
-webkit-border-radius: 4px;
}
/* below rules are only for formstyle = bootstrap
trying to make errors look like bootstrap ones */
@@ -67,10 +67,13 @@ div.controls .error{
border:none;
padding:0;
margin:0;
//display:inline; /* uncommenting this, the animation effect is lost */
/*display:inline;*/ /* uncommenting this, the animation effect is lost */
}
div.controls .inline-help{color:#3A87AD;}
div.controls .error_wrapper+.inline-help{margin-left:-99999px;}
div.controls .help-inline{color:#3A87AD;}
div.controls .error_wrapper +.help-inline {margin-left:-99999px;}
div.controls select +.error_wrapper {margin-left:5px;}
.ie-lte7 div.error{color:#fff;}
/* beautify brand */
.navbar-inverse .brand{color:#c6cecc;}
.navbar-inverse .brand b{display:inline-block;margin-top:-1px;}
@@ -89,13 +92,13 @@ a{white-space:normal;}
li{margin-bottom:0;}
textarea,button{display:block;}
/*reset ul padding */
ul#navbar{padding:0;}
ul#navbar{padding:0;}
/* label aligned to related input */
td.w2p_fl,td.w2p_fc {padding:0;}
#web2py_user_form td{vertical-align:middle;}
/*=============================================================
OVERRIDING BOOTSTRAP.CSS RULES
OVERRIDING BOOTSTRAP.CSS RULES
==============================================================*/
/* because web2py handles this via js */
@@ -175,9 +178,6 @@ background-repeat:repeat;
OTHER RULES
==============================================================*/
.navbar-inner{
position:relative; /*unnecessary ??*/
}
/* Massimo Di Pierro fixed alignment in forms with list:string */
form table tr{margin-bottom:9px;}
td.w2p_fw ul{margin-left:0px;}
@@ -189,8 +189,8 @@ td.w2p_fw ul{margin-left:0px;}
margin-bottom: 0;
vertical-align: middle;
}
.web2py_console input[type="submit"],
.web2py_console input[type="button"],
.web2py_console input[type="submit"],
.web2py_console input[type="button"],
.web2py_console button{
padding-top:4px;
padding-bottom:4px;
@@ -212,7 +212,7 @@ td.w2p_fw ul{margin-left:0px;}
@media only screen and (max-width:979px){
body{padding-top:0px;}
#navbar{bottom:-10px;left:4px;}
#navbar{top:5px;}
div.flash{right:5px;}
.dropdown-menu ul{visibility:visible;}
}
@@ -224,8 +224,8 @@ td.w2p_fw ul{margin-left:0px;}
.navbar-fixed-top,.navbar-fixed-bottom {
margin-left:-10px;
margin-right:-10px;
}
}
input[type="text"],input[type="password"],select{
width:95%;
}
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -16,7 +16,7 @@ jQuery(function(){
return match && decodeURIComponent(match[1].replace(/\+/g, ' '))||default_value;
}
var path = params('static','social');
var url = window.location.href;
var url = encodeURIComponent(window.location.href);
var host = window.location.hostname;
var title = escape(jQuery('title').text());
var twit = 'http://twitter.com/home?status='+title+'%20'+url;
@@ -27,7 +27,7 @@ jQuery(function(){
jQuery('body').append(tbar);
var st = jQuery('#socialdrawer');
st.css({'opacity':'.7','z-index':'3000','background':'#FFF','border':'solid 1px #666','border-width':' 1px 0 0 1px','height':'20px','width':'40px','position':'fixed','bottom':'0','right':'0','padding':'2px 5px','overflow':'hidden','-webkit-border-top-left-radius':' 12px','-moz-border-radius-topleft':' 12px','border-top-left-radius':' 12px','-moz-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','-webkit-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)'});
jQuery('#socialdrawer a').css({'float':'left','width':'32px','margin':'3px 2px 2px 2px','padding':'0'});
jQuery('#socialdrawer a').css({'float':'left','width':'32px','margin':'3px 2px 2px 2px','padding':'0','cursor':'pointer'});
jQuery('#socialdrawer span').css({'float':'left','margin':'2px 3px','text-shadow':' 1px 1px 1px #FFF','color':'#444','font-size':'12px','line-height':'1em'});
jQuery('#socialdrawer img').hide();
// hover
+17 -4
View File
@@ -50,12 +50,19 @@ function web2py_event_handlers() {
window.location = redirect;
};
});
doc.ajaxError(function(e, xhr, settings, exception) {
doc.off('click', '.flash')
switch(xhr.status){
case 500:
$('.flash').html(ajax_error_500).slideDown();
}
});
};
jQuery(function() {
var flash = jQuery('.flash');
flash.hide();
if(flash.html()) flash.append('<span style="float:right;">&times;</span>').slideDown();
if(flash.html()) flash.append('<span id="closeflash">&times;</span>').slideDown();
web2py_ajax_init(document);
web2py_event_handlers();
});
@@ -102,15 +109,20 @@ function web2py_ajax_page(method, action, data, target) {
web2py_ajax_init('#'+target);
if(command)
eval(decodeURIComponent(command));
if(flash)
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
if(flash) {
jQuery('.flash')
.html(decodeURIComponent(flash))
.append('<span id="closeflash">&times;</span>')
.slideDown();
}
}
});
}
function web2py_component(action, target, timeout, times){
jQuery(function(){
var element = jQuery("#" + target).get(0);
var jelement = jQuery("#" + target);
var element = jelement.get(0);
var statement = "jQuery('#" + target + "').get(0).reload();";
element.reload = function (){
// Continue if times is Infinity or
@@ -119,6 +131,7 @@ function web2py_component(action, target, timeout, times){
web2py_ajax_page('get', action, null, target);} }; // reload
// Method to check timing limit
element.reload_check = function (){
if (jelement.hasClass('w2p_component_stop')) {return false;}
if (this.reload_counter == Infinity){return true;}
else {
if (!isNaN(this.reload_counter)){
+24 -13
View File
@@ -2,7 +2,7 @@
<script><!--
jQuery(document).ready(function(){
jQuery("table.sortable tbody tr").mouseover( function() {
jQuery(this).addClass("highlight"); }).mouseout( function() {
jQuery(this).addClass("highlight"); }).mouseout( function() {
jQuery(this).removeClass("highlight"); });
jQuery('table.sortable tbody tr:odd').addClass('odd');
jQuery('table.sortable tbody tr:even').addClass('even');
@@ -63,11 +63,11 @@
<br/><br/>
<h4>{{=T("%s selected", nrows)}}</h4>
{{if start>0:}}{{=A(T('previous 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start-100)),_class="btn")}}{{pass}}
{{if stop<nrows:}}{{=A(T('next 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start+100)),_class="btn")}}{{pass}}
{{if stop<nrows:}}{{=A(T('next 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start+100)),_class="btn")}}{{pass}}
{{if rows:}}
<div style="overflow: auto;" width="80%">
{{linkto=URL('update',args=request.args[0])}}
{{upload=URL('download',args=request.args[0])}}
{{upload=URL('download',args=request.args[0])}}
{{=SQLTABLE(rows,linkto,upload,orderby=True,_class='sortable')}}
</div>
{{pass}}
@@ -75,7 +75,7 @@
<a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}" class="btn">{{=T("export as csv file")}}</a>
{{=formcsv or ''}}
{{elif request.function=='insert':}}
{{elif request.function=='insert':}}
<h2>{{=T("Database")}} {{=A(request.args[0],_href=URL('index'))}}
{{if hasattr(table,'_primarykey'):}}
{{fieldname=table._primarykey[0]}}
@@ -83,7 +83,7 @@
{{tablename=request.args[1]}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}}
{{else:}}
{{else:}}
{{=T("Table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}}
{{pass}}
</h2>
@@ -95,7 +95,7 @@
{{fieldname=request.vars.keys()[0]}}
{{dbname=request.args[0]}}
{{tablename=request.args[1]}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}}
{{=T("Record")}} {{=A('%s=%s'%request.vars.items()[0],_href=URL('update',args=request.args[:2],vars=request.vars))}}
{{else:}}
@@ -131,7 +131,7 @@
dict(ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
</p>
<p>
{{=T("Size of cache:")}}
{{=T("Size of cache:")}}
{{if object_stats:}}
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict(items=total['objects'], bytes=total['bytes']))}}
{{if total['bytes'] > 524287:}}
@@ -151,7 +151,7 @@
</div>
<br />
{{pass}}
<h4>{{=T("RAM")}}</h4>
<p>{{=T.M("Number of entries: **%s**", ram['entries'])}}</p>
{{if ram['entries'] > 0:}}
@@ -179,16 +179,16 @@
</div>
<br />
{{pass}}
<h4>{{=T("DISK")}}</h4>
<p>{{=T.M("Number of entries: **%s**", disk['entries'])}}</p>
{{if disk['entries'] > 0:}}
<p>
{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}}
dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}}
</p>
<p>
{{=T("Size of cache:")}}
{{=T("Size of cache:")}}
{{if object_stats:}}
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict( items=disk['objects'], bytes=disk['bytes']))}}
{{if disk['bytes'] > 524287:}}
@@ -209,11 +209,11 @@
<br />
{{pass}}
</div>
<div class="list-header">
<h3>{{=T("Manage Cache")}}</h3>
</div>
<div class="content">
<p>
{{=form}}
@@ -222,3 +222,14 @@
</div>
<div class="clear"></div>
{{pass}}
{{if request.function=='graph_model':}}
<h2>{{=T("Graph Model")}}</h2>
{{if not pgv:}}
{{=T('pygraphviz library not found')}}
{{elif not databases:}}
{{=T("No databases in this application")}}
{{else:}}
{{=IMG(_src=URL('appadmin', 'bg_graph_model'))}}
{{pass}}
{{pass}}

Some files were not shown because too many files have changed in this diff Show More