Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edcc2e44dc | ||
|
|
2cf9f26b0d | ||
|
|
4b99b6fdd7 | ||
|
|
622430583f | ||
|
|
89cc5a5f70 | ||
|
|
6899154fcd | ||
|
|
47c0e461f1 | ||
|
|
93237837ed | ||
|
|
cf20ce5fae | ||
|
|
04c86f07ef | ||
|
|
1a12c4011b | ||
|
|
85bbe15758 | ||
|
|
5816481a44 | ||
|
|
2675e9d229 | ||
|
|
41498917d5 | ||
|
|
8f7acd8154 | ||
|
|
26865421b6 | ||
|
|
b9ee4d4730 | ||
|
|
8fd7a27d5f | ||
|
|
69231bdd7f | ||
|
|
55dfb9e8c4 | ||
|
|
7761219cba | ||
|
|
e31e4e236f | ||
|
|
a43d822412 | ||
|
|
f94bc250eb | ||
|
|
5775d2788d | ||
|
|
048f275076 | ||
|
|
8078d4b0f3 | ||
|
|
5ee8c9c930 | ||
|
|
6659bc0793 | ||
|
|
d7caaf04cc | ||
|
|
e95115deb4 | ||
|
|
42c69b6343 | ||
|
|
d2347dec41 | ||
|
|
8420020c21 | ||
|
|
571fc6d919 | ||
|
|
52ec228eeb | ||
|
|
5848d9acaa | ||
|
|
3e8cbd5a0d | ||
|
|
e276cc2fc1 | ||
|
|
39a048db61 | ||
|
|
df4b896334 | ||
|
|
6d58845153 | ||
|
|
ba1f8bf741 | ||
|
|
a378ab3e51 | ||
|
|
2d866647e2 | ||
|
|
81863d69c9 | ||
|
|
ee2879442f | ||
|
|
ad68d2415d | ||
|
|
928de67f8d | ||
|
|
68296f9e65 | ||
|
|
7ac6edae52 | ||
|
|
1fc90fdb6d | ||
|
|
34a9d72cde | ||
|
|
198ce939d0 | ||
|
|
e31a099cb3 | ||
|
|
cc7e10d216 | ||
|
|
d8b68036c2 | ||
|
|
f9cd7e4ef4 | ||
|
|
896b45b838 | ||
|
|
d6146c9c5d | ||
|
|
b3be806244 | ||
|
|
eac12d3a57 | ||
|
|
2fc081bc3c | ||
|
|
032af7c04d | ||
|
|
8e63825def | ||
|
|
5d2e5dded3 | ||
|
|
61e33da844 | ||
|
|
da9dbaa5d6 | ||
|
|
7543c54bdb | ||
|
|
00608e4f04 | ||
|
|
cdbf48f09b | ||
|
|
f39db6331a | ||
|
|
ef433da190 | ||
|
|
d2375b4187 | ||
|
|
26d87967c5 | ||
|
|
044b2331c3 | ||
|
|
c89614ada6 | ||
|
|
f0aba167b4 | ||
|
|
bde9562b78 | ||
|
|
9a1229470a | ||
|
|
f781b9e1f5 | ||
|
|
fa32b7577b | ||
|
|
68526a0c6d | ||
|
|
ad2003c618 | ||
|
|
c1ecf823d8 | ||
|
|
6134f82452 | ||
|
|
fbb5a8b9bb | ||
|
|
df34869d65 | ||
|
|
28e6999e7d | ||
|
|
f4f77b0cb6 | ||
|
|
23ddb6c3c2 | ||
|
|
b636a5d6e9 | ||
|
|
efc392966e | ||
|
|
cffa59a80c | ||
|
|
82a1b9f628 | ||
|
|
94d2f1453d | ||
|
|
a1875ee362 | ||
|
|
5f13dca712 | ||
|
|
f78d423c92 | ||
|
|
f60ae809b6 | ||
|
|
34dd8af101 | ||
|
|
6bf6ebab1b | ||
|
|
29bf50425b | ||
|
|
8a7612c976 | ||
|
|
97489fd277 | ||
|
|
b86184fe58 | ||
|
|
2ce53e9957 | ||
|
|
d61c372c95 | ||
|
|
73e176365f | ||
|
|
33f12d91a5 | ||
|
|
d0f1286f03 | ||
|
|
04d698109e | ||
|
|
0e9c5caf4d | ||
|
|
509b0a6987 | ||
|
|
e0074ebcac | ||
|
|
918fdf2f0c | ||
|
|
8e827f7a09 | ||
|
|
cf2d5b637b | ||
|
|
236fdcfafc | ||
|
|
ce0f83d00c | ||
|
|
156d771ab3 | ||
|
|
01474c99b0 | ||
|
|
66d15491ca | ||
|
|
376a27da73 | ||
|
|
0f95c13dc7 | ||
|
|
a2e7794b92 | ||
|
|
926de90ee4 | ||
|
|
538f375284 | ||
|
|
4c61c0962d | ||
|
|
9b71646fc5 | ||
|
|
1e66fa3a93 | ||
|
|
57a8dfe034 | ||
|
|
77e7631740 | ||
|
|
ba978d55cf | ||
|
|
12e8ee5c25 | ||
|
|
d293e98b43 | ||
|
|
4f316d0294 | ||
|
|
81e15879d4 | ||
|
|
cd1d6c5af1 | ||
|
|
c7d3758c77 | ||
|
|
040e52278e | ||
|
|
3daf953c66 | ||
|
|
de3d722ac9 | ||
|
|
ff10eab373 | ||
|
|
eb4d159b37 | ||
|
|
5ef7a8e9a1 | ||
|
|
76cfba7047 | ||
|
|
f77f307869 | ||
|
|
5ef8648929 | ||
|
|
ed042685ea | ||
|
|
d09ce57f12 | ||
|
|
169818b275 | ||
|
|
4b14a87463 | ||
|
|
cadf38b4f6 | ||
|
|
a6226d6391 | ||
|
|
5c167907eb | ||
|
|
587ff56a94 | ||
|
|
6f91fdd833 | ||
|
|
6e2f9ad043 | ||
|
|
cdca2793e0 | ||
|
|
a0ee649884 | ||
|
|
380b491724 | ||
|
|
f45bf73992 | ||
|
|
94461724f6 | ||
|
|
c36c391786 | ||
|
|
f6db7c995f | ||
|
|
ccc4b96709 | ||
|
|
71b02e3044 | ||
|
|
99fb1c3010 | ||
|
|
20067d7b93 | ||
|
|
44eb35c617 | ||
|
|
df03317054 | ||
|
|
9d873cbd1c | ||
|
|
1bb4117cbd | ||
|
|
e834186a86 | ||
|
|
1394942feb | ||
|
|
32b9b5c799 | ||
|
|
340d7b5e6f | ||
|
|
302f56ecc1 | ||
|
|
9b12459a82 | ||
|
|
8e3925820c | ||
|
|
279d71d4cd | ||
|
|
258e2e57ae | ||
|
|
9357d810d8 | ||
|
|
54b385b321 | ||
|
|
df039e734c | ||
|
|
77f154a56b | ||
|
|
842207ab33 | ||
|
|
c58f29bb9c | ||
|
|
0b0f82b514 | ||
|
|
3ab8a7bfd6 | ||
|
|
c5a9d2c456 |
No files matched your search
@@ -58,3 +58,4 @@ HOWTO-web2py-devel
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
.idea/*
|
||||
site-packages/
|
||||
+2
-2
@@ -17,14 +17,14 @@ install:
|
||||
before_script:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install --download-cache $HOME/.pip-cache unittest2; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install --download-cache $HOME/.pip-cache coverage; fi;
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install --download-cache $HOME/.pip-cache python-coveralls; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install --download-cache $HOME/.pip-cache codecov; fi
|
||||
|
||||
|
||||
script: export COVERAGE_PROCESS_START=gluon/tests/coverage.ini; ./web2py.py --run_system_tests --with_coverage
|
||||
|
||||
after_success:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then coverage combine; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then coveralls --config_file=gluon/tests/coverage.ini; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then codecov; fi
|
||||
|
||||
notifications:
|
||||
email: true
|
||||
@@ -1,3 +1,25 @@
|
||||
## 2.12.1
|
||||
|
||||
- security fix: Validate for open redirect everywhere, not just in login()
|
||||
- allow to pack invidual apps and selected files as packed exe files
|
||||
- allow bulk user registration with default bulk_register_enabled=False
|
||||
- allow unsorted multiword query in grid search
|
||||
- better MongoDB support with newer pyDAL
|
||||
- enable <app>/appadmin/manage/auth by default for user admin
|
||||
- allow mail.settings.server='logging:filename' to log emails to a file
|
||||
- better caching logic
|
||||
- fixed order of confirm-password field
|
||||
- TLS support in ldap
|
||||
- prettydate can do UTC
|
||||
- jquery 1.11.3
|
||||
- bootstrap 3.3.5
|
||||
- moved to codecov and enabled appveyor
|
||||
- many bug fixes
|
||||
|
||||
## 2.11.1
|
||||
|
||||
- Many small but significative improvements and bug fixes
|
||||
|
||||
## 2.10.1-2.10.2
|
||||
|
||||
- welcome app defaults to Bootstrap 3
|
||||
|
||||
@@ -32,7 +32,7 @@ update:
|
||||
echo "remember that pymysql was tweaked"
|
||||
src:
|
||||
### Use semantic versioning
|
||||
echo 'Version 2.10.4-beta+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
||||
echo 'Version 2.12.3-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
||||
### rm -f all junk files
|
||||
make clean
|
||||
### clean up baisc apps
|
||||
|
||||
+4
-3
@@ -13,7 +13,7 @@ Learn more at http://web2py.com
|
||||
|
||||
Then edit ./app.yaml and replace "yourappname" with yourappname.
|
||||
|
||||
## Import about this GIT repo
|
||||
## Important reminder about this GIT repo
|
||||
|
||||
An important part of web2py is the Database Abstraction Layer (DAL). In early 2015 this was decoupled into a separate code-base (PyDAL). In terms of git, it is a sub-module of the main repository.
|
||||
|
||||
@@ -38,9 +38,10 @@ PyDAL uses a separate stable release cycle to the rest of web2py. PyDAL releases
|
||||
|
||||
## Tests
|
||||
|
||||
[](https://travis-ci.org/web2py/web2py)
|
||||
[](https://travis-ci.org/web2py/web2py)
|
||||
[](https://ci.appveyor.com/project/web2py/web2py)
|
||||
[](https://codecov.io/github/web2py/web2py)
|
||||
|
||||
[](https://coveralls.io/r/web2py/web2py)
|
||||
|
||||
## Installation Instructions
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
Version 2.10.4-stable+timestamp.2015.04.26.09.05.21
|
||||
Version 2.12.3-stable+timestamp.2015.08.18.19.14.07
|
||||
@@ -49,7 +49,8 @@ if request.function == 'manage':
|
||||
auth.table_group(),
|
||||
auth.table_permission()])
|
||||
manager_role = manager_action.get('role', None) if manager_action else None
|
||||
auth.requires_membership(manager_role)(lambda: None)()
|
||||
if not (gluon.fileutils.check_credentials(request) or auth.has_membership(manager_role)):
|
||||
raise HTTP(403, "Not authorized")
|
||||
menu = False
|
||||
elif (request.application == 'admin' and not session.authorized) or \
|
||||
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
|
||||
@@ -80,7 +81,6 @@ if False and request.tickets_db:
|
||||
def get_databases(request):
|
||||
dbs = {}
|
||||
for (key, value) in global_env.items():
|
||||
cond = False
|
||||
try:
|
||||
cond = isinstance(value, GQLDB)
|
||||
except:
|
||||
@@ -445,30 +445,31 @@ def ccache():
|
||||
gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age'])
|
||||
total.update(gae_stats)
|
||||
else:
|
||||
# get ram stats directly from the cache object
|
||||
ram_stats = cache.ram.stats[request.application]
|
||||
ram['hits'] = ram_stats['hit_total'] - ram_stats['misses']
|
||||
ram['misses'] = ram_stats['misses']
|
||||
try:
|
||||
ram['ratio'] = ram['hits'] * 100 / ram_stats['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
ram['ratio'] = 0
|
||||
|
||||
for key, value in cache.ram.storage.iteritems():
|
||||
if isinstance(value, dict):
|
||||
ram['hits'] = value['hit_total'] - value['misses']
|
||||
ram['misses'] = value['misses']
|
||||
try:
|
||||
ram['ratio'] = ram['hits'] * 100 / value['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
ram['ratio'] = 0
|
||||
else:
|
||||
if hp:
|
||||
ram['bytes'] += hp.iso(value[1]).size
|
||||
ram['objects'] += hp.iso(value[1]).count
|
||||
ram['entries'] += 1
|
||||
if value[0] < ram['oldest']:
|
||||
ram['oldest'] = value[0]
|
||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
if hp:
|
||||
ram['bytes'] += hp.iso(value[1]).size
|
||||
ram['objects'] += hp.iso(value[1]).count
|
||||
ram['entries'] += 1
|
||||
if value[0] < ram['oldest']:
|
||||
ram['oldest'] = value[0]
|
||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
|
||||
for key in cache.disk.storage:
|
||||
value = cache.disk.storage[key]
|
||||
if isinstance(value, dict):
|
||||
disk['hits'] = value['hit_total'] - value['misses']
|
||||
disk['misses'] = value['misses']
|
||||
if isinstance(value[1], dict):
|
||||
disk['hits'] = value[1]['hit_total'] - value[1]['misses']
|
||||
disk['misses'] = value[1]['misses']
|
||||
try:
|
||||
disk['ratio'] = disk['hits'] * 100 / value['hit_total']
|
||||
disk['ratio'] = disk['hits'] * 100 / value[1]['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
disk['ratio'] = 0
|
||||
else:
|
||||
@@ -480,12 +481,12 @@ def ccache():
|
||||
disk['oldest'] = value[0]
|
||||
disk['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
|
||||
total['entries'] = ram['entries'] + disk['entries']
|
||||
total['bytes'] = ram['bytes'] + disk['bytes']
|
||||
total['objects'] = ram['objects'] + disk['objects']
|
||||
total['hits'] = ram['hits'] + disk['hits']
|
||||
total['misses'] = ram['misses'] + disk['misses']
|
||||
total['keys'] = ram['keys'] + disk['keys']
|
||||
ram_keys = ram.keys() # ['hits', 'objects', 'ratio', 'entries', 'keys', 'oldest', 'bytes', 'misses']
|
||||
ram_keys.remove('ratio')
|
||||
ram_keys.remove('oldest')
|
||||
for key in ram_keys:
|
||||
total[key] = ram[key] + disk[key]
|
||||
|
||||
try:
|
||||
total['ratio'] = total['hits'] * 100 / (total['hits'] +
|
||||
total['misses'])
|
||||
@@ -577,9 +578,7 @@ def bg_graph_model():
|
||||
group = meta_graphmodel['group'].replace(' ', '')
|
||||
if not subgraphs.has_key(group):
|
||||
subgraphs[group] = dict(meta=meta_graphmodel, tables=[])
|
||||
subgraphs[group]['tables'].append(tablename)
|
||||
else:
|
||||
subgraphs[group]['tables'].append(tablename)
|
||||
subgraphs[group]['tables'].append(tablename)
|
||||
|
||||
graph.add_node(tablename, name=tablename, shape='plaintext',
|
||||
label=table_template(tablename))
|
||||
|
||||
@@ -220,7 +220,7 @@ def list_breakpoints():
|
||||
"Return a list of linenumbers for current breakpoints"
|
||||
|
||||
breakpoints = []
|
||||
ok = None
|
||||
ok = False
|
||||
try:
|
||||
filename = os.path.join(request.env['applications_parent'],
|
||||
'applications', request.vars.filename)
|
||||
@@ -235,5 +235,4 @@ def list_breakpoints():
|
||||
ok = True
|
||||
except Exception, e:
|
||||
session.flash = str(e)
|
||||
ok = False
|
||||
return response.json({'ok': ok, 'breakpoints': breakpoints})
|
||||
@@ -292,9 +292,6 @@ def site():
|
||||
log_progress(appname)
|
||||
session.flash = T(msg, dict(appname=appname,
|
||||
digest=md5_hash(installed)))
|
||||
elif f and form_update.vars.overwrite:
|
||||
msg = 'unable to install application "%(appname)s"'
|
||||
session.flash = T(msg, dict(appname=form_update.vars.name))
|
||||
else:
|
||||
msg = 'unable to install application "%(appname)s"'
|
||||
session.flash = T(msg, dict(appname=form_update.vars.name))
|
||||
@@ -370,25 +367,56 @@ def pack_plugin():
|
||||
session.flash = T('internal error')
|
||||
redirect(URL('plugin', args=request.args))
|
||||
|
||||
|
||||
|
||||
def pack_exe(app, base, filenames=None):
|
||||
import urllib
|
||||
import zipfile
|
||||
from cStringIO import StringIO
|
||||
# Download latest web2py_win and open it with zipfile
|
||||
download_url = 'http://www.web2py.com/examples/static/web2py_win.zip'
|
||||
out = StringIO()
|
||||
out.write(urllib.urlopen(download_url).read())
|
||||
web2py_win = zipfile.ZipFile(out, mode='a')
|
||||
# Write routes.py with the application as default
|
||||
routes = u'# -*- coding: utf-8 -*-\nrouters = dict(BASE=dict(default_application="%s"))' % app
|
||||
web2py_win.writestr('web2py/routes.py', routes.encode('utf-8'))
|
||||
# Copy the application into the zipfile
|
||||
common_root = os.path.dirname(base)
|
||||
for filename in filenames:
|
||||
fname = os.path.join(base, filename)
|
||||
arcname = os.path.join('web2py/applications', app, filename)
|
||||
web2py_win.write(fname, arcname)
|
||||
web2py_win.close()
|
||||
response.headers['Content-Type'] = 'application/zip'
|
||||
response.headers['Content-Disposition'] = 'attachment; filename=web2py.app.%s.zip' % app
|
||||
out.seek(0)
|
||||
return response.stream(out)
|
||||
|
||||
|
||||
def pack_custom():
|
||||
app = get_app()
|
||||
base = apath(app, r=request)
|
||||
if request.post_vars.file:
|
||||
|
||||
files = request.post_vars.file
|
||||
files = [files] if not isinstance(files,list) else files
|
||||
fname = 'web2py.app.%s.w2p' % app
|
||||
try:
|
||||
filename = app_pack(app, request, raise_ex=True, filenames=files)
|
||||
except Exception, e:
|
||||
filename = None
|
||||
if filename:
|
||||
response.headers['Content-Type'] = 'application/w2p'
|
||||
disposition = 'attachment; filename=%s' % fname
|
||||
response.headers['Content-Disposition'] = disposition
|
||||
return safe_read(filename, 'rb')
|
||||
if request.post_vars.doexe is None:
|
||||
fname = 'web2py.app.%s.w2p' % app
|
||||
try:
|
||||
filename = app_pack(app, request, raise_ex=True, filenames=files)
|
||||
except Exception, e:
|
||||
filename = None
|
||||
if filename:
|
||||
response.headers['Content-Type'] = 'application/w2p'
|
||||
disposition = 'attachment; filename=%s' % fname
|
||||
response.headers['Content-Disposition'] = disposition
|
||||
return safe_read(filename, 'rb')
|
||||
else:
|
||||
session.flash = T('internal error: %s', e)
|
||||
redirect(URL(args=request.args))
|
||||
else:
|
||||
session.flash = T('internal error: %s', e)
|
||||
redirect(URL(args=request.args))
|
||||
return pack_exe(app, base, files)
|
||||
def ignore(fs):
|
||||
return [f for f in fs if not (
|
||||
f[:1] in '#' or f.endswith('~') or f.endswith('.bak'))]
|
||||
@@ -744,7 +772,7 @@ def edit():
|
||||
viewlist.append(aviewpath + '.html')
|
||||
if len(viewlist):
|
||||
editviewlinks = []
|
||||
for v in viewlist:
|
||||
for v in sorted(viewlist):
|
||||
vf = os.path.split(v)[-1]
|
||||
vargs = "/".join([viewpath.replace(os.sep, "/"), vf])
|
||||
editviewlinks.append(A(vf.split(".")[0],
|
||||
@@ -754,6 +782,7 @@ def edit():
|
||||
if len(request.args) > 2 and request.args[1] == 'controllers':
|
||||
controller = (request.args[2])[:-3]
|
||||
functions = find_exposed_functions(data)
|
||||
functions = functions and sorted(functions) or []
|
||||
else:
|
||||
(controller, functions) = (None, None)
|
||||
|
||||
@@ -866,13 +895,9 @@ def resolve():
|
||||
|
||||
def getclass(item):
|
||||
""" Determine item class """
|
||||
operators = {' ':'normal', '+':'plus', '-':'minus'}
|
||||
|
||||
if item[0] == ' ':
|
||||
return 'normal'
|
||||
if item[0] == '+':
|
||||
return 'plus'
|
||||
if item[0] == '-':
|
||||
return 'minus'
|
||||
return operators[item[0]]
|
||||
|
||||
if request.vars:
|
||||
c = '\n'.join([item[2:].rstrip() for (i, item) in enumerate(d) if item[0]
|
||||
@@ -1067,7 +1092,7 @@ def design():
|
||||
for c in controllers:
|
||||
data = safe_read(apath('%s/controllers/%s' % (app, c), r=request))
|
||||
items = find_exposed_functions(data)
|
||||
functions[c] = items
|
||||
functions[c] = items and sorted(items) or []
|
||||
|
||||
# Get all views
|
||||
views = sorted(
|
||||
@@ -1205,7 +1230,7 @@ def plugin():
|
||||
for c in controllers:
|
||||
data = safe_read(apath('%s/controllers/%s' % (app, c), r=request))
|
||||
items = find_exposed_functions(data)
|
||||
functions[c] = items
|
||||
functions[c] = items and sorted(items) or []
|
||||
|
||||
# Get all views
|
||||
views = sorted(
|
||||
@@ -1509,7 +1534,7 @@ def upload_file():
|
||||
if filename:
|
||||
d = dict(filename=filename[len(path):])
|
||||
else:
|
||||
d = dict(filename='unkown')
|
||||
d = dict(filename='unknown')
|
||||
session.flash = T('cannot upload file "%(filename)s"', d)
|
||||
|
||||
redirect(request.vars.sender)
|
||||
|
||||
+5
-4
@@ -1,4 +1,5 @@
|
||||
/*! jQuery v1.11.2 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.2",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(Line truncated
|
||||
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var
Line truncated
|
||||
}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(aLine truncated
|
||||
/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^Line truncated
|
||||
|
||||
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var
Line truncated
|
||||
return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[cLine truncated
|
||||
@@ -490,12 +490,12 @@
|
||||
* and prevent clicking on it */
|
||||
disableElement: function(el) {
|
||||
el.addClass('disabled');
|
||||
var method = el.is('button') ? 'html' : 'val';
|
||||
var method = el.is('input') ? 'val' : 'html';
|
||||
//method = el.attr('name') ? 'html' : 'val';
|
||||
var disable_with_message = (typeof w2p_ajax_disable_with_message != 'undefined') ? w2p_ajax_disable_with_message : "Working...";
|
||||
/*store enabled state if not already disabled */
|
||||
if(el.data('w2p:enable-with') === undefined) {
|
||||
el.data('w2p:enable-with', el[method]());
|
||||
if(el.data('w2p_enable_with') === undefined) {
|
||||
el.data('w2p_enable_with', el[method]());
|
||||
}
|
||||
/*if you don't want to see "working..." on buttons, replace the following
|
||||
* two lines with this one
|
||||
@@ -515,11 +515,11 @@
|
||||
|
||||
/* restore element to its original state which was disabled by 'disableElement' above*/
|
||||
enableElement: function(el) {
|
||||
var method = el.is('button') ? 'val' : 'html';
|
||||
if(el.data('w2p:enable-with') !== undefined) {
|
||||
var method = el.is('input') ? 'val' : 'html';
|
||||
if(el.data('w2p_enable_with') !== undefined) {
|
||||
/* set to old enabled state */
|
||||
el[method](el.data('w2p:enable-with'));
|
||||
el.removeData('w2p:enable-with');
|
||||
el[method](el.data('w2p_enable_with'));
|
||||
el.removeData('w2p_enable_with');
|
||||
}
|
||||
el.removeClass('disabled');
|
||||
el.unbind('click.w2pDisable');
|
||||
@@ -586,12 +586,14 @@
|
||||
if(pre_call != undefined) {
|
||||
eval(pre_call);
|
||||
}
|
||||
if(confirm_message != undefined) {
|
||||
if(confirm_message == 'default') confirm_message = w2p_ajax_confirm_message || 'Are you sure you want to delete this object?';
|
||||
if(!web2py.confirm(confirm_message)) {
|
||||
web2py.stopEverything(e);
|
||||
return;
|
||||
}
|
||||
if(confirm_message) {
|
||||
if(confirm_message == 'default')
|
||||
confirm_message = w2p_ajax_confirm_message ||
|
||||
'Are you sure you want to delete this object?';
|
||||
if(!web2py.confirm(confirm_message)) {
|
||||
web2py.stopEverything(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(target == undefined) {
|
||||
if(method == 'GET') {
|
||||
@@ -634,7 +636,7 @@
|
||||
});
|
||||
},
|
||||
/* Disables form elements:
|
||||
- Caches element value in 'w2p:enable-with' data store
|
||||
- Caches element value in 'w2p_enable_with' data store
|
||||
- Replaces element text with value of 'data-disable-with' attribute
|
||||
- Sets disabled property to true
|
||||
*/
|
||||
@@ -646,8 +648,8 @@
|
||||
if(disable_with == undefined) {
|
||||
element.data('w2p_disable_with', element[method]())
|
||||
}
|
||||
if(element.data('w2p:enable-with') === undefined) {
|
||||
element.data('w2p:enable-with', element[method]());
|
||||
if(element.data('w2p_enable_with') === undefined) {
|
||||
element.data('w2p_enable_with', element[method]());
|
||||
}
|
||||
element[method](element.data('w2p_disable_with'));
|
||||
element.prop('disabled', true);
|
||||
@@ -655,16 +657,16 @@
|
||||
},
|
||||
|
||||
/* Re-enables disabled form elements:
|
||||
- Replaces element text with cached value from 'w2p:enable-with' data store (created in `disableFormElements`)
|
||||
- Replaces element text with cached value from 'w2p_enable_with' data store (created in `disableFormElements`)
|
||||
- Sets disabled property to false
|
||||
*/
|
||||
enableFormElements: function(form) {
|
||||
form.find(web2py.enableSelector).each(function() {
|
||||
var element = $(this),
|
||||
method = element.is('button') ? 'html' : 'val';
|
||||
if(element.data('w2p:enable-with')) {
|
||||
element[method](element.data('w2p:enable-with'));
|
||||
element.removeData('w2p:enable-with');
|
||||
if(element.data('w2p_enable_with')) {
|
||||
element[method](element.data('w2p_enable_with'));
|
||||
element.removeData('w2p_enable_with');
|
||||
}
|
||||
element.prop('disabled', false);
|
||||
});
|
||||
|
||||
@@ -137,9 +137,9 @@
|
||||
<h4>{{=T("Overview")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", total['entries'])}}</p>
|
||||
{{if total['entries'] > 0:}}
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses})",
|
||||
dict(ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
|
||||
</p>
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
|
||||
dict( ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
@@ -155,7 +155,7 @@
|
||||
{{=T.M("Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=total['oldest'][0], min=total['oldest'][1], sec=total['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle();')}}
|
||||
{{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle().toggleClass( "hidden" );')}}
|
||||
<div class="hidden" id="all_keys">
|
||||
{{=total['keys']}}
|
||||
</div>
|
||||
@@ -183,7 +183,7 @@
|
||||
{{=T.M("RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=ram['oldest'][0], min=ram['oldest'][1], sec=ram['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle();')}}
|
||||
{{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle().toggleClass( "hidden" );')}}
|
||||
<div class="hidden" id="ram_keys">
|
||||
{{=ram['keys']}}
|
||||
</div>
|
||||
@@ -212,7 +212,7 @@
|
||||
{{=T.M("DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=disk['oldest'][0], min=disk['oldest'][1], sec=disk['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle().toggleClass( "hidden" );')}}
|
||||
<div class="hidden" id="disk_keys">
|
||||
{{=disk['keys']}}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{{extend 'layout.html'}}
|
||||
{{
|
||||
import re
|
||||
regex_space = re.compile('\s+')
|
||||
def all(items):
|
||||
return reduce(lambda a,b:a and b,items,True)
|
||||
def peekfile(path,file,vars={},title=None):
|
||||
@@ -304,7 +306,7 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
|
||||
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)
|
||||
thispath = regex_space.sub('-', 'static__'+'__'.join(path))
|
||||
}}
|
||||
<li class="folder"><i> </i>
|
||||
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<form action="{{=URL(args=request.args)}}" method="POST">
|
||||
<h2>{{=T('Select Files to Package')}}</h2>
|
||||
<input type="submit" value="{{=T('Download .w2p')}}" class="btn"/>
|
||||
<input type="submit" name="doexe" value="{{=T('Download as .exe')}}" class="btn"/>
|
||||
<div style="margin-top:20px">
|
||||
{{tree(base)}}
|
||||
</div>
|
||||
|
||||
@@ -49,7 +49,8 @@ if request.function == 'manage':
|
||||
auth.table_group(),
|
||||
auth.table_permission()])
|
||||
manager_role = manager_action.get('role', None) if manager_action else None
|
||||
auth.requires_membership(manager_role)(lambda: None)()
|
||||
if not (gluon.fileutils.check_credentials(request) or auth.has_membership(manager_role)):
|
||||
raise HTTP(403, "Not authorized")
|
||||
menu = False
|
||||
elif (request.application == 'admin' and not session.authorized) or \
|
||||
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
|
||||
@@ -80,7 +81,6 @@ if False and request.tickets_db:
|
||||
def get_databases(request):
|
||||
dbs = {}
|
||||
for (key, value) in global_env.items():
|
||||
cond = False
|
||||
try:
|
||||
cond = isinstance(value, GQLDB)
|
||||
except:
|
||||
@@ -445,30 +445,31 @@ def ccache():
|
||||
gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age'])
|
||||
total.update(gae_stats)
|
||||
else:
|
||||
# get ram stats directly from the cache object
|
||||
ram_stats = cache.ram.stats[request.application]
|
||||
ram['hits'] = ram_stats['hit_total'] - ram_stats['misses']
|
||||
ram['misses'] = ram_stats['misses']
|
||||
try:
|
||||
ram['ratio'] = ram['hits'] * 100 / ram_stats['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
ram['ratio'] = 0
|
||||
|
||||
for key, value in cache.ram.storage.iteritems():
|
||||
if isinstance(value, dict):
|
||||
ram['hits'] = value['hit_total'] - value['misses']
|
||||
ram['misses'] = value['misses']
|
||||
try:
|
||||
ram['ratio'] = ram['hits'] * 100 / value['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
ram['ratio'] = 0
|
||||
else:
|
||||
if hp:
|
||||
ram['bytes'] += hp.iso(value[1]).size
|
||||
ram['objects'] += hp.iso(value[1]).count
|
||||
ram['entries'] += 1
|
||||
if value[0] < ram['oldest']:
|
||||
ram['oldest'] = value[0]
|
||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
if hp:
|
||||
ram['bytes'] += hp.iso(value[1]).size
|
||||
ram['objects'] += hp.iso(value[1]).count
|
||||
ram['entries'] += 1
|
||||
if value[0] < ram['oldest']:
|
||||
ram['oldest'] = value[0]
|
||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
|
||||
for key in cache.disk.storage:
|
||||
value = cache.disk.storage[key]
|
||||
if isinstance(value, dict):
|
||||
disk['hits'] = value['hit_total'] - value['misses']
|
||||
disk['misses'] = value['misses']
|
||||
if isinstance(value[1], dict):
|
||||
disk['hits'] = value[1]['hit_total'] - value[1]['misses']
|
||||
disk['misses'] = value[1]['misses']
|
||||
try:
|
||||
disk['ratio'] = disk['hits'] * 100 / value['hit_total']
|
||||
disk['ratio'] = disk['hits'] * 100 / value[1]['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
disk['ratio'] = 0
|
||||
else:
|
||||
@@ -480,12 +481,12 @@ def ccache():
|
||||
disk['oldest'] = value[0]
|
||||
disk['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
|
||||
total['entries'] = ram['entries'] + disk['entries']
|
||||
total['bytes'] = ram['bytes'] + disk['bytes']
|
||||
total['objects'] = ram['objects'] + disk['objects']
|
||||
total['hits'] = ram['hits'] + disk['hits']
|
||||
total['misses'] = ram['misses'] + disk['misses']
|
||||
total['keys'] = ram['keys'] + disk['keys']
|
||||
ram_keys = ram.keys() # ['hits', 'objects', 'ratio', 'entries', 'keys', 'oldest', 'bytes', 'misses']
|
||||
ram_keys.remove('ratio')
|
||||
ram_keys.remove('oldest')
|
||||
for key in ram_keys:
|
||||
total[key] = ram[key] + disk[key]
|
||||
|
||||
try:
|
||||
total['ratio'] = total['hits'] * 100 / (total['hits'] +
|
||||
total['misses'])
|
||||
@@ -577,9 +578,7 @@ def bg_graph_model():
|
||||
group = meta_graphmodel['group'].replace(' ', '')
|
||||
if not subgraphs.has_key(group):
|
||||
subgraphs[group] = dict(meta=meta_graphmodel, tables=[])
|
||||
subgraphs[group]['tables'].append(tablename)
|
||||
else:
|
||||
subgraphs[group]['tables'].append(tablename)
|
||||
subgraphs[group]['tables'].append(tablename)
|
||||
|
||||
graph.add_node(tablename, name=tablename, shape='plaintext',
|
||||
label=table_template(tablename))
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#### Learning and Demos
|
||||
- [[Intro video http://www.youtube.com/watch?v=BXzqmHx6edY]] and [[code examples https://github.com/mjhea0/web2py]]
|
||||
- [[Step by step tutorial https://milesm.pythonanywhere.com/wiki]]
|
||||
- [[Killer Web Development Tutorial http://killer-web-development.com/]]
|
||||
- [[Real Python for the Web http://www.realpython.com]] (web development with web2py and more!)
|
||||
- [[Admin Demo http://www.web2py.com/demo_admin popup]] (web-based IDE)
|
||||
@@ -22,5 +23,6 @@
|
||||
- [[More Plugins http://dev.s-cubism.com/web2py_plugins]]
|
||||
- [[Appliances http://www.web2py.com/appliances popup]]
|
||||
- [[web2py utils http://packages.python.org/web2py_utils/ popup]]
|
||||
- [[Sublime text 3 plugin https://bitbucket.org/kfog/w2p popup]]
|
||||
|
||||
#### [[Sites Powered by web2py http://www.web2py.com/poweredby popup]]
|
||||
+5
-4
@@ -1,4 +1,5 @@
|
||||
/*! jQuery v1.11.2 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.2",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(Line truncated
|
||||
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var
Line truncated
|
||||
}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(aLine truncated
|
||||
/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^Line truncated
|
||||
|
||||
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var
Line truncated
|
||||
return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[cLine truncated
|
||||
@@ -490,12 +490,12 @@
|
||||
* and prevent clicking on it */
|
||||
disableElement: function(el) {
|
||||
el.addClass('disabled');
|
||||
var method = el.is('button') ? 'html' : 'val';
|
||||
var method = el.is('input') ? 'val' : 'html';
|
||||
//method = el.attr('name') ? 'html' : 'val';
|
||||
var disable_with_message = (typeof w2p_ajax_disable_with_message != 'undefined') ? w2p_ajax_disable_with_message : "Working...";
|
||||
/*store enabled state if not already disabled */
|
||||
if(el.data('w2p:enable-with') === undefined) {
|
||||
el.data('w2p:enable-with', el[method]());
|
||||
if(el.data('w2p_enable_with') === undefined) {
|
||||
el.data('w2p_enable_with', el[method]());
|
||||
}
|
||||
/*if you don't want to see "working..." on buttons, replace the following
|
||||
* two lines with this one
|
||||
@@ -515,11 +515,11 @@
|
||||
|
||||
/* restore element to its original state which was disabled by 'disableElement' above*/
|
||||
enableElement: function(el) {
|
||||
var method = el.is('button') ? 'val' : 'html';
|
||||
if(el.data('w2p:enable-with') !== undefined) {
|
||||
var method = el.is('input') ? 'val' : 'html';
|
||||
if(el.data('w2p_enable_with') !== undefined) {
|
||||
/* set to old enabled state */
|
||||
el[method](el.data('w2p:enable-with'));
|
||||
el.removeData('w2p:enable-with');
|
||||
el[method](el.data('w2p_enable_with'));
|
||||
el.removeData('w2p_enable_with');
|
||||
}
|
||||
el.removeClass('disabled');
|
||||
el.unbind('click.w2pDisable');
|
||||
@@ -586,12 +586,14 @@
|
||||
if(pre_call != undefined) {
|
||||
eval(pre_call);
|
||||
}
|
||||
if(confirm_message != undefined) {
|
||||
if(confirm_message == 'default') confirm_message = w2p_ajax_confirm_message || 'Are you sure you want to delete this object?';
|
||||
if(!web2py.confirm(confirm_message)) {
|
||||
web2py.stopEverything(e);
|
||||
return;
|
||||
}
|
||||
if(confirm_message) {
|
||||
if(confirm_message == 'default')
|
||||
confirm_message = w2p_ajax_confirm_message ||
|
||||
'Are you sure you want to delete this object?';
|
||||
if(!web2py.confirm(confirm_message)) {
|
||||
web2py.stopEverything(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(target == undefined) {
|
||||
if(method == 'GET') {
|
||||
@@ -634,7 +636,7 @@
|
||||
});
|
||||
},
|
||||
/* Disables form elements:
|
||||
- Caches element value in 'w2p:enable-with' data store
|
||||
- Caches element value in 'w2p_enable_with' data store
|
||||
- Replaces element text with value of 'data-disable-with' attribute
|
||||
- Sets disabled property to true
|
||||
*/
|
||||
@@ -646,8 +648,8 @@
|
||||
if(disable_with == undefined) {
|
||||
element.data('w2p_disable_with', element[method]())
|
||||
}
|
||||
if(element.data('w2p:enable-with') === undefined) {
|
||||
element.data('w2p:enable-with', element[method]());
|
||||
if(element.data('w2p_enable_with') === undefined) {
|
||||
element.data('w2p_enable_with', element[method]());
|
||||
}
|
||||
element[method](element.data('w2p_disable_with'));
|
||||
element.prop('disabled', true);
|
||||
@@ -655,16 +657,16 @@
|
||||
},
|
||||
|
||||
/* Re-enables disabled form elements:
|
||||
- Replaces element text with cached value from 'w2p:enable-with' data store (created in `disableFormElements`)
|
||||
- Replaces element text with cached value from 'w2p_enable_with' data store (created in `disableFormElements`)
|
||||
- Sets disabled property to false
|
||||
*/
|
||||
enableFormElements: function(form) {
|
||||
form.find(web2py.enableSelector).each(function() {
|
||||
var element = $(this),
|
||||
method = element.is('button') ? 'html' : 'val';
|
||||
if(element.data('w2p:enable-with')) {
|
||||
element[method](element.data('w2p:enable-with'));
|
||||
element.removeData('w2p:enable-with');
|
||||
if(element.data('w2p_enable_with')) {
|
||||
element[method](element.data('w2p_enable_with'));
|
||||
element.removeData('w2p_enable_with');
|
||||
}
|
||||
element.prop('disabled', false);
|
||||
});
|
||||
|
||||
@@ -137,9 +137,9 @@
|
||||
<h4>{{=T("Overview")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", total['entries'])}}</p>
|
||||
{{if total['entries'] > 0:}}
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses})",
|
||||
dict(ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
|
||||
</p>
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
|
||||
dict( ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
@@ -155,7 +155,7 @@
|
||||
{{=T.M("Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=total['oldest'][0], min=total['oldest'][1], sec=total['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle();')}}
|
||||
{{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle().toggleClass( "hidden" );')}}
|
||||
<div class="hidden" id="all_keys">
|
||||
{{=total['keys']}}
|
||||
</div>
|
||||
@@ -183,7 +183,7 @@
|
||||
{{=T.M("RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=ram['oldest'][0], min=ram['oldest'][1], sec=ram['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle();')}}
|
||||
{{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle().toggleClass( "hidden" );')}}
|
||||
<div class="hidden" id="ram_keys">
|
||||
{{=ram['keys']}}
|
||||
</div>
|
||||
@@ -212,7 +212,7 @@
|
||||
{{=T.M("DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=disk['oldest'][0], min=disk['oldest'][1], sec=disk['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle().toggleClass( "hidden" );')}}
|
||||
<div class="hidden" id="disk_keys">
|
||||
{{=disk['keys']}}
|
||||
</div>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</center>
|
||||
|
||||
<p style="text-align:left;">
|
||||
The source code version works on all supported platforms, including Linux, but it requires Python 2.5, 2.6, or 2.7.
|
||||
The source code version works on all supported platforms, including Linux, but it requires Python 2.6, or 2.7 (recommended).
|
||||
It runs on Windows and most Unix systems, including <b>Linux</b> and <b>BSD</b>.
|
||||
</p>
|
||||
|
||||
|
||||
@@ -17,19 +17,24 @@
|
||||
<ul>
|
||||
<li><a target="_blank" href="http://experts4solutions.com">Experts4Soutions</a> (worldwide)</li>
|
||||
<li><a target="_blank" href="http://www.planethost.com">PlanetHost</a> (USA)</li>
|
||||
<li><a target="_blank" href="http://www.10biosystems.com">10BioSystems</a> (USA)</li>
|
||||
<li><a target="_blank" href="http://www.formatics.nl">Formatics</a> (Netherlands)</li>
|
||||
<li><a target="_blank" href="http://www.corebyte.nl">Corebyte</a> (Netherlands)</li>
|
||||
<li><a target="_blank" href="http://www.dutveul.nl">Dutveul</a> (Netherlands)</li>
|
||||
<li><a target="_blank" href="http://www.onemewebservices.com">OneMeWebServices</a> (Canada)</li>
|
||||
<li><a target="_blank" href="http://www.budgetbytes.nl">BudgetBytes</a> (The Netherlands)</li>
|
||||
<li><a target="_blank" href="http://www.androsoft.pl">ANDROSoft</a> (Poland)</li>
|
||||
|
||||
<li><a target="_blank" href="www.sonnetech.com.br">Sonne Tech</a> (Brazil)</li>
|
||||
<li><a target="_blank" href="http://www.sonnetech.com.br">Sonne Tech</a> (Brazil)</li>
|
||||
<li><a target="_blank" href="http://www.nrg.com.br">NRG Internet Solutions</a> (Brazil)</li>
|
||||
<li><a target="_blank" href="http://itjp.net.br/">ITJP</a> (Brazil)</li>
|
||||
<li><a target="_blank" href="http://i-am.pt">I am Consultoria</a> (Portugal)</li>
|
||||
<li><a target="_blank" href="http://www.definescope.com/">DefineScope</a> (Portugal)</li>
|
||||
<li><a target="_blank" href="http://lpfx.com.br">LPFX</a> (Brazil)</li>
|
||||
<li><a target="_blank" href="http://emotionull.com">Emotionull</a> (Greece and Cyprus)</li>
|
||||
<li><a target="_blank" href="http://www.vsa-services.com/">VSA Services</a> (Singapore)</li>
|
||||
<li><a target="_blank" href="http://www.albendas.com">Albendas</a> (Spain)</li>
|
||||
<li><a target="_blank" href="www.corebyte.nl">Corebyte</a> (Netherland)</li>
|
||||
<li><a target="_blank" href="https://loadinfo-net.appspot.com">LoadInfo</a> (Bulgaria)</li>
|
||||
<li><a target="_blank" href="http://www.appliedobjects.com">Applied Objects</a> (New Zealand)</li>
|
||||
<li><a target="_blank" href="http://www.sistemasagiles.com.ar/">Sistemas Ágiles</a> ("Agile Systems") (Argentina)</li>
|
||||
|
||||
@@ -49,7 +49,8 @@ if request.function == 'manage':
|
||||
auth.table_group(),
|
||||
auth.table_permission()])
|
||||
manager_role = manager_action.get('role', None) if manager_action else None
|
||||
auth.requires_membership(manager_role)(lambda: None)()
|
||||
if not (gluon.fileutils.check_credentials(request) or auth.has_membership(manager_role)):
|
||||
raise HTTP(403, "Not authorized")
|
||||
menu = False
|
||||
elif (request.application == 'admin' and not session.authorized) or \
|
||||
(request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
|
||||
@@ -80,7 +81,6 @@ if False and request.tickets_db:
|
||||
def get_databases(request):
|
||||
dbs = {}
|
||||
for (key, value) in global_env.items():
|
||||
cond = False
|
||||
try:
|
||||
cond = isinstance(value, GQLDB)
|
||||
except:
|
||||
@@ -445,30 +445,31 @@ def ccache():
|
||||
gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age'])
|
||||
total.update(gae_stats)
|
||||
else:
|
||||
# get ram stats directly from the cache object
|
||||
ram_stats = cache.ram.stats[request.application]
|
||||
ram['hits'] = ram_stats['hit_total'] - ram_stats['misses']
|
||||
ram['misses'] = ram_stats['misses']
|
||||
try:
|
||||
ram['ratio'] = ram['hits'] * 100 / ram_stats['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
ram['ratio'] = 0
|
||||
|
||||
for key, value in cache.ram.storage.iteritems():
|
||||
if isinstance(value, dict):
|
||||
ram['hits'] = value['hit_total'] - value['misses']
|
||||
ram['misses'] = value['misses']
|
||||
try:
|
||||
ram['ratio'] = ram['hits'] * 100 / value['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
ram['ratio'] = 0
|
||||
else:
|
||||
if hp:
|
||||
ram['bytes'] += hp.iso(value[1]).size
|
||||
ram['objects'] += hp.iso(value[1]).count
|
||||
ram['entries'] += 1
|
||||
if value[0] < ram['oldest']:
|
||||
ram['oldest'] = value[0]
|
||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
if hp:
|
||||
ram['bytes'] += hp.iso(value[1]).size
|
||||
ram['objects'] += hp.iso(value[1]).count
|
||||
ram['entries'] += 1
|
||||
if value[0] < ram['oldest']:
|
||||
ram['oldest'] = value[0]
|
||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
|
||||
for key in cache.disk.storage:
|
||||
value = cache.disk.storage[key]
|
||||
if isinstance(value, dict):
|
||||
disk['hits'] = value['hit_total'] - value['misses']
|
||||
disk['misses'] = value['misses']
|
||||
if isinstance(value[1], dict):
|
||||
disk['hits'] = value[1]['hit_total'] - value[1]['misses']
|
||||
disk['misses'] = value[1]['misses']
|
||||
try:
|
||||
disk['ratio'] = disk['hits'] * 100 / value['hit_total']
|
||||
disk['ratio'] = disk['hits'] * 100 / value[1]['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
disk['ratio'] = 0
|
||||
else:
|
||||
@@ -480,12 +481,12 @@ def ccache():
|
||||
disk['oldest'] = value[0]
|
||||
disk['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
|
||||
total['entries'] = ram['entries'] + disk['entries']
|
||||
total['bytes'] = ram['bytes'] + disk['bytes']
|
||||
total['objects'] = ram['objects'] + disk['objects']
|
||||
total['hits'] = ram['hits'] + disk['hits']
|
||||
total['misses'] = ram['misses'] + disk['misses']
|
||||
total['keys'] = ram['keys'] + disk['keys']
|
||||
ram_keys = ram.keys() # ['hits', 'objects', 'ratio', 'entries', 'keys', 'oldest', 'bytes', 'misses']
|
||||
ram_keys.remove('ratio')
|
||||
ram_keys.remove('oldest')
|
||||
for key in ram_keys:
|
||||
total[key] = ram[key] + disk[key]
|
||||
|
||||
try:
|
||||
total['ratio'] = total['hits'] * 100 / (total['hits'] +
|
||||
total['misses'])
|
||||
@@ -577,9 +578,7 @@ def bg_graph_model():
|
||||
group = meta_graphmodel['group'].replace(' ', '')
|
||||
if not subgraphs.has_key(group):
|
||||
subgraphs[group] = dict(meta=meta_graphmodel, tables=[])
|
||||
subgraphs[group]['tables'].append(tablename)
|
||||
else:
|
||||
subgraphs[group]['tables'].append(tablename)
|
||||
subgraphs[group]['tables'].append(tablename)
|
||||
|
||||
graph.add_node(tablename, name=tablename, shape='plaintext',
|
||||
label=table_template(tablename))
|
||||
|
||||
@@ -30,6 +30,7 @@ def user():
|
||||
http://..../[app]/default/user/retrieve_password
|
||||
http://..../[app]/default/user/change_password
|
||||
http://..../[app]/default/user/manage_users (requires membership in
|
||||
http://..../[app]/default/user/bulk_register
|
||||
use @auth.requires_login()
|
||||
@auth.requires_membership('group name')
|
||||
@auth.requires_permission('read','table name',record_id)
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
# Language from default.py or 'en' (if the file is not found) is used as
|
||||
# a default_language
|
||||
#
|
||||
# See <web2py-root-dir>/router.example.py for parameter's detail
|
||||
# See <web2py-root-dir>/examples/routes.parametric.example.py for parameter's detail
|
||||
#-------------------------------------------------------------------------------------
|
||||
# To enable this route file you must do the steps:
|
||||
#
|
||||
# 1. rename <web2py-root-dir>/router.example.py to routes.py
|
||||
# 1. rename <web2py-root-dir>/examples/routes.parametric.example.py to routes.py
|
||||
# 2. rename this APP/routes.example.py to APP/routes.py
|
||||
# (where APP - is your application directory)
|
||||
# 3. restart web2py (or reload routes in web2py admin interfase)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap v3.3.4 (http://getbootstrap.com)
|
||||
* Bootstrap v3.3.5 (http://getbootstrap.com)
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-imagLine truncated
|
||||
*/.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-succLine truncated
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap v3.3.4 (http://getbootstrap.com)
|
||||
* Bootstrap v3.3.5 (http://getbootstrap.com)
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:befoLine truncated
|
||||
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026Line truncated
|
||||
@@ -24,7 +24,9 @@ div.flash.alert:hover {
|
||||
.ie-lte8 div.flash:hover {
|
||||
filter: alpha(opacity=25);
|
||||
}
|
||||
|
||||
.main-container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
div.error {
|
||||
width: auto;
|
||||
@@ -283,6 +285,7 @@ li.w2p_grid_breadcrumb_elem {
|
||||
.web2py_console .form-control {
|
||||
width: 20%;
|
||||
display: inline;
|
||||
height: 100%;
|
||||
}
|
||||
.web2py_console #w2p_keywords {
|
||||
width: 50%;
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
/*!
|
||||
* Bootstrap v3.3.4 (http://getbootstrap.com)
|
||||
* Bootstrap v3.3.5 (http://getbootstrap.com)
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* Licensed under the MIT license
|
||||
*/
|
||||
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.4",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.4",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parLine truncated
|
||||
var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.4",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a(document.body).height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
|
||||
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&cLine truncated
|
||||
d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.5",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
|
||||
+5
-4
@@ -1,4 +1,5 @@
|
||||
/*! jQuery v1.11.2 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.2",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(Line truncated
|
||||
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var
Line truncated
|
||||
}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(aLine truncated
|
||||
/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^Line truncated
|
||||
|
||||
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var
Line truncated
|
||||
return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[cLine truncated
|
||||
@@ -586,12 +586,14 @@
|
||||
if(pre_call != undefined) {
|
||||
eval(pre_call);
|
||||
}
|
||||
if(confirm_message != undefined) {
|
||||
if(confirm_message == 'default') confirm_message = w2p_ajax_confirm_message || 'Are you sure you want to delete this object?';
|
||||
if(!web2py.confirm(confirm_message)) {
|
||||
web2py.stopEverything(e);
|
||||
return;
|
||||
}
|
||||
if(confirm_message) {
|
||||
if(confirm_message == 'default')
|
||||
confirm_message = w2p_ajax_confirm_message ||
|
||||
'Are you sure you want to delete this object?';
|
||||
if(!web2py.confirm(confirm_message)) {
|
||||
web2py.stopEverything(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(target == undefined) {
|
||||
if(method == 'GET') {
|
||||
|
||||
@@ -137,9 +137,9 @@
|
||||
<h4>{{=T("Overview")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", total['entries'])}}</p>
|
||||
{{if total['entries'] > 0:}}
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses})",
|
||||
dict(ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
|
||||
</p>
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
|
||||
dict( ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
@@ -155,7 +155,7 @@
|
||||
{{=T.M("Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=total['oldest'][0], min=total['oldest'][1], sec=total['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle();')}}
|
||||
{{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle().toggleClass( "hidden" );')}}
|
||||
<div class="hidden" id="all_keys">
|
||||
{{=total['keys']}}
|
||||
</div>
|
||||
@@ -183,7 +183,7 @@
|
||||
{{=T.M("RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=ram['oldest'][0], min=ram['oldest'][1], sec=ram['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle();')}}
|
||||
{{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle().toggleClass( "hidden" );')}}
|
||||
<div class="hidden" id="ram_keys">
|
||||
{{=ram['keys']}}
|
||||
</div>
|
||||
@@ -212,7 +212,7 @@
|
||||
{{=T.M("DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=disk['oldest'][0], min=disk['oldest'][1], sec=disk['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle().toggleClass( "hidden" );')}}
|
||||
<div class="hidden" id="disk_keys">
|
||||
{{=disk['keys']}}
|
||||
</div>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
{{end}}
|
||||
<!-- Main ========================================= -->
|
||||
<!-- Begin page content -->
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid main-container">
|
||||
{{if left_sidebar_enabled:}}
|
||||
<div class="col-md-3 left-sidebar">
|
||||
{{block left_sidebar}}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
build: false
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- PYTHON: "C:/Python27"
|
||||
COVERAGE_PROCESS_START: gluon/tests/coverage.ini
|
||||
|
||||
clone_depth: 50
|
||||
|
||||
init:
|
||||
- "ECHO %PYTHON%"
|
||||
- set PATH=%PYTHON%;%PYTHON%\Scripts;%PATH%
|
||||
|
||||
install:
|
||||
- ps: Start-FileDownload https://bootstrap.pypa.io/get-pip.py
|
||||
- python get-pip.py
|
||||
- pip install codecov
|
||||
- git submodule update --init --recursive
|
||||
|
||||
test_script:
|
||||
- python web2py.py --run_system_tests --with_coverage
|
||||
|
||||
after_test:
|
||||
- coverage combine
|
||||
- codecov
|
||||
+3
-2
@@ -59,6 +59,8 @@ def app_pack(app, request, raise_ex=False, filenames=None):
|
||||
w2p_pack(filename, apath(app, request), filenames=filenames)
|
||||
return filename
|
||||
except Exception, e:
|
||||
import traceback
|
||||
print traceback.format_exc()
|
||||
if raise_ex:
|
||||
raise
|
||||
return False
|
||||
@@ -119,9 +121,8 @@ def app_cleanup(app, request):
|
||||
|
||||
# Remove cache files
|
||||
path = apath('%s/cache/' % app, request)
|
||||
CacheOnDisk(folder=path).clear()
|
||||
|
||||
if os.path.exists(path):
|
||||
CacheOnDisk(folder=path).clear()
|
||||
for f in os.listdir(path):
|
||||
try:
|
||||
if f[:1] != '.': recursive_unlink(os.path.join(path, f))
|
||||
|
||||
+6
-1
@@ -473,7 +473,12 @@ class CacheOnDisk(CacheAbstract):
|
||||
if item and ((dt is None) or (item[0] > now - dt)):
|
||||
value = item[1]
|
||||
else:
|
||||
value = f()
|
||||
try:
|
||||
value = f()
|
||||
except:
|
||||
self.storage.release(CacheAbstract.cache_stats_name)
|
||||
self.storage.release(key)
|
||||
raise
|
||||
self.storage[key] = (now, value)
|
||||
self.storage.safe_apply(CacheAbstract.cache_stats_name, inc_misses,
|
||||
default_value={'hit_total': 0, 'misses': 0})
|
||||
|
||||
+9
-8
@@ -261,7 +261,7 @@ class LoadFactory(object):
|
||||
import globals
|
||||
target = target or 'c' + str(random.random())[2:]
|
||||
attr['_id'] = target
|
||||
request = self.environment['request']
|
||||
request = current.request
|
||||
if '.' in f:
|
||||
f, extension = f.rsplit('.', 1)
|
||||
if url or ajax:
|
||||
@@ -532,10 +532,11 @@ def run_models_in(environment):
|
||||
It tries pre-compiled models first before compiling them.
|
||||
"""
|
||||
|
||||
folder = environment['request'].folder
|
||||
c = environment['request'].controller
|
||||
request = current.request
|
||||
folder = request.folder
|
||||
c = request.controller
|
||||
#f = environment['request'].function
|
||||
response = environment['response']
|
||||
response = current.response
|
||||
|
||||
path = pjoin(folder, 'models')
|
||||
cpath = pjoin(folder, 'compiled')
|
||||
@@ -577,7 +578,7 @@ def run_controller_in(controller, function, environment):
|
||||
"""
|
||||
|
||||
# if compiled should run compiled!
|
||||
folder = environment['request'].folder
|
||||
folder = current.request.folder
|
||||
path = pjoin(folder, 'compiled')
|
||||
badc = 'invalid controller (%s/%s)' % (controller, function)
|
||||
badf = 'invalid function (%s/%s)' % (controller, function)
|
||||
@@ -631,7 +632,7 @@ def run_controller_in(controller, function, environment):
|
||||
layer = filename + ':' + function
|
||||
code = getcfs(layer, filename, lambda: compile2(code, layer))
|
||||
restricted(code, environment, filename)
|
||||
response = environment['response']
|
||||
response = current.response
|
||||
vars = response._vars
|
||||
if response.postprocessing:
|
||||
vars = reduce(lambda vars, p: p(vars), response.postprocessing, vars)
|
||||
@@ -649,8 +650,8 @@ def run_view_in(environment):
|
||||
or `view/generic.extension`
|
||||
It tries the pre-compiled views_controller_function.pyc before compiling it.
|
||||
"""
|
||||
request = environment['request']
|
||||
response = environment['response']
|
||||
request = current.request
|
||||
response = current.response
|
||||
view = response.view
|
||||
folder = request.folder
|
||||
path = pjoin(folder, 'compiled')
|
||||
|
||||
@@ -6,15 +6,17 @@
|
||||
#
|
||||
# Given the model
|
||||
#
|
||||
# db.define_table("table_name", Field("picture", "upload"), Field("thumbnail", "upload"))
|
||||
# db.define_table("table_name", Field("picture", "upload"),
|
||||
# Field("thumbnail", "upload"))
|
||||
#
|
||||
# # to resize the picture on upload
|
||||
# to resize the picture on upload
|
||||
#
|
||||
# from images import RESIZE
|
||||
#
|
||||
# db.table_name.picture.requires = RESIZE(200, 200)
|
||||
#
|
||||
# # to store original image in picture and create a thumbnail in 'thumbnail' field
|
||||
# to store original image in picture and create a thumbnail
|
||||
# in 'thumbnail' field
|
||||
#
|
||||
# from images import THUMB
|
||||
# db.table_name.thumbnail.compute = lambda row: THUMB(row.picture, 200, 200)
|
||||
@@ -24,8 +26,11 @@ from gluon import current
|
||||
|
||||
|
||||
class RESIZE(object):
|
||||
def __init__(self, nx=160, ny=80, error_message=' image resize'):
|
||||
(self.nx, self.ny, self.error_message) = (nx, ny, error_message)
|
||||
|
||||
def __init__(self, nx=160, ny=80, quality=100,
|
||||
error_message=' image resize'):
|
||||
(self.nx, self.ny, self.quality, self.error_message) = (
|
||||
nx, ny, quality, error_message)
|
||||
|
||||
def __call__(self, value):
|
||||
if isinstance(value, str) and len(value) == 0:
|
||||
@@ -36,7 +41,7 @@ class RESIZE(object):
|
||||
img = Image.open(value.file)
|
||||
img.thumbnail((self.nx, self.ny), Image.ANTIALIAS)
|
||||
s = cStringIO.StringIO()
|
||||
img.save(s, 'JPEG', quality=100)
|
||||
img.save(s, 'JPEG', quality=self.quality)
|
||||
s.seek(0)
|
||||
value.file = s
|
||||
except:
|
||||
@@ -51,7 +56,7 @@ def THUMB(image, nx=120, ny=120, gae=False, name='thumb'):
|
||||
request = current.request
|
||||
from PIL import Image
|
||||
import os
|
||||
img = Image.open(os.path.join(request.folder,'uploads',image))
|
||||
img = Image.open(os.path.join(request.folder, 'uploads', image))
|
||||
img.thumbnail((nx, ny), Image.ANTIALIAS)
|
||||
root, ext = os.path.splitext(image)
|
||||
thumb = '%s_%s%s' % (root, name, ext)
|
||||
|
||||
@@ -33,6 +33,7 @@ def ldap_auth(server='ldap', port=None,
|
||||
group_name_attrib='cn',
|
||||
group_member_attrib='memberUid',
|
||||
group_filterstr='objectClass=*',
|
||||
tls=False,
|
||||
logging_level='error'):
|
||||
|
||||
"""
|
||||
@@ -80,6 +81,13 @@ def ldap_auth(server='ldap', port=None,
|
||||
If ldap is using GnuTLS then you need cert_file="..." instead cert_path
|
||||
because cert_path isn't implemented in GnuTLS :(
|
||||
|
||||
To enable TLS, set tls=True:
|
||||
|
||||
auth.settings.login_methods.append(ldap_auth(
|
||||
server='my.ldap.server',
|
||||
base_dn='ou=Users,dc=domain,dc=com',
|
||||
tls=True))
|
||||
|
||||
If you need to bind to the directory with an admin account in order to
|
||||
search it then specify bind_dn & bind_pw to use for this.
|
||||
- currently only implemented for Active Directory
|
||||
@@ -610,6 +618,8 @@ def ldap_auth(server='ldap', port=None,
|
||||
ldap_port = 389
|
||||
con = ldap.initialize(
|
||||
"ldap://" + ldap_server + ":" + str(ldap_port))
|
||||
if tls:
|
||||
con.start_tls_s()
|
||||
return con
|
||||
|
||||
def get_user_groups_from_ldap(username,
|
||||
|
||||
@@ -13,6 +13,7 @@ Include in your model (eg db.py)::
|
||||
|
||||
auth.define_tables(username=True)
|
||||
from gluon.contrib.login_methods.saml2_auth import Saml2Auth
|
||||
import os
|
||||
auth.settings.login_form=Saml2Auth(
|
||||
config_file = os.path.join(request.folder,'private','sp_conf'),
|
||||
maps=dict(
|
||||
@@ -20,10 +21,59 @@ Include in your model (eg db.py)::
|
||||
email=lambda v: v['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn'][0],
|
||||
user_id=lambda v: v['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn'][0]))
|
||||
|
||||
you must have private/sp_conf.py, the pysaml2 sp configuration file
|
||||
you must have private/sp_conf.py, the pysaml2 sp configuration file. For example:
|
||||
|
||||
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from saml2 import BINDING_HTTP_POST, BINDING_HTTP_REDIRECT
|
||||
import os.path
|
||||
import requests
|
||||
import tempfile
|
||||
|
||||
BASEDIR = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
# Web2py SP url and application name
|
||||
HOST = 'http://127.0.0.1:8000'
|
||||
APP = 'sp'
|
||||
|
||||
# To load the IDP metadata...
|
||||
IDP_METADATA = 'http://127.0.0.1:8088/metadata'
|
||||
|
||||
def full_path(local_file):
|
||||
return os.path.join(BASEDIR, local_file)
|
||||
|
||||
CONFIG = {
|
||||
# your entity id, usually your subdomain plus the url to the metadata view.
|
||||
'entityid': '%s/%s/default/metadata' % (HOST, APP),
|
||||
'service': {
|
||||
'sp' : {
|
||||
'name': 'MYSP',
|
||||
'endpoints': {
|
||||
'assertion_consumer_service': [
|
||||
('%s/%s/default/user/login' % (HOST, APP), BINDING_HTTP_REDIRECT),
|
||||
('%s/%s/default/user/login' % (HOST, APP), BINDING_HTTP_POST),
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
# Your private and public key.
|
||||
'key_file': full_path('pki/mykey.pem'),
|
||||
'cert_file': full_path('pki/mycert.pem'),
|
||||
|
||||
# where the remote metadata is stored
|
||||
'metadata': {
|
||||
"remote": [{
|
||||
"url": IDP_METADATA,
|
||||
"cert":full_path('pki/mycert.pem')
|
||||
}]
|
||||
},
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
from saml2 import BINDING_HTTP_REDIRECT
|
||||
from saml2 import BINDING_HTTP_REDIRECT, BINDING_HTTP_POST
|
||||
from saml2.client import Saml2Client
|
||||
from gluon.utils import web2py_uuid
|
||||
from gluon import current, redirect, URL
|
||||
@@ -59,10 +109,13 @@ def saml2_handler(session, request, config_filename = None):
|
||||
client = Saml2Client(config_file = config_filename)
|
||||
idps = client.metadata.with_descriptor("idpsso")
|
||||
entityid = idps.keys()[0]
|
||||
bindings = [BINDING_HTTP_REDIRECT]
|
||||
bindings = [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST]
|
||||
binding, destination = client.pick_binding(
|
||||
"single_sign_on_service", bindings, "idpsso", entity_id=entityid)
|
||||
binding = BINDING_HTTP_REDIRECT
|
||||
if request.env.request_method == 'GET':
|
||||
binding = BINDING_HTTP_REDIRECT
|
||||
elif request.env.request_method == 'POST':
|
||||
binding = BINDING_HTTP_POST
|
||||
if not request.vars.SAMLResponse:
|
||||
req_id, req = client.create_authn_request(destination, binding=binding)
|
||||
relay_state = web2py_uuid().replace('-','')
|
||||
|
||||
@@ -67,11 +67,12 @@ def RedisCache(*args, **vars):
|
||||
|
||||
locker.acquire()
|
||||
try:
|
||||
if not hasattr(RedisCache, 'redis_instance'):
|
||||
RedisCache.redis_instance = RedisClient(*args, **vars)
|
||||
instance_name = 'redis_instance_' + current.request.application
|
||||
if not hasattr(RedisCache, instance_name):
|
||||
setattr(RedisCache, instance_name, RedisClient(*args, **vars))
|
||||
return getattr(RedisCache, instance_name)
|
||||
finally:
|
||||
locker.release()
|
||||
return RedisCache.redis_instance
|
||||
|
||||
|
||||
class RedisClient(object):
|
||||
|
||||
@@ -126,7 +126,7 @@ class History:
|
||||
def globals_dict(self):
|
||||
"""Returns a dictionary view of the globals.
|
||||
"""
|
||||
return dict((name, cPickle.loads(val))
|
||||
return dict((name, pickle.loads(val))
|
||||
for name, val in zip(self.global_names, self.globals))
|
||||
|
||||
def add_unpicklable(self, statement, names):
|
||||
|
||||
@@ -34,7 +34,7 @@ except ImportError:
|
||||
class JSONRPCError(RuntimeError):
|
||||
"Error object for remote procedure call fail"
|
||||
def __init__(self, code, message, data=None):
|
||||
value = "%s: %s\n%s" % (code, message, '\n'.join(data))
|
||||
value = "%s: %s\n%s" % (code, message, '\n'.join(data or ''))
|
||||
RuntimeError.__init__(self, value)
|
||||
self.code = code
|
||||
self.message = message
|
||||
|
||||
@@ -145,6 +145,10 @@ class TokenHandler(tornado.web.RequestHandler):
|
||||
|
||||
|
||||
class DistributeHandler(tornado.websocket.WebSocketHandler):
|
||||
|
||||
def check_origin(self, origin):
|
||||
return True
|
||||
|
||||
def open(self, params):
|
||||
group, token, name = params.split('/') + [None, None]
|
||||
self.group = group or 'default'
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ Takes care of adapting pyDAL to web2py's needs
|
||||
|
||||
from pydal import DAL as DAL
|
||||
from pydal import Field
|
||||
from pydal.objects import Row, Rows, Table, Query, Expression
|
||||
from pydal.objects import Row, Rows, Table, Query, Set, Expression
|
||||
from pydal import SQLCustomType, geoPoint, geoLine, geoPolygon
|
||||
|
||||
|
||||
|
||||
+48
-32
@@ -26,6 +26,8 @@ import gluon.settings as settings
|
||||
from gluon.utils import web2py_uuid, secure_dumps, secure_loads
|
||||
from gluon.settings import global_settings
|
||||
from gluon import recfile
|
||||
from gluon.cache import CacheInRam
|
||||
from gluon.fileutils import copystream
|
||||
import hashlib
|
||||
import portalocker
|
||||
try:
|
||||
@@ -47,8 +49,7 @@ import cgi
|
||||
import urlparse
|
||||
import copy
|
||||
import tempfile
|
||||
from gluon.cache import CacheInRam
|
||||
from gluon.fileutils import copystream
|
||||
|
||||
|
||||
FMT = '%a, %d-%b-%Y %H:%M:%S PST'
|
||||
PAST = 'Sat, 1-Jan-1971 00:00:00'
|
||||
@@ -82,13 +83,22 @@ less_template = '<link href="%s" rel="stylesheet/less" type="text/css" />'
|
||||
css_inline = '<style type="text/css">\n%s\n</style>'
|
||||
js_inline = '<script type="text/javascript">\n%s\n</script>'
|
||||
|
||||
template_mapping = {
|
||||
'css': css_template,
|
||||
'js': js_template,
|
||||
'coffee': coffee_template,
|
||||
'ts': typescript_template,
|
||||
'less': less_template,
|
||||
'css:inline': css_inline,
|
||||
'js:inline': js_inline
|
||||
}
|
||||
|
||||
# IMPORTANT:
|
||||
# this is required so that pickled dict(s) and class.__dict__
|
||||
# are sorted and web2py can detect without ambiguity when a session changes
|
||||
class SortingPickler(Pickler):
|
||||
def save_dict(self, obj):
|
||||
self.write(EMPTY_DICT if self.bin else MARK+DICT)
|
||||
self.write(EMPTY_DICT if self.bin else MARK + DICT)
|
||||
self.memoize(obj)
|
||||
self._batch_setitems([(key, obj[key]) for key in sorted(obj)])
|
||||
|
||||
@@ -193,6 +203,7 @@ class Request(Storage):
|
||||
self.is_https = False
|
||||
self.is_local = False
|
||||
self.global_settings = settings.global_settings
|
||||
self._uuid = None
|
||||
|
||||
def parse_get_vars(self):
|
||||
"""Takes the QUERY_STRING and unpacks it to get_vars
|
||||
@@ -275,7 +286,7 @@ class Request(Storage):
|
||||
"""
|
||||
self._vars = copy.copy(self.get_vars)
|
||||
for key, value in self.post_vars.iteritems():
|
||||
if not key in self._vars:
|
||||
if key not in self._vars:
|
||||
self._vars[key] = value
|
||||
else:
|
||||
if not isinstance(self._vars[key], list):
|
||||
@@ -306,13 +317,21 @@ class Request(Storage):
|
||||
self.parse_all_vars()
|
||||
return self._vars
|
||||
|
||||
@property
|
||||
def uuid(self):
|
||||
"""Lazily uuid
|
||||
"""
|
||||
if self._uuid is None:
|
||||
self.compute_uuid()
|
||||
return self._uuid
|
||||
|
||||
def compute_uuid(self):
|
||||
self.uuid = '%s/%s.%s.%s' % (
|
||||
self._uuid = '%s/%s.%s.%s' % (
|
||||
self.application,
|
||||
self.client.replace(':', '_'),
|
||||
self.now.strftime('%Y-%m-%d.%H-%M-%S'),
|
||||
web2py_uuid())
|
||||
return self.uuid
|
||||
return self._uuid
|
||||
|
||||
def user_agent(self):
|
||||
from gluon.contrib import user_agent_parser
|
||||
@@ -436,29 +455,32 @@ class Response(Storage):
|
||||
return page
|
||||
|
||||
def include_meta(self):
|
||||
s = "\n";
|
||||
s = "\n"
|
||||
for meta in (self.meta or {}).iteritems():
|
||||
k, v = meta
|
||||
if isinstance(v,dict):
|
||||
s = s+'<meta'+''.join(' %s="%s"' % (xmlescape(key), xmlescape(v[key])) for key in v) +' />\n'
|
||||
if isinstance(v, dict):
|
||||
s += '<meta' + ''.join(' %s="%s"' % (xmlescape(key), xmlescape(v[key])) for key in v) +' />\n'
|
||||
else:
|
||||
s = s+'<meta name="%s" content="%s" />\n' % (k, xmlescape(v))
|
||||
s += '<meta name="%s" content="%s" />\n' % (k, xmlescape(v))
|
||||
self.write(s, escape=False)
|
||||
|
||||
def include_files(self, extensions=None):
|
||||
|
||||
"""
|
||||
Caching method for writing out files.
|
||||
Includes files (usually in the head).
|
||||
Can minify and cache local files
|
||||
By default, caches in ram for 5 minutes. To change,
|
||||
response.cache_includes = (cache_method, time_expire).
|
||||
Example: (cache.disk, 60) # caches to disk for 1 minute.
|
||||
"""
|
||||
from gluon import URL
|
||||
|
||||
files = []
|
||||
ext_files = []
|
||||
has_js = has_css = False
|
||||
for item in self.files:
|
||||
if extensions and not item.split('.')[-1] in extensions:
|
||||
if isinstance(item, (list, tuple)):
|
||||
ext_files.append(item)
|
||||
continue
|
||||
if extensions and not item.rpartition('.')[2] in extensions:
|
||||
continue
|
||||
if item in files:
|
||||
continue
|
||||
@@ -487,10 +509,13 @@ class Response(Storage):
|
||||
time_expire)
|
||||
else:
|
||||
files = call_minify()
|
||||
s = ''
|
||||
|
||||
files.extend(ext_files)
|
||||
s = []
|
||||
for item in files:
|
||||
if isinstance(item, str):
|
||||
f = item.lower().split('?')[0]
|
||||
ext = f.rpartition('.')[2]
|
||||
# if static_version we need also to check for
|
||||
# static_version_urls. In that case, the _.x.x.x
|
||||
# bit would have already been added by the URL()
|
||||
@@ -498,24 +523,15 @@ class Response(Storage):
|
||||
if self.static_version and not self.static_version_urls:
|
||||
item = item.replace(
|
||||
'/static/', '/static/_%s/' % self.static_version, 1)
|
||||
if f.endswith('.css'):
|
||||
s += css_template % item
|
||||
elif f.endswith('.js'):
|
||||
s += js_template % item
|
||||
elif f.endswith('.coffee'):
|
||||
s += coffee_template % item
|
||||
elif f.endswith('.ts'):
|
||||
# http://www.typescriptlang.org/
|
||||
s += typescript_template % item
|
||||
elif f.endswith('.less'):
|
||||
s += less_template % item
|
||||
tmpl = template_mapping.get(ext)
|
||||
if tmpl:
|
||||
s.append(tmpl % item)
|
||||
elif isinstance(item, (list, tuple)):
|
||||
f = item[0]
|
||||
if f == 'css:inline':
|
||||
s += css_inline % item[1]
|
||||
elif f == 'js:inline':
|
||||
s += js_inline % item[1]
|
||||
self.write(s, escape=False)
|
||||
tmpl = template_mapping.get(f)
|
||||
if tmpl:
|
||||
s.append(tmpl % item[1])
|
||||
self.write(''.join(s), escape=False)
|
||||
|
||||
def stream(self,
|
||||
stream,
|
||||
@@ -663,7 +679,7 @@ class Response(Storage):
|
||||
return handler(request, self, methods)
|
||||
|
||||
def toolbar(self):
|
||||
from html import DIV, SCRIPT, BEAUTIFY, TAG, URL, A
|
||||
from gluon.html import DIV, SCRIPT, BEAUTIFY, TAG, A
|
||||
BUTTON = TAG.button
|
||||
admin = URL("admin", "default", "design", extension='html',
|
||||
args=current.request.application)
|
||||
|
||||
@@ -376,7 +376,6 @@ def wsgibase(environ, responder):
|
||||
request.env.http_x_forwarded_proto in HTTPS_SCHEMES \
|
||||
or env.https == 'on'
|
||||
)
|
||||
request.compute_uuid() # requires client
|
||||
request.url = environ['PATH_INFO']
|
||||
|
||||
# ##################################################
|
||||
|
||||
+1
-1
Submodule gluon/packages/dal updated: 62eb7767db...50f8dafdff.
@@ -119,7 +119,7 @@ class LockedFile(object):
|
||||
lock(self.file, LOCK_EX)
|
||||
if not 'a' in mode:
|
||||
self.file.seek(0)
|
||||
self.file.truncate()
|
||||
self.file.truncate(0)
|
||||
else:
|
||||
raise RuntimeError("invalid LockedFile(...,mode)")
|
||||
|
||||
|
||||
+19
-15
@@ -66,14 +66,15 @@ class XssCleaner(HTMLParser):
|
||||
|
||||
#to strip or escape disallowed tags?
|
||||
self.strip_disallowed = strip_disallowed
|
||||
self.in_disallowed = False
|
||||
# there might be data after final closing tag, that is to be ignored
|
||||
self.in_disallowed = [False]
|
||||
|
||||
def handle_data(self, data):
|
||||
if data and not self.in_disallowed:
|
||||
if data and not self.in_disallowed[-1]:
|
||||
self.result += xssescape(data)
|
||||
|
||||
def handle_charref(self, ref):
|
||||
if self.in_disallowed:
|
||||
if self.in_disallowed[-1]:
|
||||
return
|
||||
elif len(ref) < 7 and (ref.isdigit() or ref == 'x27'): # x27 is a special case for apostrophe
|
||||
self.result += '&#%s;' % ref
|
||||
@@ -81,7 +82,7 @@ class XssCleaner(HTMLParser):
|
||||
self.result += xssescape('&#%s' % ref)
|
||||
|
||||
def handle_entityref(self, ref):
|
||||
if self.in_disallowed:
|
||||
if self.in_disallowed[-1]:
|
||||
return
|
||||
elif ref in entitydefs:
|
||||
self.result += '&%s;' % ref
|
||||
@@ -89,7 +90,7 @@ class XssCleaner(HTMLParser):
|
||||
self.result += xssescape('&%s' % ref)
|
||||
|
||||
def handle_comment(self, comment):
|
||||
if self.in_disallowed:
|
||||
if self.in_disallowed[-1]:
|
||||
return
|
||||
elif comment:
|
||||
self.result += xssescape('<!--%s-->' % comment)
|
||||
@@ -100,11 +101,11 @@ class XssCleaner(HTMLParser):
|
||||
attrs
|
||||
):
|
||||
if tag not in self.permitted_tags:
|
||||
if self.strip_disallowed:
|
||||
self.in_disallowed = True
|
||||
else:
|
||||
self.in_disallowed.append(True)
|
||||
if (not self.strip_disallowed):
|
||||
self.result += xssescape('<%s>' % tag)
|
||||
else:
|
||||
self.in_disallowed.append(False)
|
||||
bt = '<' + tag
|
||||
if tag in self.allowed_attributes:
|
||||
attrs = dict(attrs)
|
||||
@@ -119,6 +120,7 @@ class XssCleaner(HTMLParser):
|
||||
else:
|
||||
bt += ' %s=%s' % (xssescape(attribute),
|
||||
quoteattr(attrs[attribute]))
|
||||
# deal with <a> without href and <img> without src
|
||||
if bt == '<a' or bt == '<img':
|
||||
return
|
||||
if tag in self.requires_no_close:
|
||||
@@ -129,10 +131,9 @@ class XssCleaner(HTMLParser):
|
||||
|
||||
def handle_endtag(self, tag):
|
||||
bracketed = '</%s>' % tag
|
||||
self.in_disallowed.pop()
|
||||
if tag not in self.permitted_tags:
|
||||
if self.strip_disallowed:
|
||||
self.in_disallowed = False
|
||||
else:
|
||||
if (not self.strip_disallowed):
|
||||
self.result += xssescape(bracketed)
|
||||
elif tag in self.open_tags:
|
||||
self.result += bracketed
|
||||
@@ -143,10 +144,13 @@ class XssCleaner(HTMLParser):
|
||||
Accepts relative, absolute, and mailto urls
|
||||
"""
|
||||
|
||||
parsed = urlparse(url)
|
||||
return (parsed[0] in self.allowed_schemes and '.' in parsed[1]) \
|
||||
or (parsed[0] in self.allowed_schemes and '@' in parsed[2]) \
|
||||
or (parsed[0] == '' and parsed[2].startswith('/'))
|
||||
if url.startswith('#'):
|
||||
return True
|
||||
else:
|
||||
parsed = urlparse(url)
|
||||
return ((parsed[0] in self.allowed_schemes and '.' in parsed[1]) or
|
||||
(parsed[0] in self.allowed_schemes and '@' in parsed[2]) or
|
||||
(parsed[0] == '' and parsed[2].startswith('/')))
|
||||
|
||||
def strip(self, rawstring, escape=True):
|
||||
"""
|
||||
|
||||
+1
-3
@@ -41,9 +41,7 @@ def enable_autocomplete_and_history(adir, env):
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
readline.parse_and_bind("bind ^I rl_complete"
|
||||
if sys.platform == 'darwin'
|
||||
else "tab: complete")
|
||||
readline.parse_and_bind("tab: complete")
|
||||
history_file = os.path.join(adir, '.pythonhistory')
|
||||
try:
|
||||
readline.read_history_file(history_file)
|
||||
|
||||
+75
-58
@@ -29,7 +29,7 @@ from gluon.html import URL, FIELDSET, P, DEFAULT_PASSWORD_DISPLAY
|
||||
from pydal.base import DEFAULT
|
||||
from pydal.objects import Table, Row, Expression, Field
|
||||
from pydal.adapters.base import CALLABLETYPES
|
||||
from pydal.helpers.methods import smart_query, bar_encode
|
||||
from pydal.helpers.methods import smart_query, bar_encode, _repr_ref
|
||||
from pydal.helpers.classes import Reference, SQLCustomType
|
||||
from gluon.storage import Storage
|
||||
from gluon.utils import md5_hash
|
||||
@@ -71,6 +71,26 @@ def represent(field, value, record):
|
||||
else:
|
||||
raise RuntimeError("field representation must take 1 or 2 args")
|
||||
|
||||
class CacheRepresenter(object):
|
||||
def __init__(self):
|
||||
self.cache = {}
|
||||
def __call__(self, field, value, row):
|
||||
cache = self.cache
|
||||
if field not in cache:
|
||||
cache[field] = {}
|
||||
try:
|
||||
nvalue = cache[field][value]
|
||||
except KeyError:
|
||||
try:
|
||||
nvalue = field.represent(value, row)
|
||||
except KeyError:
|
||||
try:
|
||||
nvalue = field.represent(value, row[field.tablename])
|
||||
except KeyError:
|
||||
nvalue = None
|
||||
if isinstance(field, _repr_ref):
|
||||
cache[field][value] = nvalue
|
||||
return nvalue
|
||||
|
||||
def safe_int(x):
|
||||
try:
|
||||
@@ -626,13 +646,12 @@ class AutocompleteWidget(object):
|
||||
def __init__(self, request, field, id_field=None, db=None,
|
||||
orderby=None, limitby=(0, 10), distinct=False,
|
||||
keyword='_autocomplete_%(tablename)s_%(fieldname)s',
|
||||
min_length=2, help_fields=None, help_string=None):
|
||||
min_length=2, help_fields=None, help_string=None, at_beginning = True):
|
||||
|
||||
self.help_fields = help_fields or []
|
||||
self.help_string = help_string
|
||||
if self.help_fields and not self.help_string:
|
||||
self.help_string = ' '.join('%%(%s)s' % f.name
|
||||
for f in self.help_fields)
|
||||
self.help_string = ' '.join('%%(%s)s' % f.name for f in self.help_fields)
|
||||
|
||||
self.request = request
|
||||
self.keyword = keyword % dict(tablename=field.tablename,
|
||||
@@ -642,6 +661,7 @@ class AutocompleteWidget(object):
|
||||
self.limitby = limitby
|
||||
self.distinct = distinct
|
||||
self.min_length = min_length
|
||||
self.at_beginning = at_beginning
|
||||
self.fields = [field]
|
||||
if id_field:
|
||||
self.is_reference = True
|
||||
@@ -659,8 +679,10 @@ class AutocompleteWidget(object):
|
||||
field = self.fields[0]
|
||||
if settings and settings.global_settings.web2py_runtime_gae:
|
||||
rows = self.db(field.__ge__(self.request.vars[self.keyword]) & field.__lt__(self.request.vars[self.keyword] + u'\ufffd')).select(orderby=self.orderby, limitby=self.limitby, *(self.fields+self.help_fields))
|
||||
else:
|
||||
elif self.at_beginning:
|
||||
rows = self.db(field.like(self.request.vars[self.keyword] + '%', case_sensitive=False)).select(orderby=self.orderby, limitby=self.limitby, distinct=self.distinct, *(self.fields+self.help_fields))
|
||||
else:
|
||||
rows = self.db(field.contains(self.request.vars[self.keyword], case_sensitive=False)).select(orderby=self.orderby, limitby=self.limitby, distinct=self.distinct, *(self.fields+self.help_fields))
|
||||
if rows:
|
||||
if self.is_reference:
|
||||
id_field = self.fields[1]
|
||||
@@ -1126,7 +1148,8 @@ class SQLFORM(FORM):
|
||||
extra_fields = extra_fields or []
|
||||
self.extra_fields = {}
|
||||
for extra_field in extra_fields:
|
||||
self.fields.append(extra_field.name)
|
||||
if not extra_field.name in self.fields:
|
||||
self.fields.append(extra_field.name)
|
||||
self.extra_fields[extra_field.name] = extra_field
|
||||
extra_field.db = table._db
|
||||
extra_field.table = table
|
||||
@@ -1678,7 +1701,7 @@ class SQLFORM(FORM):
|
||||
self.vars.update(pk)
|
||||
else:
|
||||
ret = False
|
||||
else:
|
||||
elif self.table._db._uri:
|
||||
if record_id:
|
||||
self.vars.id = self.record[self.id_field_name]
|
||||
if fields:
|
||||
@@ -1691,6 +1714,7 @@ class SQLFORM(FORM):
|
||||
|
||||
AUTOTYPES = {
|
||||
type(''): ('string', None),
|
||||
type(u''): ('string',None),
|
||||
type(True): ('boolean', None),
|
||||
type(1): ('integer', IS_INT_IN_RANGE(-1e12, +1e12)),
|
||||
type(1.0): ('double', IS_FLOAT_IN_RANGE()),
|
||||
@@ -1755,10 +1779,16 @@ class SQLFORM(FORM):
|
||||
keywords = keywords[0]
|
||||
request.vars.keywords = keywords
|
||||
key = keywords.strip()
|
||||
if key and ' ' not in key and not '"' in key and not "'" in key:
|
||||
if key and not '"' in key:
|
||||
SEARCHABLE_TYPES = ('string', 'text', 'list:string')
|
||||
parts = [field.contains(
|
||||
key) for field in fields if field.type in SEARCHABLE_TYPES]
|
||||
sfields = [field for field in fields if field.type in SEARCHABLE_TYPES]
|
||||
if settings.global_settings.web2py_runtime_gae:
|
||||
return reduce(lambda a,b: a|b, [field.contains(key) for field in sfields])
|
||||
else:
|
||||
return reduce(lambda a,b:a&b,[
|
||||
reduce(lambda a,b: a|b, [
|
||||
field.contains(k) for field in sfields]
|
||||
) for k in key.split()])
|
||||
|
||||
# from https://groups.google.com/forum/#!topic/web2py/hKe6lI25Bv4
|
||||
# needs testing...
|
||||
@@ -1772,10 +1802,6 @@ class SQLFORM(FORM):
|
||||
# filters.append(reduce(lambda a, b: (a & b), all_words_filters))
|
||||
#parts = filters
|
||||
|
||||
else:
|
||||
parts = None
|
||||
if parts:
|
||||
return reduce(lambda a, b: a | b, parts)
|
||||
else:
|
||||
return smart_query(fields, key)
|
||||
|
||||
@@ -1838,15 +1864,19 @@ class SQLFORM(FORM):
|
||||
operators = SELECT(*[OPTION(T(option), _value=option) for option in options], _class='form-control')
|
||||
_id = "%s_%s" % (value_id, name)
|
||||
if field_type in ['boolean', 'double', 'time', 'integer']:
|
||||
value_input = SQLFORM.widgets[field_type].widget(field, field.default, _id=_id, _class='form-control')
|
||||
widget_ = SQLFORM.widgets[field_type]
|
||||
value_input = widget_.widget(field, field.default, _id=_id, _class=widget_._class + ' form-control')
|
||||
elif field_type == 'date':
|
||||
iso_format = {'_data-w2p_date_format' : '%Y-%m-%d'}
|
||||
value_input = SQLFORM.widgets.date.widget(field, field.default, _id=_id, _class='form-control', **iso_format)
|
||||
iso_format = {'_data-w2p_date_format': '%Y-%m-%d'}
|
||||
widget_ = SQLFORM.widgets.date
|
||||
value_input = widget_.widget(field, field.default, _id=_id, _class=widget_._class + ' form-control', **iso_format)
|
||||
elif field_type == 'datetime':
|
||||
iso_format = {'_data-w2p_datetime_format' : '%Y-%m-%d %H:%M:%S'}
|
||||
value_input = SQLFORM.widgets.datetime.widget(field, field.default, _id=_id, _class='form-control', **iso_format)
|
||||
iso_format = {'_data-w2p_datetime_format': '%Y-%m-%d %H:%M:%S'}
|
||||
widget_ = SQLFORM.widgets.datetime
|
||||
value_input = widget_.widget(field, field.default, _id=_id, _class=widget_._class + ' form-control', **iso_format)
|
||||
elif (field_type.startswith('reference ') or
|
||||
field_type.startswith('list:reference ')) and \
|
||||
hasattr(field.requires, 'options') or \
|
||||
hasattr(field.requires, 'options'):
|
||||
value_input = SELECT(
|
||||
*[OPTION(v, _value=k)
|
||||
@@ -1856,7 +1886,8 @@ class SQLFORM(FORM):
|
||||
elif field_type.startswith('reference ') or \
|
||||
field_type.startswith('list:integer') or \
|
||||
field_type.startswith('list:reference '):
|
||||
value_input = SQLFORM.widgets.integer.widget(field, field.default, _id=_id, _class='form-control')
|
||||
widget_ = SQLFORM.widgets.integer
|
||||
value_input = widget_.widget(field, field.default, _id=_id, _class=widget_._class + ' form-control')
|
||||
else:
|
||||
value_input = INPUT(
|
||||
_type='text', _id=_id,
|
||||
@@ -1967,7 +1998,8 @@ class SQLFORM(FORM):
|
||||
cache_count=None,
|
||||
client_side_delete=False,
|
||||
ignore_common_filters=None,
|
||||
auto_pagination=True):
|
||||
auto_pagination=True,
|
||||
use_cursor=False):
|
||||
|
||||
formstyle = formstyle or current.response.formstyle
|
||||
|
||||
@@ -2069,18 +2101,15 @@ class SQLFORM(FORM):
|
||||
# is unique and usually indexed. See issue #679
|
||||
if not orderby:
|
||||
orderby = field_id
|
||||
else:
|
||||
if isinstance(orderby, Expression):
|
||||
if orderby.first:
|
||||
# here we're with a DESC order on a field
|
||||
# stored as orderby.first
|
||||
if orderby.first is not field_id:
|
||||
orderby = orderby | field_id
|
||||
else:
|
||||
# here we're with an ASC order on a field
|
||||
# stored as orderby
|
||||
if orderby is not field_id:
|
||||
orderby = orderby | field_id
|
||||
elif isinstance(orderby, list):
|
||||
orderby = reduce(lambda a,b: a|b, orderby)
|
||||
elif isinstance(orderby, Field) and orderby is not field_id:
|
||||
# here we're with an ASC order on a field stored as orderby
|
||||
orderby = orderby | field_id
|
||||
elif (isinstance(orderby, Expression) and
|
||||
orderby.first and orderby.first is not field_id):
|
||||
# here we're with a DESC order on a field stored as orderby.first
|
||||
orderby = orderby | field_id
|
||||
return orderby
|
||||
|
||||
def url(**b):
|
||||
@@ -2108,10 +2137,8 @@ class SQLFORM(FORM):
|
||||
# - url has valid signature (vars are not signed, only path_info)
|
||||
# = url does not contain 'create','delete','edit' (readonly)
|
||||
if user_signature:
|
||||
if not (
|
||||
'/'.join(str(a) for a in args) == '/'.join(request.args) or
|
||||
URL.verify(request, user_signature=user_signature,
|
||||
hash_vars=False) or
|
||||
if not ('/'.join(map(str,args)) == '/'.join(map(str,request.args)) or
|
||||
URL.verify(request, user_signature=user_signature, hash_vars=False) or
|
||||
(request.args(len(args)) == 'view' and not logged)):
|
||||
session.flash = T('not authorized')
|
||||
redirect(referrer)
|
||||
@@ -2542,7 +2569,7 @@ class SQLFORM(FORM):
|
||||
|
||||
cursor = True
|
||||
# figure out what page we are one to setup the limitby
|
||||
if paginate and dbset._db._adapter.dbengine == 'google:datastore':
|
||||
if paginate and dbset._db._adapter.dbengine == 'google:datastore' and use_cursor:
|
||||
cursor = request.vars.cursor or True
|
||||
limitby = (0, paginate)
|
||||
try:
|
||||
@@ -2564,7 +2591,7 @@ class SQLFORM(FORM):
|
||||
table_fields = [field for field in fields
|
||||
if (field.tablename in tablenames and
|
||||
not(isinstance(field, Field.Virtual)))]
|
||||
if dbset._db._adapter.dbengine == 'google:datastore':
|
||||
if dbset._db._adapter.dbengine == 'google:datastore' and use_cursor:
|
||||
rows = dbset.select(left=left, orderby=orderby,
|
||||
groupby=groupby, limitby=limitby,
|
||||
reusecursor=cursor,
|
||||
@@ -2574,6 +2601,7 @@ class SQLFORM(FORM):
|
||||
rows = dbset.select(left=left, orderby=orderby,
|
||||
groupby=groupby, limitby=limitby,
|
||||
cacheable=True, *table_fields)
|
||||
next_cursor = None
|
||||
except SyntaxError:
|
||||
rows = None
|
||||
next_cursor = None
|
||||
@@ -2592,7 +2620,7 @@ class SQLFORM(FORM):
|
||||
console.append(DIV(message or '', _class='web2py_counter'))
|
||||
|
||||
paginator = UL()
|
||||
if paginate and dbset._db._adapter.dbengine == 'google:datastore':
|
||||
if paginate and dbset._db._adapter.dbengine == 'google:datastore' and use_cursor:
|
||||
# this means we may have a large table with an unknown number of rows.
|
||||
try:
|
||||
page = int(request.vars.page or 1) - 1
|
||||
@@ -2663,7 +2691,7 @@ class SQLFORM(FORM):
|
||||
htmltable = TABLE(COLGROUP(*cols), THEAD(head))
|
||||
tbody = TBODY()
|
||||
numrec = 0
|
||||
repr_cache = {}
|
||||
repr_cache = CacheRepresenter()
|
||||
for row in rows:
|
||||
trcols = []
|
||||
id = row[field_id]
|
||||
@@ -2676,31 +2704,20 @@ class SQLFORM(FORM):
|
||||
continue
|
||||
if field.type == 'blob':
|
||||
continue
|
||||
value = row[str(field)]
|
||||
if isinstance(field, Field.Virtual) and field.tablename in row:
|
||||
value = dbset.db[field.tablename][row[field.tablename][field_id]][field.name]
|
||||
else:
|
||||
value = row[str(field)]
|
||||
maxlength = maxtextlengths.get(str(field), maxtextlength)
|
||||
if field.represent:
|
||||
if field.type.startswith('reference'):
|
||||
if field not in repr_cache:
|
||||
repr_cache[field] = {}
|
||||
try:
|
||||
nvalue = repr_cache[field][value]
|
||||
except KeyError:
|
||||
try:
|
||||
nvalue = field.represent(value, row)
|
||||
except KeyError:
|
||||
try:
|
||||
nvalue = field.represent(
|
||||
value, row[field.tablename])
|
||||
except KeyError:
|
||||
nvalue = None
|
||||
repr_cache[field][value] = nvalue
|
||||
nvalue = repr_cache(field, value, row)
|
||||
else:
|
||||
try:
|
||||
nvalue = field.represent(value, row)
|
||||
except KeyError:
|
||||
try:
|
||||
nvalue = field.represent(
|
||||
value, row[field.tablename])
|
||||
nvalue = field.represent(value, row[field.tablename])
|
||||
except KeyError:
|
||||
nvalue = None
|
||||
value = nvalue
|
||||
|
||||
+31
-28
@@ -269,31 +269,33 @@ class FastStorage(dict):
|
||||
|
||||
|
||||
class List(list):
|
||||
|
||||
"""
|
||||
Like a regular python list but a[i] if i is out of bounds returns None
|
||||
instead of `IndexOutOfBounds`
|
||||
Like a regular python list but callable.
|
||||
When a(i) is called if i is out of bounds returns None
|
||||
instead of `IndexError`.
|
||||
"""
|
||||
|
||||
def __call__(self, i, default=DEFAULT, cast=None, otherwise=None):
|
||||
"""Allows to use a special syntax for fast-check of `request.args()`
|
||||
validity
|
||||
|
||||
Args:
|
||||
"""Allows to use a special syntax for fast-check of
|
||||
`request.args()` validity.
|
||||
:params:
|
||||
i: index
|
||||
default: use this value if arg not found
|
||||
cast: type cast
|
||||
otherwise: can be:
|
||||
|
||||
- None: results in a 404
|
||||
- str: redirect to this address
|
||||
- callable: calls the function (nothing is passed)
|
||||
|
||||
otherwise:
|
||||
will be executed when:
|
||||
- casts fail
|
||||
- value not found, dont have default and otherwise is
|
||||
especified
|
||||
can be:
|
||||
- None: results in a 404
|
||||
- str: redirect to this address
|
||||
- callable: calls the function (nothing is passed)
|
||||
Example:
|
||||
You can use::
|
||||
|
||||
request.args(0,default=0,cast=int,otherwise='http://error_url')
|
||||
request.args(0,default=0,cast=int,otherwise=lambda:...)
|
||||
|
||||
"""
|
||||
n = len(self)
|
||||
if 0 <= i < n or -n <= i < 0:
|
||||
@@ -301,23 +303,24 @@ class List(list):
|
||||
elif default is DEFAULT:
|
||||
value = None
|
||||
else:
|
||||
value, cast = default, False
|
||||
if cast:
|
||||
try:
|
||||
value, cast, otherwise = default, False, False
|
||||
try:
|
||||
if cast:
|
||||
value = cast(value)
|
||||
except (ValueError, TypeError):
|
||||
from http import HTTP, redirect
|
||||
if otherwise is None:
|
||||
raise HTTP(404)
|
||||
elif isinstance(otherwise, str):
|
||||
redirect(otherwise)
|
||||
elif callable(otherwise):
|
||||
return otherwise()
|
||||
else:
|
||||
raise RuntimeError("invalid otherwise")
|
||||
if not value and otherwise:
|
||||
raise ValueError('Otherwise will raised.')
|
||||
except (ValueError, TypeError):
|
||||
from http import HTTP, redirect
|
||||
if otherwise is None:
|
||||
raise HTTP(404)
|
||||
elif isinstance(otherwise, str):
|
||||
redirect(otherwise)
|
||||
elif callable(otherwise):
|
||||
return otherwise()
|
||||
else:
|
||||
raise RuntimeError("invalid otherwise")
|
||||
return value
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
@@ -4,6 +4,7 @@ from test_http import *
|
||||
from test_cache import *
|
||||
from test_contenttype import *
|
||||
from test_fileutils import *
|
||||
from test_globals import *
|
||||
from test_html import *
|
||||
from test_is_url import *
|
||||
from test_languages import *
|
||||
|
||||
@@ -26,6 +26,7 @@ exclude_lines =
|
||||
ignore_errors = True
|
||||
omit = gluon/contrib/*
|
||||
gluon/tests/*
|
||||
gluon/packages/*
|
||||
|
||||
[html]
|
||||
directory = coverage_html_report
|
||||
@@ -13,6 +13,7 @@ fix_sys_path(__file__)
|
||||
|
||||
from storage import Storage
|
||||
from cache import CacheInRam, CacheOnDisk, Cache
|
||||
from gluon.dal import DAL, Field
|
||||
|
||||
oldcwd = None
|
||||
|
||||
@@ -30,6 +31,11 @@ def tearDownModule():
|
||||
if oldcwd:
|
||||
os.chdir(oldcwd)
|
||||
oldcwd = None
|
||||
try:
|
||||
os.unlink('dummy.db')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class TestCache(unittest.TestCase):
|
||||
@@ -107,7 +113,34 @@ class TestCache(unittest.TestCase):
|
||||
cache.clear(regex=r'a*')
|
||||
self.assertEqual(cache('a1', lambda: 2, 0), 2)
|
||||
self.assertEqual(cache('a2', lambda: 3, 100), 3)
|
||||
return
|
||||
|
||||
def testDALcache(self):
|
||||
s = Storage({'application': 'admin',
|
||||
'folder': 'applications/admin'})
|
||||
cache = Cache(s)
|
||||
db = DAL(check_reserved=['all'])
|
||||
db.define_table('t_a', Field('f_a'))
|
||||
db.t_a.insert(f_a='test')
|
||||
db.commit()
|
||||
a = db(db.t_a.id > 0).select(cache=(cache.ram, 60), cacheable=True)
|
||||
b = db(db.t_a.id > 0).select(cache=(cache.ram, 60), cacheable=True)
|
||||
self.assertEqual(a.as_csv(), b.as_csv())
|
||||
c = db(db.t_a.id > 0).select(cache=(cache.disk, 60), cacheable=True)
|
||||
d = db(db.t_a.id > 0).select(cache=(cache.disk, 60), cacheable=True)
|
||||
self.assertEqual(c.as_csv(), d.as_csv())
|
||||
self.assertEqual(a.as_csv(), c.as_csv())
|
||||
self.assertEqual(b.as_csv(), d.as_csv())
|
||||
e = db(db.t_a.id > 0).select(cache=(cache.disk, 60))
|
||||
f = db(db.t_a.id > 0).select(cache=(cache.disk, 60))
|
||||
self.assertEqual(e.as_csv(), f.as_csv())
|
||||
self.assertEqual(a.as_csv(), f.as_csv())
|
||||
g = db(db.t_a.id > 0).select(cache=(cache.ram, 60))
|
||||
h = db(db.t_a.id > 0).select(cache=(cache.ram, 60))
|
||||
self.assertEqual(g.as_csv(), h.as_csv())
|
||||
self.assertEqual(a.as_csv(), h.as_csv())
|
||||
db.t_a.drop()
|
||||
db.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setUpModule() # pre-python-2.7
|
||||
|
||||
+16
-1
@@ -4,6 +4,7 @@
|
||||
Unit tests for gluon.dal
|
||||
"""
|
||||
|
||||
import os
|
||||
import unittest
|
||||
from fix_path import fix_sys_path
|
||||
|
||||
@@ -12,8 +13,15 @@ fix_sys_path(__file__)
|
||||
|
||||
from gluon.dal import DAL, Field
|
||||
|
||||
def tearDownModule():
|
||||
try:
|
||||
os.unlink('dummy.db')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
class TestDALSubclass(unittest.TestCase):
|
||||
|
||||
def testRun(self):
|
||||
from gluon.serializers import custom_json, xml
|
||||
from gluon import sqlhtml
|
||||
@@ -22,19 +30,26 @@ class TestDALSubclass(unittest.TestCase):
|
||||
self.assertEqual(db.serializers['xml'], xml)
|
||||
self.assertEqual(db.representers['rows_render'], sqlhtml.represent)
|
||||
self.assertEqual(db.representers['rows_xml'], sqlhtml.SQLTABLE)
|
||||
db.close()
|
||||
|
||||
def testSerialization(self):
|
||||
import pickle
|
||||
db = DAL(check_reserved=['all'])
|
||||
db.define_table('t_a', Field('f_a'))
|
||||
db.t_a.insert(f_a='test')
|
||||
a = db(db.t_a.id>0).select(cacheable=True)
|
||||
a = db(db.t_a.id > 0).select(cacheable=True)
|
||||
s = pickle.dumps(a)
|
||||
b = pickle.loads(s)
|
||||
self.assertEqual(a.db, b.db)
|
||||
db.t_a.drop()
|
||||
db.close()
|
||||
|
||||
""" TODO:
|
||||
class TestDefaultValidators(unittest.TestCase):
|
||||
def testRun(self):
|
||||
pass
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
tearDownModule()
|
||||
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Unit tests for gluon.globals
|
||||
"""
|
||||
|
||||
|
||||
import unittest
|
||||
from fix_path import fix_sys_path
|
||||
|
||||
fix_sys_path(__file__)
|
||||
|
||||
from gluon.globals import Response
|
||||
from gluon import URL
|
||||
|
||||
|
||||
class testResponse(unittest.TestCase):
|
||||
|
||||
def test_include_files(self):
|
||||
|
||||
def return_includes(response, extensions=None):
|
||||
response.include_files(extensions)
|
||||
return response.body.getvalue()
|
||||
|
||||
response = Response()
|
||||
response.files.append(URL('a', 'static', 'css/file.css'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<link href="/a/static/css/file.css" rel="stylesheet" type="text/css" />')
|
||||
|
||||
response = Response()
|
||||
response.files.append(URL('a', 'static', 'css/file.js'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<script src="/a/static/css/file.js" type="text/javascript"></script>')
|
||||
|
||||
response = Response()
|
||||
response.files.append(URL('a', 'static', 'css/file.coffee'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<script src="/a/static/css/file.coffee" type="text/coffee"></script>')
|
||||
|
||||
response = Response()
|
||||
response.files.append(URL('a', 'static', 'css/file.ts'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<script src="/a/static/css/file.ts" type="text/typescript"></script>')
|
||||
|
||||
response = Response()
|
||||
response.files.append(URL('a', 'static', 'css/file.less'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<link href="/a/static/css/file.less" rel="stylesheet/less" type="text/css" />')
|
||||
|
||||
response = Response()
|
||||
response.files.append(('css:inline', 'background-color; white;'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<style type="text/css">\nbackground-color; white;\n</style>')
|
||||
|
||||
response = Response()
|
||||
response.files.append(('js:inline', 'alert("hello")'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<script type="text/javascript">\nalert("hello")\n</script>')
|
||||
|
||||
response = Response()
|
||||
response.files.append('https://code.jquery.com/jquery-1.11.3.min.js')
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<script src="https://code.jquery.com/jquery-1.11.3.min.js" type="text/javascript"></script>')
|
||||
|
||||
response = Response()
|
||||
response.files.append('https://code.jquery.com/jquery-1.11.3.min.js?var=0')
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<script src="https://code.jquery.com/jquery-1.11.3.min.js?var=0" type="text/javascript"></script>')
|
||||
|
||||
response = Response()
|
||||
response.files.append('https://code.jquery.com/jquery-1.11.3.min.js?var=0')
|
||||
response.files.append('https://code.jquery.com/jquery-1.11.3.min.js?var=0')
|
||||
response.files.append(URL('a', 'static', 'css/file.css'))
|
||||
response.files.append(URL('a', 'static', 'css/file.css'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content,
|
||||
'<script src="https://code.jquery.com/jquery-1.11.3.min.js?var=0" type="text/javascript"></script>' +
|
||||
'<link href="/a/static/css/file.css" rel="stylesheet" type="text/css" />')
|
||||
|
||||
response = Response()
|
||||
response.files.append(('js', 'http://maps.google.com/maps/api/js?sensor=false'))
|
||||
response.files.append('https://code.jquery.com/jquery-1.11.3.min.js?var=0')
|
||||
response.files.append(URL('a', 'static', 'css/file.css'))
|
||||
response.files.append(URL('a', 'static', 'css/file.ts'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content,
|
||||
'<script src="https://code.jquery.com/jquery-1.11.3.min.js?var=0" type="text/javascript"></script>' +
|
||||
'<link href="/a/static/css/file.css" rel="stylesheet" type="text/css" />' +
|
||||
'<script src="/a/static/css/file.ts" type="text/typescript"></script>' +
|
||||
'<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>'
|
||||
)
|
||||
|
||||
|
||||
response = Response()
|
||||
response.files.append(URL('a', 'static', 'css/file.js'))
|
||||
response.files.append(URL('a', 'static', 'css/file.css'))
|
||||
content = return_includes(response, extensions=['css'])
|
||||
self.assertEqual(content, '<link href="/a/static/css/file.css" rel="stylesheet" type="text/css" />')
|
||||
|
||||
#regr test for #628
|
||||
response = Response()
|
||||
response.files.append('http://maps.google.com/maps/api/js?sensor=false')
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '')
|
||||
|
||||
#regr test for #628
|
||||
response = Response()
|
||||
response.files.append(('js', 'http://maps.google.com/maps/api/js?sensor=false'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>')
|
||||
|
||||
response = Response()
|
||||
response.files.append(['js', 'http://maps.google.com/maps/api/js?sensor=false'])
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>')
|
||||
|
||||
response = Response()
|
||||
response.files.append(('js1', 'http://maps.google.com/maps/api/js?sensor=false'))
|
||||
content = return_includes(response)
|
||||
self.assertEqual(content, '')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -120,6 +120,7 @@ class TestStorageList(unittest.TestCase):
|
||||
|
||||
|
||||
class TestList(unittest.TestCase):
|
||||
|
||||
""" Tests Storage.List (fast-check for request.args()) """
|
||||
|
||||
def test_listcall(self):
|
||||
@@ -134,6 +135,23 @@ class TestList(unittest.TestCase):
|
||||
self.assertEqual(a(3, cast=int), 1234)
|
||||
a.append('x')
|
||||
self.assertRaises(HTTP, a, 4, cast=int)
|
||||
b = List()
|
||||
# default is always returned when especified
|
||||
self.assertEqual(b(0, cast=int, default=None), None)
|
||||
self.assertEqual(b(0, cast=int, default=None, otherwise='teste'), None)
|
||||
self.assertEqual(b(0, cast=int, default='a', otherwise='teste'), 'a')
|
||||
# if don't have value and otherwise is especified it will called
|
||||
self.assertEqual(b(0, otherwise=lambda: 'something'), 'something')
|
||||
self.assertEqual(b(0, cast=int, otherwise=lambda: 'something'),
|
||||
'something')
|
||||
# except if default is especified
|
||||
self.assertEqual(b(0, default=0, otherwise=lambda: 'something'), 0)
|
||||
|
||||
def test_listgetitem(self):
|
||||
'''Mantains list behaviour.'''
|
||||
a = List((1, 2, 3))
|
||||
self.assertEqual(a[0], 1)
|
||||
self.assertEqual(a[::-1], [3, 2, 1])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
+388
-33
@@ -60,7 +60,7 @@ except ImportError:
|
||||
# fallback to pure-Python module
|
||||
import gluon.contrib.simplejson as json_parser
|
||||
|
||||
__all__ = ['Mail', 'Auth', 'Recaptcha', 'Crud', 'Service', 'Wiki',
|
||||
__all__ = ['Mail', 'Auth', 'Recaptcha', 'Recaptcha2', 'Crud', 'Service', 'Wiki',
|
||||
'PluginManager', 'fetch', 'geocode', 'reverse_geocode', 'prettydate']
|
||||
|
||||
### mind there are two loggers here (logger and crud.settings.logger)!
|
||||
@@ -765,10 +765,13 @@ class Mail(object):
|
||||
result = {}
|
||||
try:
|
||||
if self.settings.server == 'logging':
|
||||
logger.warn('email not sent\n%s\nFrom: %s\nTo: %s\nSubject: %s\n\n%s\n%s\n' %
|
||||
('-' * 40, sender,
|
||||
', '.join(to), subject,
|
||||
text or html, '-' * 40))
|
||||
entry = 'email not sent\n%s\nFrom: %s\nTo: %s\nSubject: %s\n\n%s\n%s\n' % \
|
||||
('-' * 40, sender, ', '.join(to), subject, text or html, '-' * 40)
|
||||
logger.warn(entry)
|
||||
elif self.settings.server.startswith('logging:'):
|
||||
entry = 'email not sent\n%s\nFrom: %s\nTo: %s\nSubject: %s\n\n%s\n%s\n' % \
|
||||
('-' * 40, sender, ', '.join(to), subject, text or html, '-' * 40)
|
||||
open(self.settings.server[8:], 'a').write(entry)
|
||||
elif self.settings.server == 'gae':
|
||||
xcc = dict()
|
||||
if cc:
|
||||
@@ -786,16 +789,16 @@ class Mail(object):
|
||||
if attachments:
|
||||
result = mail.send_mail(
|
||||
sender=sender, to=origTo,
|
||||
subject=subject, body=text, html=html,
|
||||
subject=unicode(subject), body=unicode(text), html=html,
|
||||
attachments=attachments, **xcc)
|
||||
elif html and (not raw):
|
||||
result = mail.send_mail(
|
||||
sender=sender, to=origTo,
|
||||
subject=subject, body=text, html=html, **xcc)
|
||||
subject=unicode(subject), body=unicode(text), html=html, **xcc)
|
||||
else:
|
||||
result = mail.send_mail(
|
||||
sender=sender, to=origTo,
|
||||
subject=subject, body=text, **xcc)
|
||||
subject=unicode(subject), body=unicode(text), **xcc)
|
||||
else:
|
||||
smtp_args = self.settings.server.split(':')
|
||||
kwargs = dict(timeout=self.settings.timeout)
|
||||
@@ -965,7 +968,142 @@ class Recaptcha(DIV):
|
||||
return XML(captcha).xml()
|
||||
|
||||
|
||||
# this should only be used for catcha and perhaps not even for that
|
||||
class Recaptcha2(DIV):
|
||||
"""
|
||||
Experimental:
|
||||
Creates a DIV holding the newer Recaptcha from Google (v2)
|
||||
|
||||
Args:
|
||||
request : the request. If not passed, uses current request
|
||||
public_key : the public key Google gave you
|
||||
private_key : the private key Google gave you
|
||||
error_message : the error message to show if verification fails
|
||||
label : the label to use
|
||||
options (dict) : takes these parameters
|
||||
|
||||
- hl
|
||||
- theme
|
||||
- type
|
||||
- tabindex
|
||||
- callback
|
||||
- expired-callback
|
||||
|
||||
see https://developers.google.com/recaptcha/docs/display for docs about those
|
||||
|
||||
comment : the comment
|
||||
|
||||
Examples:
|
||||
Use as::
|
||||
|
||||
form = FORM(Recaptcha2(public_key='...',private_key='...'))
|
||||
|
||||
or::
|
||||
|
||||
form = SQLFORM(...)
|
||||
form.append(Recaptcha2(public_key='...',private_key='...'))
|
||||
|
||||
to protect the login page instead, use::
|
||||
|
||||
from gluon.tools import Recaptcha2
|
||||
auth.settings.captcha = Recaptcha2(request, public_key='...',private_key='...')
|
||||
|
||||
"""
|
||||
|
||||
API_URI = 'https://www.google.com/recaptcha/api.js'
|
||||
VERIFY_SERVER = 'https://www.google.com/recaptcha/api/siteverify'
|
||||
|
||||
def __init__(self,
|
||||
request=None,
|
||||
public_key='',
|
||||
private_key='',
|
||||
error_message='invalid',
|
||||
label='Verify:',
|
||||
options=None,
|
||||
comment='',
|
||||
):
|
||||
request = request or current.request
|
||||
self.request_vars = request and request.vars or current.request.vars
|
||||
self.remote_addr = request.env.remote_addr
|
||||
self.public_key = public_key
|
||||
self.private_key = private_key
|
||||
self.errors = Storage()
|
||||
self.error_message = error_message
|
||||
self.components = []
|
||||
self.attributes = {}
|
||||
self.label = label
|
||||
self.options = options or {}
|
||||
self.comment = comment
|
||||
|
||||
def _validate(self):
|
||||
recaptcha_response_field = self.request_vars.pop('g-recaptcha-response', None)
|
||||
remoteip = self.remote_addr
|
||||
if not recaptcha_response_field:
|
||||
self.errors['captcha'] = self.error_message
|
||||
return False
|
||||
params = urllib.urlencode({
|
||||
'secret': self.private_key,
|
||||
'remoteip': remoteip,
|
||||
'response': recaptcha_response_field,
|
||||
})
|
||||
request = urllib2.Request(
|
||||
url=self.VERIFY_SERVER,
|
||||
data=params,
|
||||
headers={'Content-type': 'application/x-www-form-urlencoded',
|
||||
'User-agent': 'reCAPTCHA Python'})
|
||||
httpresp = urllib2.urlopen(request)
|
||||
content = httpresp.read()
|
||||
httpresp.close()
|
||||
try:
|
||||
response_dict = json_parser.loads(content)
|
||||
except:
|
||||
self.errors['captcha'] = self.error_message
|
||||
return False
|
||||
if response_dict.get('success', False):
|
||||
self.request_vars.captcha = ''
|
||||
return True
|
||||
else:
|
||||
self.errors['captcha'] = self.error_message
|
||||
return False
|
||||
|
||||
def xml(self):
|
||||
api_uri = self.API_URI
|
||||
hl = self.options.pop('hl', None)
|
||||
if hl:
|
||||
api_uri = self.API_URI + '?hl=%s' % hl
|
||||
public_key = self.public_key
|
||||
self.options['sitekey'] = public_key
|
||||
captcha = DIV(
|
||||
SCRIPT(_src=api_uri, _async='', _defer=''),
|
||||
DIV(_class="g-recaptcha", data=self.options),
|
||||
TAG.noscript(XML("""
|
||||
<div style="width: 302px; height: 352px;">
|
||||
<div style="width: 302px; height: 352px; position: relative;">
|
||||
<div style="width: 302px; height: 352px; position: absolute;">
|
||||
<iframe src="https://www.google.com/recaptcha/api/fallback?k=%(public_key)s"
|
||||
frameborder="0" scrolling="no"
|
||||
style="width: 302px; height:352px; border-style: none;">
|
||||
</iframe>
|
||||
</div>
|
||||
<div style="width: 250px; height: 80px; position: absolute; border-style: none;
|
||||
bottom: 21px; left: 25px; margin: 0px; padding: 0px; right: 25px;">
|
||||
<textarea id="g-recaptcha-response" name="g-recaptcha-response"
|
||||
class="g-recaptcha-response"
|
||||
style="width: 250px; height: 80px; border: 1px solid #c1c1c1;
|
||||
margin: 0px; padding: 0px; resize: none;" value="">
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>""" % dict(public_key=public_key))
|
||||
)
|
||||
)
|
||||
if not self.errors.captcha:
|
||||
return XML(captcha).xml()
|
||||
else:
|
||||
captcha.append(DIV(self.errors['captcha'], _class='error'))
|
||||
return XML(captcha).xml()
|
||||
|
||||
|
||||
# this should only be used for captcha and perhaps not even for that
|
||||
def addrow(form, a, b, c, style, _id, position=-1):
|
||||
if style == "divs":
|
||||
form[0].insert(position, DIV(DIV(LABEL(a), _class='w2p_fl'),
|
||||
@@ -987,6 +1125,15 @@ def addrow(form, a, b, c, style, _id, position=-1):
|
||||
DIV(b, SPAN(c, _class='inline-help'),
|
||||
_class='controls'),
|
||||
_class='control-group', _id=_id))
|
||||
elif style == "bootstrap3_inline":
|
||||
form[0].insert(position, DIV(LABEL(a, _class='control-label col-sm-3'),
|
||||
DIV(b, SPAN(c, _class='help-block'),
|
||||
_class='col-sm-9'),
|
||||
_class='form-group', _id=_id))
|
||||
elif style == "bootstrap3_stacked":
|
||||
form[0].insert(position, DIV(LABEL(a, _class='control-label'),
|
||||
b, SPAN(c, _class='help-block'),
|
||||
_class='form-group', _id=_id))
|
||||
else:
|
||||
form[0].insert(position, TR(TD(LABEL(a), _class='w2p_fl'),
|
||||
TD(b, _class='w2p_fw'),
|
||||
@@ -1002,6 +1149,7 @@ class Auth(object):
|
||||
reset_password_requires_verification=False,
|
||||
registration_requires_verification=False,
|
||||
registration_requires_approval=False,
|
||||
bulk_register_enabled=False,
|
||||
login_after_registration=False,
|
||||
login_after_password_change=True,
|
||||
alternate_requires_registration=False,
|
||||
@@ -1035,6 +1183,7 @@ class Auth(object):
|
||||
table_permission_name='auth_permission',
|
||||
table_event_name='auth_event',
|
||||
table_cas_name='auth_cas',
|
||||
table_token_name='auth_token',
|
||||
table_user=None,
|
||||
table_group=None,
|
||||
table_membership=None,
|
||||
@@ -1103,6 +1252,8 @@ class Auth(object):
|
||||
retrieve_password_subject='Password retrieve',
|
||||
reset_password='Click on the link %(link)s to reset your password',
|
||||
reset_password_subject='Password reset',
|
||||
bulk_invite_subject='Invitation to join%(site)s',
|
||||
bulk_invite_body='You have been invited to join %(site)s, click %(link)s to complete the process',
|
||||
invalid_reset_password='Invalid reset password',
|
||||
profile_updated='Profile updated',
|
||||
new_password='New password',
|
||||
@@ -1316,6 +1467,7 @@ class Auth(object):
|
||||
settings.update(Auth.default_settings)
|
||||
settings.update(
|
||||
cas_domains=[request.env.http_host],
|
||||
enable_tokens=False,
|
||||
cas_provider=cas_provider,
|
||||
cas_actions=dict(login='login',
|
||||
validate='validate',
|
||||
@@ -1330,8 +1482,7 @@ class Auth(object):
|
||||
logged_url=URL(controller, function, args='profile'),
|
||||
download_url=URL(controller, 'download'),
|
||||
mailer=(mailer is True) and Mail() or mailer,
|
||||
on_failed_authorization =
|
||||
URL(controller, function, args='not_authorized'),
|
||||
on_failed_authorization = URL(controller, function, args='not_authorized'),
|
||||
login_next = url_index,
|
||||
login_onvalidation = [],
|
||||
login_onaccept = [],
|
||||
@@ -1356,6 +1507,8 @@ class Auth(object):
|
||||
change_password_onvalidation = [],
|
||||
change_password_onaccept = [],
|
||||
retrieve_password_onvalidation = [],
|
||||
request_reset_password_onvalidation = [],
|
||||
request_reset_password_onaccept = [],
|
||||
reset_password_onvalidation = [],
|
||||
reset_password_onaccept = [],
|
||||
hmac_key = hmac_key,
|
||||
@@ -1391,6 +1544,12 @@ class Auth(object):
|
||||
next = current.request.vars._next
|
||||
if isinstance(next, (list, tuple)):
|
||||
next = next[0]
|
||||
if next and self.settings.prevent_open_redirect_attacks:
|
||||
# Prevent an attacker from adding an arbitrary url after the
|
||||
# _next variable in the request.
|
||||
items = next.split('/')
|
||||
if '//' in next and items[2] != current.request.env.http_host:
|
||||
next = None
|
||||
return next
|
||||
|
||||
def _get_user_id(self):
|
||||
@@ -1417,6 +1576,9 @@ class Auth(object):
|
||||
def table_cas(self):
|
||||
return self.db[self.settings.table_cas_name]
|
||||
|
||||
def table_token(self):
|
||||
return self.db[self.settings.table_token_name]
|
||||
|
||||
def _HTTP(self, *a, **b):
|
||||
"""
|
||||
only used in lambda: self._HTTP(404)
|
||||
@@ -1444,7 +1606,8 @@ class Auth(object):
|
||||
'retrieve_username', 'retrieve_password',
|
||||
'reset_password', 'request_reset_password',
|
||||
'change_password', 'profile', 'groups',
|
||||
'impersonate', 'not_authorized'):
|
||||
'impersonate', 'not_authorized', 'confirm_registration',
|
||||
'bulk_register','manage_tokens'):
|
||||
if len(request.args) >= 2 and args[0] == 'impersonate':
|
||||
return getattr(self, args[0])(request.args[1])
|
||||
else:
|
||||
@@ -1771,7 +1934,7 @@ class Auth(object):
|
||||
writable=False, readable=False,
|
||||
label=T('Modified By'), ondelete=ondelete))
|
||||
|
||||
def define_tables(self, username=None, signature=None,
|
||||
def define_tables(self, username=None, signature=None, enable_tokens=False,
|
||||
migrate=None, fake_migrate=None):
|
||||
"""
|
||||
To be called unless tables are defined manually
|
||||
@@ -1798,6 +1961,7 @@ class Auth(object):
|
||||
username = settings.use_username
|
||||
else:
|
||||
settings.use_username = username
|
||||
settings.enable_tokens = enable_tokens
|
||||
if not self.signature:
|
||||
self.define_signature()
|
||||
if signature == True:
|
||||
@@ -1981,6 +2145,21 @@ class Auth(object):
|
||||
migrate=self.__get_migrate(
|
||||
settings.table_cas_name, migrate),
|
||||
fake_migrate=fake_migrate))
|
||||
if settings.enable_tokens:
|
||||
extra_fields = settings.extra_fields.get(
|
||||
settings.table_token_name, []) + signature_list
|
||||
if not settings.table_token_name in db.tables:
|
||||
db.define_table(
|
||||
settings.table_token_name,
|
||||
Field('user_id', reference_table_user, default=None,
|
||||
label=self.messages.label_user_id),
|
||||
Field('expires_on', 'datetime', default=datetime.datetime(2999,12,31)),
|
||||
Field('token',writable=False,default=web2py_uuid(),unique=True),
|
||||
*extra_fields,
|
||||
**dict(
|
||||
migrate=self.__get_migrate(
|
||||
settings.table_token_name, migrate),
|
||||
fake_migrate=fake_migrate))
|
||||
if not db._lazy_tables:
|
||||
settings.table_user = db[settings.table_user_name]
|
||||
settings.table_group = db[settings.table_group_name]
|
||||
@@ -2180,8 +2359,8 @@ class Auth(object):
|
||||
# user not in database try other login methods
|
||||
for login_method in self.settings.login_methods:
|
||||
if login_method != self and login_method(username, password):
|
||||
self.user = username
|
||||
return username
|
||||
self.user = user
|
||||
return user
|
||||
return False
|
||||
|
||||
def register_bare(self, **fields):
|
||||
@@ -2190,14 +2369,16 @@ class Auth(object):
|
||||
and a raw password.
|
||||
"""
|
||||
settings = self._get_login_settings()
|
||||
if not fields.get(settings.passfield):
|
||||
raise ValueError("register_bare: " +
|
||||
"password not provided or invalid")
|
||||
elif not fields.get(settings.userfield):
|
||||
# users can register_bare even if no password is provided,
|
||||
# in this case they will have to reset their password to login
|
||||
if fields.get(settings.passfield):
|
||||
fields[settings.passfield] = \
|
||||
settings.table_user[settings.passfield].validate(fields[settings.passfield])[0]
|
||||
if not fields.get(settings.userfield):
|
||||
raise ValueError("register_bare: " +
|
||||
"userfield not provided or invalid")
|
||||
fields[settings.passfield] = settings.table_user[settings.passfield].validate(fields[settings.passfield])[0]
|
||||
user = self.get_or_create_user(fields, login=False, get=False, update_fields=self.settings.update_fields)
|
||||
user = self.get_or_create_user(fields, login=False, get=False,
|
||||
update_fields=self.settings.update_fields)
|
||||
if not user:
|
||||
# get or create did not create a user (it ignores duplicate records)
|
||||
return False
|
||||
@@ -2341,10 +2522,6 @@ class Auth(object):
|
||||
|
||||
### use session for federated login
|
||||
snext = self.get_vars_next()
|
||||
if snext and self.settings.prevent_open_redirect_attacks:
|
||||
items = snext.split('/')
|
||||
if '//' in snext and items[2] != request.env.http_host:
|
||||
snext = None
|
||||
|
||||
if snext:
|
||||
session._auth_next = snext
|
||||
@@ -2718,6 +2895,10 @@ class Auth(object):
|
||||
passfield = self.settings.password_field
|
||||
formstyle = self.settings.formstyle
|
||||
if self.settings.register_verify_password:
|
||||
if self.settings.register_fields == None:
|
||||
self.settings.register_fields = [f.name for f in table_user if f.writable]
|
||||
k = self.settings.register_fields.index("password")
|
||||
self.settings.register_fields.insert(k+1, "password_two")
|
||||
extra_fields = [
|
||||
Field("password_two", "password", requires=IS_EQUAL_TO(
|
||||
request.post_vars.get(passfield, None),
|
||||
@@ -2993,6 +3174,147 @@ class Auth(object):
|
||||
table_user.email.requires = old_requires
|
||||
return form
|
||||
|
||||
def confirm_registration(
|
||||
self,
|
||||
next=DEFAULT,
|
||||
onvalidation=DEFAULT,
|
||||
onaccept=DEFAULT,
|
||||
log=DEFAULT,
|
||||
):
|
||||
"""
|
||||
Returns a form to confirm user registration
|
||||
"""
|
||||
|
||||
table_user = self.table_user()
|
||||
request = current.request
|
||||
# response = current.response
|
||||
session = current.session
|
||||
|
||||
if next is DEFAULT:
|
||||
next = self.get_vars_next() or self.settings.reset_password_next
|
||||
|
||||
if self.settings.prevent_password_reset_attacks:
|
||||
key = request.vars.key
|
||||
if not key and len(request.args)>1:
|
||||
key = request.args[-1]
|
||||
if key:
|
||||
session._reset_password_key = key
|
||||
redirect(self.url(args='confirm_registration'))
|
||||
else:
|
||||
key = session._reset_password_key
|
||||
else:
|
||||
key = request.vars.key or getarg(-1)
|
||||
try:
|
||||
t0 = int(key.split('-')[0])
|
||||
if time.time() - t0 > 60 * 60 * 24:
|
||||
raise Exception
|
||||
user = table_user(reset_password_key=key)
|
||||
if not user:
|
||||
raise Exception
|
||||
except Exception as e:
|
||||
session.flash = self.messages.invalid_reset_password
|
||||
redirect(self.url('login', vars=dict(test=e)))
|
||||
redirect(next, client_side=self.settings.client_side)
|
||||
passfield = self.settings.password_field
|
||||
form = SQLFORM.factory(
|
||||
Field('first_name',
|
||||
label='First Name',
|
||||
required=True),
|
||||
Field('last_name',
|
||||
label='Last Name',
|
||||
required=True),
|
||||
Field('new_password', 'password',
|
||||
label=self.messages.new_password,
|
||||
requires=self.table_user()[passfield].requires),
|
||||
Field('new_password2', 'password',
|
||||
label=self.messages.verify_password,
|
||||
requires=[IS_EXPR(
|
||||
'value==%s' % repr(request.vars.new_password),
|
||||
self.messages.mismatched_password)]),
|
||||
submit_button='Confirm Registration',
|
||||
hidden=dict(_next=next),
|
||||
formstyle=self.settings.formstyle,
|
||||
separator=self.settings.label_separator
|
||||
)
|
||||
if form.process().accepted:
|
||||
user.update_record(
|
||||
**{passfield: str(form.vars.new_password),
|
||||
'first_name': str(form.vars.first_name),
|
||||
'last_name': str(form.vars.last_name),
|
||||
'registration_key': '',
|
||||
'reset_password_key': ''})
|
||||
session.flash = self.messages.password_changed
|
||||
if self.settings.login_after_password_change:
|
||||
self.login_user(user)
|
||||
redirect(next, client_side=self.settings.client_side)
|
||||
return form
|
||||
|
||||
def email_registration(self, subject, body, user):
|
||||
"""
|
||||
Sends and email invitation to a user informing they have been registered with the application
|
||||
"""
|
||||
reset_password_key = str(int(time.time())) + '-' + web2py_uuid()
|
||||
link = self.url(self.settings.function,
|
||||
args=('confirm_registration',), vars={'key': reset_password_key},
|
||||
scheme=True)
|
||||
d = dict(user)
|
||||
d.update(dict(key=reset_password_key, link=link, site=current.request.env.http_host))
|
||||
if self.settings.mailer and self.settings.mailer.send(
|
||||
to=user.email,
|
||||
subject=subject % d,
|
||||
message=body % d):
|
||||
user.update_record(reset_password_key=reset_password_key)
|
||||
return True
|
||||
return False
|
||||
|
||||
def bulk_register(self, max_emails=100):
|
||||
"""
|
||||
Creates a form for ther user to send invites to other users to join
|
||||
"""
|
||||
if not self.user:
|
||||
redirect(self.settings.login_url)
|
||||
if not self.setting.bulk_register_enabled:
|
||||
return HTTP(404)
|
||||
|
||||
form = SQLFORM.factory(
|
||||
Field('subject','string',default=self.messages.bulk_invite_subject,requires=IS_NOT_EMPTY()),
|
||||
Field('emails','text',requires=IS_NOT_EMPTY()),
|
||||
Field('message','text',default=self.messages.bulk_invite_body,requires=IS_NOT_EMPTY()),
|
||||
formstyle=self.settings.formstyle)
|
||||
|
||||
if form.process().accepted:
|
||||
emails = re.compile('[^\s\'"@<>,;:]+\@[^\s\'"@<>,;:]+').findall(form.vars.emails)
|
||||
# send the invitations
|
||||
emails_sent = []
|
||||
emails_fail = []
|
||||
emails_exist = []
|
||||
for email in emails[:max_emails]:
|
||||
if self.table_user()(email=email):
|
||||
emails_exist.append(email)
|
||||
else:
|
||||
user = self.register_bare(email=email)
|
||||
if self.email_registration(form.vars.subject, form.vars.message, user):
|
||||
emails_sent.append(email)
|
||||
else:
|
||||
emails_fail.append(email)
|
||||
emails_fail += emails[max_emails:]
|
||||
form = DIV(H4('Emails sent'),UL(*[A(x,_href='mailto:'+x) for x in emails_sent]),
|
||||
H4('Emails failed'),UL(*[A(x,_href='mailto:'+x) for x in emails_fail]),
|
||||
H4('Emails existing'),UL(*[A(x,_href='mailto:'+x) for x in emails_exist]))
|
||||
return form
|
||||
|
||||
def manage_tokens(self):
|
||||
if not self.user:
|
||||
redirect(self.settings.login_url)
|
||||
table_token =self.table_token()
|
||||
table_token.user_id.writable = False
|
||||
table_token.user_id.default = self.user.id
|
||||
table_token.token.writable = False
|
||||
if current.request.args(1) == 'new':
|
||||
table_token.token.readable = False
|
||||
form = SQLFORM.grid(table_token, args=['manage_tokens'])
|
||||
return form
|
||||
|
||||
def reset_password(self,
|
||||
next=DEFAULT,
|
||||
onvalidation=DEFAULT,
|
||||
@@ -3030,6 +3352,12 @@ class Auth(object):
|
||||
except Exception:
|
||||
session.flash = self.messages.invalid_reset_password
|
||||
redirect(next, client_side=self.settings.client_side)
|
||||
|
||||
if onvalidation is DEFAULT:
|
||||
onvalidation = self.settings.reset_password_onvalidation
|
||||
if onaccept is DEFAULT:
|
||||
onaccept = self.settings.reset_password_onaccept
|
||||
|
||||
passfield = self.settings.password_field
|
||||
form = SQLFORM.factory(
|
||||
Field('new_password', 'password',
|
||||
@@ -3045,7 +3373,7 @@ class Auth(object):
|
||||
formstyle=self.settings.formstyle,
|
||||
separator=self.settings.label_separator
|
||||
)
|
||||
if form.accepts(request, session,
|
||||
if form.accepts(request, session, onvalidation=onvalidation,
|
||||
hideerror=self.settings.hideerror):
|
||||
user.update_record(
|
||||
**{passfield: str(form.vars.new_password),
|
||||
@@ -3054,6 +3382,7 @@ class Auth(object):
|
||||
session.flash = self.messages.password_changed
|
||||
if self.settings.login_after_password_change:
|
||||
self.login_user(user)
|
||||
callback(onaccept, form)
|
||||
redirect(next, client_side=self.settings.client_side)
|
||||
return form
|
||||
|
||||
@@ -3079,9 +3408,9 @@ class Auth(object):
|
||||
response.flash = self.messages.function_disabled
|
||||
return ''
|
||||
if onvalidation is DEFAULT:
|
||||
onvalidation = self.settings.reset_password_onvalidation
|
||||
onvalidation = self.settings.request_reset_password_onvalidation
|
||||
if onaccept is DEFAULT:
|
||||
onaccept = self.settings.reset_password_onaccept
|
||||
onaccept = self.settings.request_reset_password_onaccept
|
||||
if log is DEFAULT:
|
||||
log = self.messages['reset_password_log']
|
||||
userfield = self.settings.login_userfield or 'username' \
|
||||
@@ -3410,7 +3739,12 @@ class Auth(object):
|
||||
|
||||
basic_allowed, basic_accepted, user = self.basic()
|
||||
user = user or self.user
|
||||
if requires_login:
|
||||
|
||||
login_required = requires_login
|
||||
if callable(login_required):
|
||||
login_required = login_required()
|
||||
|
||||
if login_required:
|
||||
if not user:
|
||||
if current.request.ajax:
|
||||
raise HTTP(401, self.messages.ajax_failed_authentication)
|
||||
@@ -3451,6 +3785,26 @@ class Auth(object):
|
||||
"""
|
||||
return self.requires(True, otherwise=otherwise)
|
||||
|
||||
def requires_login_or_token(self, otherwise=None):
|
||||
if self.settings.enable_tokens == True:
|
||||
user = None
|
||||
request = current.request
|
||||
token = request.env.http_web2py_user_token or request.vars._token
|
||||
table_token = self.table_token()
|
||||
table_user = self.table_user()
|
||||
from gluon.settings import global_settings
|
||||
if global_settings.web2py_runtime_gae:
|
||||
row = table_token(token=token)
|
||||
if row:
|
||||
user = table_user(row.user_id)
|
||||
else:
|
||||
row = self.db(table_token.token==token)(table_user.id==table_token.user_id).select().first()
|
||||
if row:
|
||||
user = row[table_user._tablename]
|
||||
if user:
|
||||
self.login_user(user)
|
||||
return self.requires(True, otherwise=otherwise)
|
||||
|
||||
def requires_membership(self, role=None, group_id=None, otherwise=None):
|
||||
"""
|
||||
Decorator that prevents access to action if not logged in or
|
||||
@@ -5174,11 +5528,12 @@ def completion(callback):
|
||||
return _completion
|
||||
|
||||
|
||||
def prettydate(d, T=lambda x: x):
|
||||
def prettydate(d, T=lambda x: x, utc=False):
|
||||
now = datetime.datetime.utcnow() if utc else datetime.datetime.now()
|
||||
if isinstance(d, datetime.datetime):
|
||||
dt = datetime.datetime.now() - d
|
||||
dt = now - d
|
||||
elif isinstance(d, datetime.date):
|
||||
dt = datetime.date.today() - d
|
||||
dt = now.date() - d
|
||||
elif not d:
|
||||
return ''
|
||||
else:
|
||||
@@ -6049,7 +6404,7 @@ class Wiki(object):
|
||||
count = db.wiki_tag.wiki_page.count()
|
||||
fields = [db.wiki_page.id, db.wiki_page.slug,
|
||||
db.wiki_page.title, db.wiki_page.tags,
|
||||
db.wiki_page.can_read]
|
||||
db.wiki_page.can_read, db.wiki+page.can_edit]
|
||||
if preview:
|
||||
fields.append(db.wiki_page.body)
|
||||
if query is None:
|
||||
|
||||
+17
-12
@@ -200,8 +200,11 @@ class IS_MATCH(Validator):
|
||||
self.is_unicode = is_unicode
|
||||
|
||||
def __call__(self, value):
|
||||
if self.is_unicode and not isinstance(value, unicode):
|
||||
match = self.regex.search(str(value).decode('utf8'))
|
||||
if self.is_unicode:
|
||||
if isinstance(value,unicode):
|
||||
match = self.regex.search(value)
|
||||
else:
|
||||
match = self.regex.search(str(value).decode('utf8'))
|
||||
else:
|
||||
match = self.regex.search(str(value))
|
||||
if match is not None:
|
||||
@@ -3479,7 +3482,7 @@ class IS_IPV6(Validator):
|
||||
from gluon.contrib import ipaddr as ipaddress
|
||||
|
||||
try:
|
||||
ip = ipaddress.IPv6Address(value)
|
||||
ip = ipaddress.IPv6Address(value.decode('utf-8'))
|
||||
ok = True
|
||||
except ipaddress.AddressValueError:
|
||||
return (value, translate(self.error_message))
|
||||
@@ -3491,7 +3494,7 @@ class IS_IPV6(Validator):
|
||||
self.subnets = [self.subnets]
|
||||
for network in self.subnets:
|
||||
try:
|
||||
ipnet = ipaddress.IPv6Network(network)
|
||||
ipnet = ipaddress.IPv6Network(network.decode('utf-8'))
|
||||
except (ipaddress.NetmaskValueError, ipaddress.AddressValueError):
|
||||
return (value, translate('invalid subnet provided'))
|
||||
if ip in ipnet:
|
||||
@@ -3700,20 +3703,22 @@ class IS_IPADDRESS(Validator):
|
||||
|
||||
def __call__(self, value):
|
||||
try:
|
||||
import ipaddress
|
||||
from ipaddress import ip_address as IPAddress
|
||||
from ipaddress import IPv6Address, IPv4Address
|
||||
except ImportError:
|
||||
from gluon.contrib import ipaddr as ipaddress
|
||||
from gluon.contrib.ipaddr import (IPAddress, IPv4Address,
|
||||
IPv6Address)
|
||||
|
||||
try:
|
||||
ip = ipaddress.IPAddress(value)
|
||||
except ValueError, e:
|
||||
ip = IPAddress(value.decode('utf-8'))
|
||||
except ValueError:
|
||||
return (value, translate(self.error_message))
|
||||
|
||||
if self.is_ipv4 and isinstance(ip, ipaddress.IPv6Address):
|
||||
if self.is_ipv4 and isinstance(ip, IPv6Address):
|
||||
retval = (value, translate(self.error_message))
|
||||
elif self.is_ipv6 and isinstance(ip, ipaddress.IPv4Address):
|
||||
elif self.is_ipv6 and isinstance(ip, IPv4Address):
|
||||
retval = (value, translate(self.error_message))
|
||||
elif self.is_ipv4 or isinstance(ip, ipaddress.IPv4Address):
|
||||
elif self.is_ipv4 or isinstance(ip, IPv4Address):
|
||||
retval = IS_IPV4(
|
||||
minip=self.minip,
|
||||
maxip=self.maxip,
|
||||
@@ -3723,7 +3728,7 @@ class IS_IPADDRESS(Validator):
|
||||
is_automatic=self.is_automatic,
|
||||
error_message=self.error_message
|
||||
)(value)
|
||||
elif self.is_ipv6 or isinstance(ip, ipaddress.IPv6Address):
|
||||
elif self.is_ipv6 or isinstance(ip, IPv6Address):
|
||||
retval = IS_IPV6(
|
||||
is_private=self.is_private,
|
||||
is_link_local=self.is_link_local,
|
||||
|
||||
@@ -1058,6 +1058,11 @@ def start_schedulers(options):
|
||||
print 'starting single-scheduler for "%s"...' % app_
|
||||
run(app_, True, True, None, False, code)
|
||||
return
|
||||
|
||||
# Work around OS X problem: http://bugs.python.org/issue9405
|
||||
import urllib
|
||||
urllib.getproxies()
|
||||
|
||||
for app in apps:
|
||||
app_, code = get_code_for_scheduler(app, options)
|
||||
if not app_:
|
||||
|
||||
@@ -195,7 +195,7 @@ NameVirtualHost *:80
|
||||
NameVirtualHost *:443
|
||||
|
||||
<VirtualHost *:80>
|
||||
WSGIDaemonProcess web2py user=apache group=apache processes=1 threads=1
|
||||
WSGIDaemonProcess web2py user=apache group=apache
|
||||
WSGIProcessGroup web2py
|
||||
WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py
|
||||
WSGIPassAuthorization On
|
||||
|
||||
@@ -299,7 +299,7 @@ NameVirtualHost *:80
|
||||
NameVirtualHost *:443
|
||||
|
||||
<VirtualHost *:80>
|
||||
WSGIDaemonProcess web2py user=apache group=apache processes=1 threads=1
|
||||
WSGIDaemonProcess web2py user=apache group=apache
|
||||
WSGIProcessGroup web2py
|
||||
WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py
|
||||
|
||||
|
||||
@@ -301,7 +301,7 @@ NameVirtualHost *:80
|
||||
NameVirtualHost *:443
|
||||
|
||||
<VirtualHost *:80>
|
||||
WSGIDaemonProcess web2py user=apache group=apache processes=1 threads=1
|
||||
WSGIDaemonProcess web2py user=apache group=apache
|
||||
WSGIProcessGroup web2py
|
||||
WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py
|
||||
WSGIPassAuthorization On
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script will install web2py with nginx+uwsgi on centos 7
|
||||
# This script is based on excellent tutorial by Justin Ellingwood on
|
||||
# https://www.digitalocean.com/community/tutorials/how-to-deploy-web2py-python-applications-with-uwsgi-and-nginx-on-centos-7
|
||||
|
||||
#
|
||||
# Phase 1: First, let's ask a few things
|
||||
#
|
||||
|
||||
read -p "Enter username under which web2py will be installed [web2py]: " USERNAME
|
||||
USERNAME=${USERNAME:-web2py}
|
||||
|
||||
read -p "Enter path where web2py will be installed [/opt/web2py_apps]: " WEB2PY_PATH
|
||||
WEB2PY_PATH=${WEB2PY_PATH:-/opt/web2py_apps}
|
||||
|
||||
read -p "Web2py subdirectory will be called: [web2py]: " WEB2PY_APP
|
||||
WEB2PY_APP=${WEB2PY_APP:-web2py}
|
||||
|
||||
read -p "Enter your web2py admin password: " WEB2PY_PASS
|
||||
|
||||
read -p "Enter your domain name: " YOUR_SERVER_DOMAIN
|
||||
|
||||
# open new user
|
||||
useradd -d $WEB2PY_PATH $USERNAME
|
||||
|
||||
# if it's not already open, let's create a directory for web2py
|
||||
mkdir -p $WEB2PY_PATH
|
||||
|
||||
# now let's create a self signed certificate
|
||||
cd $WEB2PY_PATH
|
||||
|
||||
openssl req -x509 -new -newkey rsa:4096 -days 3652 -nodes -keyout $WEB2PY_APP.key -out $WEB2PY_APP.crt
|
||||
|
||||
#
|
||||
# phase 2: That was all the input that we needed so let's install the components
|
||||
#
|
||||
|
||||
echo "Installing necessary components"
|
||||
|
||||
# Verify packages are up to date
|
||||
yum -y upgrade
|
||||
|
||||
# Install required packages
|
||||
yum install -y epel-release
|
||||
yum install -y python-devel python-pip gcc nginx wget unzip python-psycopg2 MySQL-python
|
||||
|
||||
# download and unzip web2py
|
||||
|
||||
echo "Downloading web2py"
|
||||
|
||||
cd $WEB2PY_PATH
|
||||
wget http://web2py.com/examples/static/web2py_src.zip
|
||||
unzip web2py_src.zip
|
||||
rm web2py_src.zip
|
||||
|
||||
# preparing wsgihandler
|
||||
chown -R $USERNAME.$USERNAME $WEB2PY_PATH/$WEB2PY_APP
|
||||
mv $WEB2PY_PATH/$WEB2PY_APP/handlers/wsgihandler.py $WEB2PY_PATH/$WEB2PY_APP
|
||||
|
||||
# now let's install uwsgi
|
||||
|
||||
pip install uwsgi
|
||||
|
||||
# preparing directories
|
||||
mkdir -p /etc/uwsgi/sites
|
||||
mkdir -p /var/log/uwsgi
|
||||
mkdir -p /etc/nginx/ssl/
|
||||
|
||||
#
|
||||
# Phase 3: Ok, everything is installed now so we'll configure things
|
||||
#
|
||||
|
||||
# Create configuration file for uwsgi in /etc/uwsgi/$WEB2PY_APP.ini
|
||||
echo '[uwsgi]
|
||||
chdir = WEB2PY_PATH_PLACEHOLDER/WEB2PY_APP_PLACEHOLDER
|
||||
module = wsgihandler:application
|
||||
|
||||
master = true
|
||||
processes = 5
|
||||
|
||||
uid = USERNAME_PLACEHOLDER
|
||||
socket = /run/uwsgi/WEB2PY_APP_PLACEHOLDER.sock
|
||||
chown-socket = USERNAME_PLACEHOLDER:nginx
|
||||
chmod-socket = 660
|
||||
vacuum = true
|
||||
' >/etc/uwsgi/sites/$WEB2PY_APP.ini
|
||||
|
||||
sed -i "s@WEB2PY_PATH_PLACEHOLDER@$WEB2PY_PATH@" /etc/uwsgi/sites/$WEB2PY_APP.ini
|
||||
sed -i "s@WEB2PY_APP_PLACEHOLDER@$WEB2PY_APP@" /etc/uwsgi/sites/$WEB2PY_APP.ini
|
||||
sed -i "s@USERNAME_PLACEHOLDER@$USERNAME@" /etc/uwsgi/sites/$WEB2PY_APP.ini
|
||||
|
||||
# Create a daemon configuration file for uwsgi
|
||||
cat > /etc/systemd/system/uwsgi.service <<EOF
|
||||
[Unit]
|
||||
Description=uWSGI Emperor service
|
||||
|
||||
[Service]
|
||||
ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown USERNAME_PLACEHOLDER:nginx /run/uwsgi'
|
||||
ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
|
||||
Restart=always
|
||||
KillSignal=SIGQUIT
|
||||
Type=notify
|
||||
NotifyAccess=all
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sed -i "s@USERNAME_PLACEHOLDER@$USERNAME@" /etc/systemd/system/uwsgi.service
|
||||
|
||||
#chmod 777 /etc/systemd/system/uwsgi.service
|
||||
|
||||
# create a nginx configuration file
|
||||
cat > /etc/nginx/nginx.conf <<EOF
|
||||
# For more information on configuration, see:
|
||||
# * Official English Documentation: http://nginx.org/en/docs/
|
||||
# * Official Russian Documentation: http://nginx.org/ru/docs/
|
||||
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
error_log /var/log/nginx/error.log;
|
||||
pid /run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
|
||||
'\$status \$body_bytes_sent "\$http_referer" '
|
||||
'"\$http_user_agent" "\$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Load modular configuration files from the /etc/nginx/conf.d directory.
|
||||
# See http://nginx.org/en/docs/ngx_core_module.html#include
|
||||
# for more information.
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
server_name YOUR_SERVER_DOMAIN_PLACEHOLDER;
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
# Load configuration files for the default server block.
|
||||
include /etc/nginx/default.d/*.conf;
|
||||
|
||||
location ~* /(\w+)/static/ {
|
||||
root WEB2PY_PATH_PLACEHOLDER/WEB2PY_APP_PLACEHOLDER/applications/;
|
||||
}
|
||||
|
||||
location / {
|
||||
include uwsgi_params;
|
||||
uwsgi_pass unix:/run/uwsgi/WEB2PY_APP_PLACEHOLDER.sock;
|
||||
}
|
||||
|
||||
error_page 404 /404.html;
|
||||
location = /40x.html {
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443;
|
||||
server_name YOUR_SERVER_DOMAIN_PLACEHOLDER;
|
||||
|
||||
ssl on;
|
||||
ssl_certificate /etc/nginx/ssl/WEB2PY_APP_PLACEHOLDER.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/WEB2PY_APP_PLACEHOLDER.key;
|
||||
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
location / {
|
||||
include uwsgi_params;
|
||||
uwsgi_pass unix:/run/uwsgi/WEB2PY_APP_PLACEHOLDER.sock;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
sed -i "s@YOUR_SERVER_DOMAIN_PLACEHOLDER@$YOUR_SERVER_DOMAIN@" /etc/nginx/nginx.conf
|
||||
sed -i "s@WEB2PY_PATH_PLACEHOLDER@$WEB2PY_PATH@" /etc/nginx/nginx.conf
|
||||
sed -i "s@WEB2PY_APP_PLACEHOLDER@$WEB2PY_APP@" /etc/nginx/nginx.conf
|
||||
|
||||
#
|
||||
# Phase 4: everything is configured now, just a few final touches
|
||||
#
|
||||
|
||||
# copying certificates to nginx directory
|
||||
mv $WEB2PY_PATH/$WEB2PY_APP.crt* /etc/nginx/ssl
|
||||
mv $WEB2PY_PATH/$WEB2PY_APP.key* /etc/nginx/ssl
|
||||
|
||||
# creating web2py admin password
|
||||
cd $WEB2PY_PATH/$WEB2PY_APP
|
||||
python -c "from gluon.main import save_password; save_password('$WEB2PY_PASS',443)"
|
||||
chown -R $USERNAME.$USERNAME $WEB2PY_PATH/$WEB2PY_APP
|
||||
|
||||
# taking care of permissions
|
||||
chmod 700 /etc/nginx/ssl
|
||||
usermod -a -G $USERNAME nginx
|
||||
chmod 710 $WEB2PY_PATH
|
||||
|
||||
# enabling daemons
|
||||
systemctl start nginx
|
||||
systemctl start uwsgi
|
||||
systemctl enable nginx
|
||||
systemctl enable uwsgi
|
||||
|
||||
# If firewall is active make sure these ports are open
|
||||
|
||||
firewall-cmd --zone=public --add-port=80/tcp --permanent
|
||||
firewall-cmd --zone=public --add-port=443/tcp --permanent
|
||||
firewall-cmd --zone=public --add-port=22/tcp --permanent
|
||||
firewall-cmd --reload
|
||||
|
||||
echo
|
||||
echo 'Web2py is now installed on this server!'
|
||||
echo
|
||||
|
||||
@@ -84,7 +84,7 @@ server {
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
ssl_ciphers ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA;
|
||||
ssl_protocols SSLv3 TLSv1;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
keepalive_timeout 70;
|
||||
location / {
|
||||
#uwsgi_pass 127.0.0.1:9001;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
echo "This script will:
|
||||
1) install all modules need to run web2py on Ubuntu 14.04
|
||||
2) install web2py in /home/www-data/
|
||||
3) create a self signed sll certificate
|
||||
3) create a self signed ssl certificate
|
||||
4) setup web2py with mod_wsgi
|
||||
5) overwrite /etc/apache2/sites-available/default
|
||||
6) restart apache.
|
||||
@@ -84,7 +84,7 @@ openssl x509 -noout -fingerprint -text < /etc/apache2/ssl/self_signed.cert > /et
|
||||
echo "rewriting your apache config file to use mod_wsgi"
|
||||
echo "================================================="
|
||||
echo '
|
||||
WSGIDaemonProcess web2py user=www-data group=www-data processes=1 threads=1
|
||||
WSGIDaemonProcess web2py user=www-data group=www-data
|
||||
|
||||
<VirtualHost *:80>
|
||||
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
description "web2py task scheduler"
|
||||
|
||||
# INSTRUCTIONS:
|
||||
# COPY THIS FILE IN:
|
||||
# /etc/init/web2py-scheduler.con
|
||||
#
|
||||
# To start/stop the scheduler, use
|
||||
# "sudo start web2py-scheduler"
|
||||
# "sudo stop web2py-scheduler"
|
||||
# "sudo status web2py-scheduler"
|
||||
#
|
||||
# YOU MAY HAVE TO EDIT PATH TO WEB2PY BELOW
|
||||
|
||||
start on (local-filesystems and net-device-up IFACE=eth0)
|
||||
stop on shutdown
|
||||
|
||||
# Give up if restart occurs 8 times in 60 seconds.
|
||||
respawn limit 8 60
|
||||
|
||||
exec sudo -u www-data python /home/www-data/web2py/web2py.py -K parking > /tmp/scheduler.out
|
||||
respawn
|
||||
@@ -62,7 +62,7 @@ do_start()
|
||||
start-stop-daemon --stop --test --quiet --pidfile $PIDFILE \
|
||||
&& return 1
|
||||
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE \
|
||||
start-stop-daemon --start --quiet -m --pidfile $PIDFILE \
|
||||
${DAEMON_USER:+--chuid $DAEMON_USER} --chdir $DAEMON_DIR \
|
||||
--background --exec $DAEMON -- $DAEMON_ARGS \
|
||||
|| return 2
|
||||
|
||||
Reference in new issue
Block a user